Pull to refresh
0

PhoneJS — Новый HTML5-фреймворк для мобильных приложений

Reading time 8 min
Views 66K
Новые инструменты для разработки под мобильные устройства появляются сегодня чуть ли не каждый день. Большая часть из них — это HTML5-фреймворки, с помощью которых, обладая навыками веб-программиста, можно создавать приложения для смартфонов и планшетов, не углубляясь в изучение платформенных SDK и других языков.

Мы видим этот тренд и видим примеры реализации пользовательских интерфейсов на HTML5, не уступающих по качеству нативным приложениям, и верим, что за HTML5 стоит будущее кросс-платформенных мобильных приложений.



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

Мы в DevExpress организовали небольшую команду, которая на протяжении нескольких месяцев анализировала и пробовала различные существующие средства и подходы. Результат полученного опыта — PhoneJS — наше комплексное решение для создания кросс-платформенных мобильных приложений на HTML5.

Мы не стали писать PhoneJS с нуля. Взяли jQuery, потому что сегодня для многих это синоним слова JavaScript. Затем добавили упоминавшуюся несколько раз на Хабре библиотеку Knockout, реализующую паттерн Model-View-ViewModel (MVVM) для JavaScript, и выбрали MVVM рекомендованным подходом к структурированию приложения. Использование Apache Cordova (aka PhoneGap) позволило выйти из изоляции внутри WebView браузера и получить доступ к камере, файловой системе, акселерометру и другим функциям устройства. Сочетание этих компонентов помогло создать отличный фундамент для фреймворка.

На этом фундаменте мы построили layout-движок и UI-компоненты, адаптирующие свой внешний вид под три самых популярных платформы — iOS, Android и Windows Phone 8.

Стоит упомянуть, что всё большее количество сотрудников компаний пользуются на рабочем месте своими собственными мобильными устройствами. Идея создания кросс-платформенных приложений хорошо согласуется с этим трендом (известным под названием Bring Your Own Device, BYOD) и позволит сотрудникам устанавливать необходимое для работы корпоративное ПО на свои смартфоны и планшеты.



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

Приложение реализует алгоритм расчета чаевых. Исходный код доступен на GitHub, а посмотреть его в действии можно в онлайн-симуляторе.

В сущности, это Single Page Application на HTML5. Точка входа — файл index.html, в котором вы увидите только необходимые META-теги и подключение всех остальных ресурсов. Обратите внимание, как подключаются view-файлы

<link rel="dx-template" type="text/html" href="views/home.html" />

Такой подход позволяет избежать распространенной проблемы Single Page приложений, когда всю HTML разметку приходится держать в одном длинном index.html. Мы соблюдаем принципы декомпозиции приложения и облегчаем последующие этапы разработки и отладки.

В файле index.js объявляется пространство имен TipCalculator и создается объект-приложение:

TipCalculator.app = new DevExpress.framework.html.HtmlApplication(...)

Приложению мы сообщаем тип layout-а, используемый по умолчанию. В данном случае это самый простой из возможных — empty layout, однако есть и более функциональные варианты с навигационной панелью и так популярной сегодня боковой навигацией.



Здесь необходимо сделать отступление о том, что же такое layout вообще. В PhoneJS мы применили знакомую, проверенную и, давно известную вам идею декорации страниц (представлений, экранов) с помощью layout. Так делается в многочисленных серверных web-фреймворках (Ruby on Rails, ASP.NET MVC и многих PHP-библиотеках).

Подробнее про Views и Layouts можно почитать в нашей документации.

Есть и маршрутизация (routing):

TipCalculator.app.router.register(":view", { view: "home" });

Таким образом мы зарегистрировали простой маршрут, который из адресной строки (а если точнее, то из hash-сегмента) получает имя текущего экрана (view), причем экран «home» будет использоваться по умолчанию. Его и рассмотрим.

View Model

В файле views/home.js в пространство имен TipCalculator добавляется функция home, которая создает view-model (модель представления) для экрана home

TipCalculator.home = function(params) {
    . . .
};

Есть три входных параметра: сумма чека (billTotal), количество участников (splitNum) и размер вознаграждения (tipPercent). Они объявлены как observable, чтобы их можно было привязывать к UI-компонентам и отслеживать изменения значений

