AppleInsider.ru
X
О проекте Реклама
Чат
с читателями
Присоединяйтесь
в Телеграме

[Dev Story] Кубышка — приложение для iOS и Android за 24 часа

Нам пишет Иван Росс

Что можно успеть за новогодние праздники? Как я смог выяснить, очень много. Даже если у тебя двое детей и куча родни, которую хочется навестить. Не получается только закончить статью для хабра. Она, зараза, растягивается на весь январь.

5-го числа я оказался с ноутбуком и двумя свободными днями. Прикинув, что можно сделать полезного, я решил сделать какое-нибудь мобильное приложение быстрее, чем его создатели. Поскольку 2 дня это не то, чтобы много, нужно было найти небольшое, популярное приложение с разговорчивыми авторами.

В App Store нашлось приложение «Транжира». Это небольшая программа для записи своих трат и доходов. В конце месяца по ним можно сделать вывод: почему опять не хватило до зарплаты. На 5-е число оно входило в топ-10 в разделе «Финансы». На iphones.ru нашлась dev-story.

В своей статье ребята пишут: «После сдачи проекта у нашей команды обычно есть 3-4 полусвободных дня (таковы правила компании), и уже через час над приложением нашего дизайнера работали 4 человека. Первым в бой ринулся product manager, подсказав несколько ключевых моментов по позиционированию приложения. За ним программисты и даже office manager.» Это меня обнадежило и я стал думать, как уложиться в 2 дня.

UPD 1: приложение обновилось во второй половине января. Сравнивая с моим приложением, стоит ориентироваться на скриншоты и функционал из dev-story.

UPD 2: иконка «Транжиры» удивительно похожа на иконку платных постов из «4 правил автора» на хабре.

У меня уже был опыт мобильной разработки на C# и Cocoa. Поскольку время тратил личное, хотелось использовать его с максимальной пользой. Даже если успеть, приложение не получится, то хотя бы «вкусить» нового фреймворка или языка.

 

Я работал в DevExpress с 2006 по 2011 год и с тех пор следил за их анонсами. От них до сих пор приходит What’s New на мою почту. Соблазнить на покупку что ли хотят? У них появился мобильный js-фреймворк на базе Cordova/PhoneGap. Писать его начали уже после моего увольнения, поэтому что это за зверь я не знал и было интересно попробовать.

Исследовательская компания Gartner пишет, что по состоянию на август 2013 года большинство корпоративных мобильных приложений было написано на PhoneGap или продуктах на его основе (вроде Kony). Мой личный, потребительский опыт подсказывает, что это не так. Но вдруг я заблуждаюсь?

С JavaScript и HTML я знаком понаслышке. Верстаю со stackoverflow подмышкой, умею писать простенькие jQuery селекторы. Знаю, где находится её документация. В общем, это огромная дыра в моих знаниях. Очень хотелось если не закрыть её, то хотя бы получить какой-то опыт.

В итоге у меня должно было получиться кросс-платформенное приложение. Это позволило бы мне получить преимущество над разработчиками «Транжиры» и произвести больше добавленной пользы за доступное время. У меня была всего одна пара рук и использовать её хотелось наиболее эффективно. На одной чаше весов была потенциальная эффективность фреймворка, на другой — отсутствие опыта в js-разработке у меня. Я понадеялся, что фреймворк перевесит и решил попробовать.

 

Мне удобно писать с VCS, поэтому сейчас я попытаюсь восстановить и описать по часам мой прогресс.

Не уверен, что могу выложить в публичный доступ репо. В нем лежат фото, купленные на стоке, и сторонние библиотеки каждая со своей лицензией. Написанный мною код, вы можете увидеть ниже, либо на свой риск заглянув внутрь бандла приложения.

Место действия: Тула, Дата: 5 января 2014


// Содержимое вью

плюс

ThriftBox.home = function (params) { // Параметры запроса из uri
return {}; // Объект вью-модели
};

