Разработка приложения для Firefox OS на реальном примере
Мобильные приложения созданные с помощью веб-технологий понемногу захватывают мир. Но создание таких приложений, под популярные платформы, связанны с кучей проблем — от неизвестных истории багов, зоопарка размеров экрана, до проблем с производительностью, которые не решаются просто переписыванием тонких мест.Но к счастью, этот топик не будет наполнен обыденной трагедией разработки, подобных приложений. Поскольку сегодня, я покажу на реальном примере, как разрабатывать приложения под Firefox OS, которая поддерживает большую часть современных веб-технологий, и вообще говоря создана для них и благодаря им.
Рецепт Для приготовления нам понадобиться:0) Апи какого-нибудь сервиса, в нашем случае это ФотоФания (не сочтите за рекламу).1) Angular js — в качестве основы2) buildingfirefoxos.com/building-blocks/ — заготовки ui-блоков3) jQuery и прочие либы по вкусу0) Апи Поскольку хочется показать реальное приложение, то и апи надо использовать реальное. ФотоФания это сайт с помощью которого из своих скучных сэлфи можно создать веселые фоточки. Так что нам, немного, придется работать с изображениями на клиенте (хотя основная работа будет происходить на сервере, разумеется).1) Angular js Angular хорош. Конечно у меня есть притенении к нему, с точки зрения производительности на мобильных девайсах, но он позволяет отстранится от рутинного кода, обновлений элементов и прочего, занимаясь только данными. Кроме того, приложение на Angular без особых усилий получается отлично структурированным.2) Building Blocks Building Blocks — это готовые элементы дизайна, взятые (частично) из исходников Gaia — UI прослойки Firefox OS. Эти заготовки не используют js, вся логика, которая там есть, реализована через псевдо-селекторы. При этом, весь код написан с помощью html5 элементов, и использует data-* атрибуты для обозначения роли блока.Еще я заметил важную вещь — код Building Blocks работает быстрее и плавнее чем код, который я написал сам, как бы я не старался. По крайней мере, это касается списков. Возможно определённые элементы ускоряются нативно — не уверен насколько это правда. Так что по возможности пользуйтесь заготовками — они ускоряют разработку, делают приложение похожим на нативное и делают его плавнее.
3) jQuery и прочие Вообще говоря, я бы с радостью избавился от jQuery, но он является зависимостью плагина для пинч-зума github.com/segdeha/jquery-pan-zoom. Подсадить плагин на Zepto не получилось. К счастью jQuery можно билдить из тех кусков которые вам нужны. Поэтому я беспощадно избавился от SIzzle и прочих ненужных в быту вещей.Немного о структуре Структуру приложения каждый использует какую хочет. В моем случае она похожа на
/build/ /build.js /build.css /scripts/ /vendors/ /controllers/ /services/ /…/ /app.js /dictionary.js /config.js /styles/ /helpers/ /variables.less /mixins.less /main.less /header.less /… /images/ index.html Скрипты и стили билдятся с помощью grunt в реальном времени. А grunt release уже все минифицирует. Так же я использую grunt-angular-templates который все шаблоны превращает в js код, который так же добавляется в build.js
Первоначальная разметка страницы
Важно Думаю некоторые заметили ng-csp в элементе. Эта директива включает поддержку Content Security Policy — и это является обязательным, для создания приложения для Firefox OS. Кроме того, нам надо немного пропатчить сам angular! Ищем в коде angular строчку window.XMLHttpRequest (); и заменяем на window.XMLHttpRequest ({mozSystem: true}); А так же нам надо добавить руками в наши стили — вспомогательные стили angular.js. А именно — code.angularjs.org/1.2.16/angular-csp.cssНемного о js Надо заметить, что я изначально пишу код на coffeescript, но буду вам показывать его javascript аналог. Возможно где-то всплывут неточности — тогда мы вместе их исправим.Еще я надеюсь, что вы знакомы с angular и js достаточно хорошо, чтобы мне не останавливаться на каждом шагу. Иначе эту статью никто никогда в жизни не дочитает.
Мультиязычность Наше приложение будет мультиязычным. Поэтому нам требуется словарь, его интерпретатор и какая-нибудь директива или фильтр, чтобы вставлять слова в код. Часто когда речь заходит об мультиязычности с помощью angular — всплывают какие-то фильтры, которые выглядят не очень приятно. Например нам предлагают писать так
меня это немного корежит — зачем вызывать каждый раз лишнюю функцию и писать такой неудобный код, если можно просто использовать словарь в глобал-скоупе, и обращаться к нему? Например так . За всё время моей работы, такой способ меня не подводил. Давайте же его и реализуем.Хочется чтобы он был любой вложенностью, поддерживал любое количество языков. Без проблем!var DICTIONARY = { header: { search: { title: { ru: 'Поиск', en: 'Search' }, favorites: { ru: 'Избранное', en: 'Favorites' } } }, cancel: { ru: 'Отмена', en: 'Cancel' } }; Структура есть, теперь, чтобы не обращаться напрямую переменной (а не языку), надо написать небольшой парсер.
App.run (['$rootScope', function ($rootScope) { var lang = 'ru'; // тут должна быть какая-то логика :) $rootScope.m = (function () { var parse = function (obj, result) { result = result || {}; for (var key in obj) { var value = obj[key]; if (typeof value!== «object») return obj[lang]; result[key] = parse (value); } return result; }; return parse (DICTIONARY); })(); }]); То есть мы просто рекурсивно доходим, до того момента, когда значение переменной становится не объектом, и возвращаем значение с нужным языком. Все просто, и теперь у нас есть переменная m в рут-скоупе, к которой мы можем смело обращаться.Кто-то наверняка засомневается в производительности такого решения, но могу вас уверить, что это капля в море. И вообще вам никто не мешает написать директиву, которая не будет вешать ватчер на переменную. Так что все в порядке.
Вернемся к разметке Давайте доделаем drawer (Меню). Допустим у нас есть уже основа в виде js. Есть контроллер который обслуживает наше меню, и мы уже получили с помощью апи список категорий, которые будем выводить в меню. Тогда код меню получается очень простым.
Как видно, в своей разметке index.html мы уже использовали часть кода из Building Blocks. Сейчас мы возьмем код Drawer’a и немного изменим под себя. buildingfirefoxos.com/building-blocks/drawer.html
Как видно у нас два списка в меню, в самом верхнем лежит только одна ссылка на избранное (заметили что мы уже используем нашу переменную m?), там же выводится кол-во избранных фотоэффектов, сбоку. Ниже у нас, собственно, сам список категорий.
И для полноты картины сделаем еще одну страницу — список эффектов, то есть страница категории.buildingfirefoxos.com/building-blocks/headers.html — тут берем хедерыbuildingfirefoxos.com/building-blocks/lists.html — тут спискиbuildingfirefoxos.com/building-blocks/filters.html — тут фильтры (табы)buildingfirefoxos.com/building-blocks/buttons.html —, а тут кнопочи
И получаем, упрощенно, что-то такое:
Надеюсь все понятно. А понять надо следущее — мы берем готовые блоки и вырезаем из них самое нужное нам. Ими можно крутить и вертеть как угодно.Таким же образом делаются все остальные страницы.Об API Firefox OS В приложениях Firefox OS версии >= 1.3 input[file] работать не будет, в замен его, нам предлагают пользоваться MozActivity. Что даже упрощает работу.
Вот так выглядит получение картинки:
var pick = new MozActivity ({ name: «pick», data: { type: [«image/*»], nocrop: true } });
pick.onsuccess = function () { var blob = pick.result.blob; // что-то делаем с блобом }; Вот так шеринг:
new MozActivity ({ name: «share», data: { type: «image/*», number: 1, blobs: [blob] } }); И примерно так — сохранение:
var sdcard = navigator.getDeviceStorage («sdcard»); var request = sdcard.addNamed (blob, name); request.onsuccess = function () {}; request.onerror = function () {}; После того, как приложение готово, его надо сбилдить и протестировать.
Чтобы билдить — можно использовать эмуляторы.Я вам предлагаю использовать Менеджер приложений, который встроен по умолчанию в новые версии firefox. developer.mozilla.org/ru/docs/Mozilla/Firefox_OS/Using_the_App_Manager. Тут же можно устанавливать разные версии эмуляторов, подключать девайсы и дебажить! Что очень удобно.
Так же нам нужен манифест приложения. Выглядит и пишется он очень просто.Приведу пример:
{ «name»: «PhotoFunia», «description»: «PhotoFunia is the best way to add a spark to your photos, make them special and more original.», «launch_path»:»/index.html», «version» :»1», «type»: «privileged», «developer»: { «name»:», «email» :» }, «default_locale»: «en», «icons»: { »256»:»/images/app_icon_256.png» }, «permissions»: { «device-storage: pictures»: { «description»: «Save result images», «access»: «readwrite» }, «device-storage: sdcard»: { «description»: «Save result images», «access»: «readwrite» }, «mobilenetwork»: { «description»: «Check for available connection» }, «systemXHR»: { «description»: «Need for internet connection» } } } Собственно говоря, засовываем все нужные файлы в .zip архив и отправляем в marketplace.firefox.com на проверку. Через пару дней (а может и к вечеру) приложение появится в маркете!
Что это было? Я хотел донести до вас, что разработка под Firefox OS это очень просто, интересно и весело! Конечно, пока что, на этом денег не заработать. Но можно подумать, мы здесь ради денег собрались. Так что, берите IDE в руки, и создавайте приложения под Firefox OS! Тем, лучшим из нас, у кого есть девайс на Firefox OS — прошу к столу marketplace.firefox.com/app/photofunia/
Все пожелания, а так же ошибки и недочеты принимаю в личку.