var billTotal = ko.observable(),
    tipPercent = ko.observable(DEFAULT_TIP_PERCENT),
    splitNum = ko.observable(1);

На основании пользовательского ввода вычисляются 4 результата: totalToPay, totalPerPerson, totalTip и tipPerPerson. Все четыре являются dependent observable (или computed) — то есть обновляются автоматически при изменении хотя бы одного observable, задействованного в вычислении результата.

var totalTip = ko.computed(...);

var tipPerPerson = ko.computed(...);

var totalPerPerson = ko.computed(...);

var totalToPay = ko.computed(...);

Финальную сумму, как правило, округляют, для чего есть две функции roundUp и roundDown, изменяющие значение roundMode. Его изменение влечет пересчет зависящего от него totalToPay:

var totalToPay = ko.computed(function() {
    var value = totalTip() + billTotalAsNumber();

    switch(roundMode()) {
        case ROUND_DOWN:
            if(Math.floor(value) >= billTotalAsNumber())
                return Math.floor(value);
            return value;

        case ROUND_UP:
            return Math.ceil(value);

        default:
            return value;
    }
});

Однако при изменении каждого из входных параметров необходимо сбросить округление, чтобы пользователь видел точные цифры, для этого с помощью метода subscribe мы подписываемся на их изменение:

billTotal.subscribe(function() {
    roundMode(ROUND_NONE);
});

tipPercent.subscribe(function() {
    roundMode(ROUND_NONE);
});

splitNum.subscribe(function() {
    roundMode(ROUND_NONE);
});

View model очень проста, особенно для тех читателей, кто уже знаком с Knockout. А для тех, кто не знаком, это хорошая демонстрация его возможностей.

View

Перейдем к HTML-разметке, а именно к файлу views/home.html. На верхнем уровне расположены два специальных div-элемента: для view с именем “home” задается разметка для области с именем “content”.

<div data-options="dxView : { name: 'home' }">
    <div data-options="dxContent : { targetPlaceholder: 'content' }">
        . . .
    </div>
</div>

Внутри расположен тулбар:

<div data-bind="dxToolbar: { items: [ { align: 'center', text: 'Tip Calculator' } ] }"></div>

dxToolbar — это виджет из состава PhoneJS. Его описание в разметке реализовано в виде Knockout-привязки (binding).

Ниже идут филдсеты. Для их создания применяются предопределенные во фреймворке CSS классы dx-fieldset и dx-field. Внутри поле для ввода суммы и два слайдера для процентов и количества человек:

<div data-bind="dxNumberBox: { value: billTotal, placeholder: 'Type here...', valueUpdateEvent: 'keyup', min: 0 }">
</div>

<div data-bind="dxSlider: { min: 0, max: 25, step: 1, activeStateEnabled: true, value: tipPercent }"></div>

<div data-bind="dxSlider: { min: 1, step: 1, max: 10, activeStateEnabled: true, value: splitNum }"></div>

Далее — две кнопки (dxButton) для округления итоговой суммы и вывод результатов.

<div class="round-buttons">
    <div data-bind="dxButton: { text: 'Round Down', clickAction: roundDown }"></div>
    <div data-bind="dxButton: { text: 'Round Up', clickAction: roundUp }"></div>
</div>

<div id="results" class="dx-fieldset">
    <div class="dx-field">
        <span class="dx-field-label">Total to pay</span>
        <span class="dx-field-value" style="font-weight: bold" data-bind="text: Globalize.format(totalToPay(), 'c')"></span>
    </div>
    <div class="dx-field">
        <span class="dx-field-label">Total per person</span>
        <span class="dx-field-value" data-bind="text: Globalize.format(totalPerPerson(), 'c')"></span>
    </div>
    <div class="dx-field">
        <span class="dx-field-label">Total tip</span>
        <span class="dx-field-value" data-bind="text: Globalize.format(totalTip(), 'c')"></span>
    </div>
    <div class="dx-field">
        <span class="dx-field-label">Tip per person</span>
        <span class="dx-field-value" data-bind="text: Globalize.format(tipPerPerson(), 'c')"></span>
    </div>
</div>

Даже на таком простом примере мы чётко видим, как быстро с помощью PhoneJS создать мобильное приложение, обладая навыками веб программирования. Минимум кода, структурированность и простота освоения.