В дальнейшем одно с другим увязывается с помощью knockout-биндингов. Времени впритык, поэтому оставляю два экрана: ввод трат и отчет трат по месяцам.

+4 часа 20 минут Случился первый «затык». Не получилось быстро сделать разметку цифровых кнопок для ввода трат.
В исходном приложении на главном экране огромная клавиатура, похожая на калькулятор или приложение-звонилку.

Оказалось, что даже «в лоб», с помощью тега table сделать такую клавиатуру не получается. На Retina-iPhone бордюры в 1 пиксел между кнопками меняли свой цвет после нажатия кнопок. Разница в цвете линий на хорошем экране телефона была очень заметна. Пришлось думать, как победить.

Изучал вопрос и опробовал вариант верстки на div’ах. С ними не получилось добиться, чтобы рамка была ровно 1 пиксел шириной и все кнопки были одинакового размера на экранах разного разрешения. Спустя 3 часа баг был оставлен как есть, и я двинулся дальше.

+28 минут Убран индикатор нажатия ссылки на iOS. iOS отрисовывает серый индикатор нажатия вокруг ссылок и объектов с обработчиком onclick. Поскольку у меня был свой индикатор нажатия (кнопка становилась темнее), этот серый индикатор мне был не нужен. Проблема решилась с помощью события dxAction:

было:

1

стало:

1

Это событие — расширенная вариация события click: в качестве обработчика оно поддерживает uri навигации между вью и корректно отрабатывает в скроллируемой области.

+14 минут Обработчик buttonPress из предыдущего примера, валидация введенного числа.

var number = ko.observable(null);
var isValidNumber = ko.computed(function() {
return number() && parseFloat(number()) > 0;
});

......

function buttonPress(button) {
if (button) {
if (number())
number(number() + button);
else
number(button);
} else if (number())
number(number().substr(0, number().length - 1));
}

var viewModel = {
number: number,
isValidNumber: isValidNumber,

viewShowing: viewShowing,
buttonPress: buttonPress
};

.....

+8 минут Добавил FastClick.js, который убирает задержку перед срабатыванием события click на телефонах. По умолчанию мобильный браузер откладывает вызов обработчика click, чтобы убедиться, что не будет double-tap. Внешне это проявляется как подтормаживающее приложение. Вы быстро нажимаете кнопками, а они реагируют с ощутимой задержкой на нажатия. Авторы FastClick.js вешаются на touchstart и выстраивают свою логику обработки нажатий.

Забегая вперед скажу, что добавление этой библиотеки было ошибкой. Почему — читайте далее.

 

+4 минуты Ввел ограничение на длину числа, которое может ввести пользователь. Подкорректировал размер шрифтов, чтобы все отлично выглядело и не вылезало за границы области ввода.

+58 минут Выбор категории траты. Под областью ввода добавил прокручивающуюся область с кнопками доступных категорий. Видео.
Заняло меньше, чем могло бы. Внутри PhoneJS нашел подходящий компонент dxTileView. Из коробки получил нужный мне внешний вид и кинетик-прокрутку. С последней пришлось бы помучится, если делать её самому. Особенно здорово, что ребята из DevExpress включили её только для iOS, где она — системная, но выключили для Android, где такой прокрутки нет.


Было уже 19:40 и я решил закончить.

Место действия: Тула, Дата: 6 января 2014

+3 часа 9 минут Хранение данных на диске. В PhoneJS входят классы для работы с данными: выборка, фильтрация, сортировка, группировка. Есть несколько вариантов хранения данных: OData и LocalStorage. Делать серверную часть для бесплатного приложения мне совершенно не хотелось, поэтому обратил внимание на LocalStorage. Довольно быстро выяснилось, что хранить в LocalStorage не самая здравая идея. Например, при обновлении на iOS 5.1 терлись пользовательские данные, другие жалуются, что LocalStorage трется раз в неделю на Android, третьи, что трется при выключении питания. Я решил не рисковать пользовательскими данными и использовать File API из Cordova/PhoneGap.

