Оглавление
В этой статье мы хотим рассказать о разработке гибридных приложений для мобильных платформ на базе ionicframework и Parse.com
Самым нетерпеливым сразу же предлагаем ссылку на репозиторий — https://github.com/c3gdlk/ionic_parse_todo
Общая информация
Гибридные мобильные приложения набирают все большую популярность. Причина проста: эта технология позволяет быстро выпускать программы сразу для нескольких платформ. Однако не все так хорошо, как может показаться на первый взгляд. За скорость выпуска приходится платить потерей производительности приложения и ограничениями пользовательского интерфейса. Мы учитываем эти недостатки и, тем не менее, считаем гибридные мобильные приложения приемлемым вариантом реализации.
Движемся далее. Возможность использования веб-страниц в приложениях — не новость. Она была доступна и ранее, благодаря компоненту WebView. Начало развитию гибридных приложений положили сайты, подготовленные для отображения в браузерах мобильных устройств. За ними подтянулись более сложные приложения и игры. Вроде бы все хорошо, но этого оказалось мало. Время диктовало требования еще большего взаимодействия с операционной системой мобильных устройств. Так появилась библиотека Cordova (Apache Cordova) и подобные ей проекты.
Apache Cordova представляет собой набор APIs устройств, позволяющий разработчикам мобильных приложений получать доступ к нативным функциям устройства. Таким как камера, акселерометр из JavaScript кода и т.д. В комбинации с UI фреймворками — jQuery Mobile, Dojo Mobile или Sencha Touch — мы получаем возможность разработки полнофункционального мобильного приложения с использованием только лишь HTML, CSS и JavaScript.
Ionic framework — один из наиболее обсуждаемых и широко используемых фреймворков. Как гласит официальный сайт платформы, Ionic — это SDK для создания гибридных мобильных приложений, набор CSS и JS компонент, созданный на основе AngularJS, SASS и Apache Cordova.
Мы видим следующие преимущества в использовании Ionic фреймворка:
- Отличная документация. А также масса полезной информации от сообщества на stackoverflow и на форуме фреймворка.
- Большое количество готовых инструментов.
- Большое сообщество, обеспечивающее активное развитие фреймворка.
К числу недостатков можно отнести следующие моменты:
- Ionic несколько медлителен — существуют фреймворки-конкуренты, которые работают намного быстрее. Например famo.us.
- AngularJS. Мы считаем его использование скорее недостатком, чем достоинством.
Согласитесь, слабых мест совсем немного. Что же касается преимуществ, то именно они выступили в роли так называемой серебряной пули. Иными словами — склонили наш выбор в пользу Ionic. Причем, еще на этапе выбора архитектуры проекта.
Теперь о проекте. Он представляет собой многофункциональное, корпоративное приложение, в состав которого входят чат, новостная лента, лента сообщений и еще масса различного функционала. В перспективе его количество еще увеличится. Как говорится: не счесть алмазов в каменных долинах.
Следующим интересным инструментом в нашей “лаборатории” стал Parse. Parse.com — один из самых популярных провайдеров backend-as-a-service (BaaS). Он предоставляет все необходимые компоненты инфраструктуры для работы с веб-приложением в одном флаконе. База данных, push-уведомления, файловое хранилище и серверный код. Недурно, скажете вы и будете правы. Потому что кроме вышеперечисленных плюшек есть еще и бесплатный тариф, который предоставляет 30 запросов в секунду, одну фоновую задачу, 20 Гб файлового хранилища, 20 Гб под хранение базы данных, 2 Тб трафика и 1 000 000 push-уведомлений в месяц. Круто — скажите вы и вновь окажетесь правы.
Hello Word, он же TODO
Не будем отступать от общепринятых канонов и соберем свой велосипед с помощью вышеперечисленных инструментов. Мы решили реализовать классический TODO, который будет хранить данные в облаке (в базе на Parse.com). Реализация UI будет происходить на базе Ionic. В итоге мы должны получить кроссплатформенное мобильное приложение, адаптированное, как минимум, под iOS и Android.
Итак, что нам потребуется:
- девайс с MacOS на борту (само собой, для сборки под iOS);
- Node.js + Npm + Gulp;
- Git.
Шаг первый. Установка Ionic фреймворка и создание приложения
Устанавливаем Apache Cordova:
Устанавливаем Ionic:
Создаем новый проект:
Переходим в папку проекта и запускаем веб сервер:
В результате проведенных манипуляций мы должны получить открытую веб-браузером страницу, в шапке которой красуется надпись: Ionic Blank Starter. На данном этапе не будем рассматривать структуру проекта полностью. Все, что нам нужно на текущий момент — это приложение.
Шаг 2. Регистрация и создание приложение в Parse.com
Процедура регистрации и создания приложения весьма тривиальна. Мы вводим собственное имя, емэйл и пароль, далее выбираем тип компании “Individual Developer” и вводим имя приложения. Вот и все. Parse приложение готово к работе.
Следующая операция — создание базы данных. Нам необходимо где-то хранить свои записи. Для этого создаем таблицу
На снимке экрана прекрасно видно, что в Parse есть несколько таблиц по умолчанию. Они необходимы для хранения данных о пользователях, ролях и инсталляциях. Как проходят авторизация и регистрация мы опишем в следующей статье. Здесь же ограничимся созданием таблицы для хранения TODO записи. Для этого нам нужен класс Task. Заметьте — именно класс, а не таблица.
Итак, задача выполнена. Класс Task создан. В результате мы получили пустую таблицу со следующими полями:
- objectId — идентификатор объекта, строка.
- createdAt — дата создания.
- updatedAt — дата редактирования.
- acl — управление доступом к записи (подробности управления доступом к записи будут рассмотрены в следующих статьях).
Наша текущая цель — быстрый прототип. По этой причине можно забыть о безопасности. Никакой авторизации в приложении. Только хардкор:)
Добавляем в таблицу два поля:
- body — сама TODO запись
- isDone — статус задачи
Не отходя от кассы, тут же — в Parse консоли, добавляем две тестовые записи.
Шаг 3. Parse и Ionic
Скачиваем Parse JavaScript SDK с официального сайта и удобно располагаем его в директории www/lib, далее подключаем в файле www/js/index.html следующим образом
Один момент отмечаем отдельно — директорию www считаем корневой и используем в приложении относительные адреса.
Так как у каждого разработчика могут быть свои настройки, да и вообще хранение настроек в репозитории — моветон, мы предлагаем использовать для этого конфигурационный файл создаваемого Ionic приложения. Добавляем config.xml в список игнорируемых файлов Git, чтобы токены приложения не попали в репозиторий. Открываем config.xml и добавляем туда следующие теги:
JS Key и App Id параметры можно получить в Parse, меню Panel > Settings > Keys.
Далее создаем директорию www/xml. Также добавляем её в список игнорируемых файлов Git. Копируем в нее наш конфигурационный файл
При сборке приложения будет использоваться конфигурационный файл из корневой директории. Он нам понадобится для запуска приложения в браузере без предварительной сборки.
Далее создаем файл bootstrap.js. Его задача загружать необходимые настройки до начала работы приложения.
Parse.initialize(window.applicationConfig[‘ParseAppID’], window.applicationConfig[‘ParseJsKey’]);
GetConfigFromXML — функция, выполняющая запрос к файлу xml/config.xml файлу и считывающая все теги настроек (preference). Кроме того, она сохраняет глобальную переменную и затем инициализирует Parse SDK.
Результат можно проверить в консоли. Для этого попробуем получить тестовые записи из базы, которые мы создавали в панели управления Parse. Делать это будем следующим образом: объявим новый тип Task на основе класса Task и создадим запрос на выборку элементов, экземпляров класса. Не задаем никаких условий поиска, просто ищем все элементы. После этого сразу же вызываем функцию find, которая вернет нам Promise и говорим, что нам нужно вывести в консоль данные по готовности. Выходит больше текста с пояснениями, чем самого кода:)
В примерах из официальной документации обычно используют callback. Однако по нашему мнению текущая реализация гораздо проще. При отсутствии явного ограничения на количество записей Parse сам выставляет порог в 100 единиц.
Чтобы сразу получить все записи, можно установить заведомо большой лимит или получить их количество, а затем, используя рекурсивный метод — и все записи.
Шаг 4. Отображаем TODO записи при помощи AngularJS
Поехали дальше. Добавляем приведенный ниже html код в файл index.html
Теперь поясняем. Мы объявили на странице о необходимости верхней навигационной панели, а также подключили файлы роутинга и контроллеры.
Шаг 5. Маршрутизация
Прописываем пути и контроллеры в файле router.js
ion-nav-view — контейнер, который привязывается к контроллеру и шаблону
app — имя контейнера
соответственно код, представленный ниже
при переходе на ‘#/tasks/new’ отображает шаблон ‘templates/new-task.html’ в контейнер с именем “app” и передает управление контроллеру “NewTaskController”.
Мы можем объявить еще один контейнер, например
Использование $scope не самая лучшая практика. По этой причине мы получаем доступ к контроллеру через его псевдоним. Однако мы объявляем его не в шаблонах, а в роутах.
Шаг 6. Контроллеры
Посмотрите как мы работаем с контроллерами на представленном учебном примере и больше никогда так не делайте. Не забывайте, что мы приняли решение терять качество за счет набора скорости. Если же делать все согласно лучшим практикам Angular, то необходимо учитывать HMVC архитектуру (Hierarchical model–view–controller).
Итак, совершаем кощунство и собираем все контроллеры в один файл controllers.js. Ниже представлен его листинг.
Пояснения к коду:
Контроллер TasksController — отвечает за вывод списка наших TODO записей.
Приведенный ниже фрагмент кода выполняет загрузку файлов из Parse и сообщает Angular об изменении данных, как бы намекая, что было бы неплохо их перерисовать.
Функции completeTask и uncompleteTask отвечают за изменение состояния/статуса записи TODO.
Контроллер NewTaskController отвечает за создание новой TODO записи.
Переменная this.newTask = {body: », isDone: false}; используется для привязки к input элементу.
Фрагмент кода для создания и сохранения новой TODO записи.
Фрагмент кода выполняющий следующие операции после сохранения данных: очистка переменной и переход на список TODO элементов.
Шаг 7. Шаблоны
Общее количество шаблонов всегда равняется двум: список и создание/редактирование записи.
Код шаблона списка TODO записей templates/tasks.html
Пояснения к коду шаблона списка TODO записей
view-title=»Tasks» — заголовок нашей навигационной панели.
ссылка в навигационной панели на создание новой TODO записи.
ng-repeat=»task in tasksCtrl.tasks» — проходим все записи в цикле, вспоминаем что такое tasksCtrl — тот самый алиас, который был объявлен в роут файле.
Шаблон для создания/редактирования TODO записи new-task.html
Шаблон прост. Даже очень прост — один input и кнопка “сохранить”. Все. Краткость — сестра таланта.
Еще один важный момент, который ни в коем случае нельзя упустить. Сделаем небольшой флешбек к контроллерам
}); — после изменения статуса/состояния записи возвращаемся в TasksController. Однако именно из него мы и пришли. Логично предположить, что мы, по сути, вернулись обратно, и код контроллера не выполнился. Мы не успели разобраться баг это или фича, однако получил проблему и нашли решение в приведенном выше фрагменте кода.
Шаг 8. Сборка приложения
Код готов. Приложение прошло предварительное тестирование в браузере. Настала пора проверить приложение на реальных мобильных устройствах и эмуляторах. Для этого нужно собрать программу под целевые платформы. В нашем случае — это Android и iOS.
Для сборки приложения под Android у нас на борту должен быть установлен Android SDK
а в .bash_profile необходимо добавить следующие строки:
Для сборки приложения под iOS потребуется MacOS и установленный Xcode.
Добавляем необходимые платформы:
Приведенные выше команды представляют собой обертку над Cordova и равнозначны команде cordova platform add.
Вернемся к Android платформе и продолжим мучить командную строку.
Выполнение этих команд должно привести к запуску приложения в Android эмуляторе. Не будем останавливаться на достигнутом и попробуем запустить его на реальном устройстве. Для этого необходимо разрешить отладку приложения через USB:
- Заходим в меню “Настройки”.
- В меню “О телефоне” или в одном из разделов находим кнопку “Build Number” и нажимаем ее 7 раз подряд.
- Появляется новый раздел настроек с Develop опциями.
- Переходим в него и разрешаем отладку через USB.
http://i.imgur.com/k0JnlkM.png
http://i.imgur.com/x3caCIG.png
Отладка приложения
Отладка Ionic приложения не так уж и сложна, так как мы можем получить доступ к консоли webview в процессе его выполнения. Для того чтобы сделать это на Android:
- Используем Chrome Remote Debugging.
- В результате наше приложение становится доступным по адресу chrome://inspect/#devices в браузере.
Для того чтобы сделать это на iOS:
На телефоне
- Включаем Safari Settings — Private Browsing.
- Включаем Safari Settings advanced — Web Inspector.
На компьютере
- Safari browser — Saferi — preferences — advanced.
- Включаем Show Develop menu in menu bar.
- В результате в меню Develop появляются подключенные к компьютеру устройства.
Существуют и подводные камни. Так как приложение для iPhone не работает в background, консоль показывает вывод ровно в тот момент, когда ее запустили. Чтобы сохранять консольные логи с самого начала, следует написать небольшой логгер
Итоги
Гибридные мобильные приложения — перспективная и активно развивающаяся технология. Ionic фреймворк — самое стабильное решение для их реализации. Его основные профиты — это производительность и кроссплатформенность. Недостатки — небольшая потеря в скорости и необходимость понимания того, как устроены нативные приложения (без этого никак). Проблема в том, что нужного Cordova плагина может не оказаться или он просто перестанет поддерживаться. Мы столкнулись с такой ситуацией на практике. Плагин не обновился после выхода iOS 8. В итоге пришлось искать и исправлять ошибку в Objective C коде самостоятельно. Продолжение следует.