Запуск, отладка и упаковка для маркетов

Приложения на HTML5 очень легко отлаживать. Достаточно настроить ваш локальный веб-сервер (Apache, IIS, nginx или любой другой) на папку с исходными кодами и открыть URL на устройстве, в эмуляторе устройства или в браузере. Правда в браузере будет необходимо подменить строку UserAgent, чтобы он представлялся смартфоном или планшетом. К счастью, developer tools современных браузеров это легко позволяют.



Другой удобный вариант — это Ripple Emulator, работающий в браузере.



Но нам хочется получить настоящее мобильное приложение, с возможностью публикации в маркеты (AppStore, Google Play и Windows Store).

Конечно же, придется зарегистрироваться как разработчик на сайтах Apple, Google и Microsoft, но этот процесс хорошо описан для каждого из магазинов, так что отдельно заострять внимание на этом не будем.

PhoneGap содержит нужные инструменты и шаблоны проектов. Основной сценарий работы с PhoneGap привязан к SDK мобильной платформы. Например, чтобы собрать APK для Android нужно будет установить Android SDK и создать в Eclipse PhoneGap-проект, а для разработки под iOS понадобится Mac.

Более простой путь, избавляющий нас от установки платформенных SDK — использовать онлайн-сервис PhoneGap Build, который позволяет бесплатно собирать одно приложение (для большего количества необходимо приобрести платный аккаунт). Имея необходимые сертификаты, с помощью PhoneGap Build, буквально через пару кликов можем получить мобильное приложение для разных платформ. Останется только подготовить описания, промо-материалы, картинки, иконки и приступать к публикации вашего приложения.

Небольшая ложка дегтя: на сегодняшний день PhoneGap Build не поддерживает упаковку для Windows Phone 8 (планируют добавить позже в этом году), и для сборки пакетов понадобится Windows Phone SDK и шаблон CordovaWP8App, включенный в дистрибутив PhoneGap.

Для пользователей Visual Stuido у нас есть отдельный продукт DXTREME Mobile (включающий PhoneJS в качестве одного из компонентов), позволяющий собирать приложения для iOS, Android и Windows Phone 8 непосредственно из среды разработки.



Итак PhoneGap + PhoneJS — все что нужно для разработки мобильных приложений

PhoneGap реализует доступ к аппаратным возможностям и решает задачу упаковки в нативные пакеты.

PhoneJS предоставляет инфраструктуру для Single Page приложений и набор оптимизированных под touch-устройства элементов для построения кроссплатформенного UI.

Списки с эластичной прокруткой, «бесконечной подгрузкой» и поддержкой жеста «pull down to refresh», переключатели ON/OFF, различные кнопки и поля ввода, галерея, карты и навигационные элементы — всё это есть в PhoneJS. Посмотреть примеры можно в демо-приложении Kitchen Sink.

Все виджеты можно использовать в двух режимах — как Knockout binding:

<div data-bind="dxCheckbox: {checked: checked} "></div>
<script>
    var myViewModel= {
            checked: true
    };
    ko.applyBindings(myViewModel);
</script>

и как jQuery-плагин:

<div id="checkboxContainer" ></div>
<script>
    $(function() {
        $("#checkboxContainer").dxCheckbox({
            checked: true
        });
    });
</script>

Предвосхищая естественный вопрос читателя, чем PhoneJS лучше / хуже / выделяется на фоне существующих известных решений, мы подготовили нашу реализацию для PropertyCross. Это интересный проект, цель которого сравнить разные существующие подходы к мобильной разработке.

Отметим важную деталь: PhoneJS не похож на большинство наших продуктов — он не привязан к определенному средству разработки. Дистрибутив — это zip-архив, а в качестве инструментов разработки и отладки можно использовать ваш любимый текстовый редактор, ваш любимый веб-сервер и developer tools вашего любимого браузера. Скачать PhoneJS можно по этой ссылке.

P.S. PhoneJS бесплатен для некоммерческого использования. А наша служба поддержки готова ответить на ваши вопросы и помочь преодолеть возникшие трудности.
Tags:
Hubs:
+87
Comments 71
Comments Comments 71

Articles

Information

Website
www.developersoft.ru
Registered
Founded
1998
Employees
201–500 employees
Location
Россия