Документация утверждает, что это API основано на W3C File API. По факту это означает, что это API — разное в Chrome и Safari на Mac OS, реализации в Cordova для iOS и реализации для Android. Реализации для iOS и Android — разные. Функции себя ведут по-разному и разный набор классов и констант. Например, в реализации для Android отсутствует класс Blob и константа window.PERMANENT. Зато есть класс LocalFileSystem с классом LocalFileSystem.PERSISTENT. В браузере на ноутбуке есть дополнительное API для запроса квоты на хранение данных, которое отсутствует на мобильных телефонах.

 

Дополнительных проблем создает доступная в сети документация по этому API. Я читал несколько статей, которые я смог найти по запросу html5 file api. Мне ни разу не встретилась статья, которая дала бы мне ответы на все мои вопросы. В итоге, методом проб и ошибок, родился класс для работы с File API, поддерживающий Cordova 3.3 на iOS и Android, Chrome 32 на Mac OS и Windows 8. Вы можете найти его здесь:https://github.com/chebum/fileStorage-for-Phone.JS/blob/master/fileStora…

Использовать его можно так:

// В этом примере создастся файл data/records в папке Documents приложения.
FS.initFileAPI(1000000, true)
.then(function () {
var records = new FS.FileArrayStore({ key: "id", fileName: "records" });
return records.insert({ customer: "Петя" })
})
.then(function () {
alert("Запись добавлена!");
});

// Или использовать низкоуровневое API:
FS.initFileAPI(100000, true)
.then(function() {
return FS.writeFile(«file1», «Содержимое файла»)
})
.then(function() {
alert(«Файл записан!»);
});

Всю ночь мне снились дрянные кнопки на главном экране приложения.

Место действия: Тула, Внуково, Москва, Дата: 7-8 января 2014

У меня был ранний рейс в Будапешт из Внуково, поэтому что не успел днем, доделывал ночью в аэропорту. Спать, сидя на стуле в кафе неудобно, а программировать — вполне.
+2 часа 5 минут Утром, еще дома, решил разделить кнопки, чтобы избавиться от границ между ними. В качестве образца взял клавиатуру набора номера из iOS 7.

Клавиатуры получилось три. В зависимости от габаритов экрана меняется размер кнопок: для 3.5, 4 и 5» телефонов. В каждую ячейку таблицы был положен div и настроено выравнивание. Из-за отсутствия недоделанного выравнивания текста по вертикали в HTML, получился достаточно сложный css-стиль для кнопок:

.home-view .buttons td div {
color: #4a5360;
border: 1px solid #4a5360;
text-align: center;

position: absolute;
left: 50%;

/* Small buttons — default */
font-size: 26px;
padding: 13px 0 13px 0;
width: 52px;
line-height: 26px;
border-radius: 26px;

margin-left: -27px;
margin-top: -27px;
}

Моя Бухгалтерия

Сложим потраченное время и разобъем его по категориям.

В итоге за это время получилось минимально работающее приложение, которое сильно уступает последней версии «Транжиры». Я не успел разбиение трат по дням, ввод доходов. В интерфейсе программы срезано несколько «углов».

Если проанализировать их трудозатраты, то получается следующее. В своей статье они пишут про 3-4 дня 4 человека. Это 96-128 человеко-часов. У меня получилось чуть больше 30 часов и приложение под 3 платформы. iOS и Android уже в магазинах. Windows 8 потребует переделки интерфейса: текущий очень чужероден. Можно гордиться собой.

Готовые приложения можно загрузить по ссылкам: iOS, Android.

Если вам есть, чем поделиться с другими читателями нашего сайта, пишите на advert@appleinsider.ru и не забудьте указать свое имя или ник. Мы внимательно читаем входящие письма и публикуем ваши самые интересные истории.