Сегодня я расскажу вам о нашем опыте разработки кросс-платформенных мобильных приложений на основе PhoneGap/Cordova. В проекте используются такие технологии, как HTML5, CSS3 и Angular.js. Grunt применяется в качестве task manager’а, позволяющего упростить и ускорить выполнение рутинных задач. Все сборки компилируются локально во время процесса разработки.


Источник: build.phonegap.com

Когда версия готова к этапу тестирования, она компилируется с помощью PhoneGap Build и загружается на Ubertesters — сервис дистрибуции мобильных приложений, который позволяет проводить тестирование быстро и эффективно на всех подключенных устройствах. Приложение поддерживает минимум iOS 6 и Android 4.1 (87.5 % доля рынка).

Настройка локальной сборки и структура проекта


Для локального тестирования приложения необходимо установить инструменты для PhoneGap/Cordova. Важно убедиться, что NodeJS уже установлен, открыть командную строку или Cygwin и выполнить следующее:

npm install -g phonegap

После завершения установки пустой проект может быть создан и скомпилирован для требуемой платформы:

phonegap create my-app
cd my-app
phonegap platform add android
phonegap run android

Внимание: phonegap = cordova. Можно использовать cordova вместо phonegap при написании команд:

cordova run android

Сборка для iOS может осуществляться только под Mac OS X (согласно условиям лицензионного соглашения Apple), не существует способа запустить сборку для iOS под Windows.

Платформа Android требует наличия SDK Tools, его можно скачать по ссылке (пакет SDK Tools Only внизу страницы). Сразу после установки необходимо проверить в Android SDK Manager, что Android 5.0 (API level 21) был установлен успешно. Android 5.0 используется как target для текущей версии Phonegap/Cordova при локальной сборке.

Структура приложения


Файлы и папки

• platforms – включает в себя раздельный код под каждую из используемых платформ, компилируется каждый раз, когда выполняется сборка;
• plugins – это плагины, используемые в приложении. Плагины описываются подробнее далее;
• www – веб-приложение на основе HTML5/Angular.js, PhoneGap/Cordova отображает при помощи системного компонента Web View;
• config.xml – файл должен находиться в корневой папке проекта при локальной сборке. PhoneGap Build требует наличия файла config.xml в /www. Файл настроек является важной частью проекта на основе PhoneGap. Он включает в себя ссылки на ресурсы приложения, устанавливает необходимые разрешения и настраивает параметры для каждой из платформ (например, поведение status bar’а). Application (bundle) id и информация об издателе должна быть тоже указана в config.xml.

Plugins


Плагин это пакет, который позволяет автоматически внедрить native код в приложение и управлять native методами из Cordova Web View. Все основные функции PhoneGap/Cordova API реализованы при помощи плагинов, которые предоставляют доступ к возможностям и функциям устройства и платформы, которые недоступны обычному веб-приложению: сканирование QR кода, NFC, Push уведомления и даже Touch ID для iOS.

Существует реестр PhoneGap плагинов. Очень важно использовать плагины, совместимые с PhoneGap Build, иначе сборка будет возможно только локально.
Для добавления плагина в проект при локальной сборке используют команду plugin add из корневой папки проекта. Аргументом к этой команде является URL Git репозитория, содержащего код плагина:

cordova plugin add https://github.com/phonegap-build/PushPlugin.git

PhoneGap Build требует указания id в файле config.xml для каждого плагина (что-то вроде зависимостей). Указывать конкретную версию не обязательно, но желательно, так как различные сборки плагина могут быть несовместимы, и придётся долго выяснять причину внезапно появившихся ошибок. Пример со страницы плагина:

<gap:plugin name="com.phonegap.plugins.pushplugin" version="2.4.0" />

Соответствующие .js файлы должны быть импортированы на HTML странице:

<script type="text/javascript" charset="utf-8" src="PushNotification.js"></script> 

Все плагины обычно имеют документацию (пускай, и не всегда подробную) на GitHub.
Поскольку мы используем Angular.js framework, а не чистый JavaScript, дополнительный компонент требуется для того, чтобы «обернуть» плагины. Он называется ngCordova.
?
ngCordova

ngCordova это коллекция из более чем 60 Angular.js расширений на основе Cordova API, которые позволяют упростить создание, тестирование и сборку мобильных приложений PhoneGap/Cordova. Проект поддерживается и развивается командой Ionic Framework. ngCordova предоставляет простые Angular.js wrapper’ы для самых популярных и часто используемых плагинов PhoneGap/Cordova и позволяет сделать фото, отсканировать QR код, загрузить файл, включить вспышку, получить текущую локацию, а также многое другое с помощью нескольких строк кода.

Для локальной сборки всё так же необходимо добавить плагин с помощью команды:

cordova plugin add https://github.com/phonegap-build/PushPlugin.git

Для PhoneGap Build требуется ссылка на id плагина в config.xml:

<gap:plugin name="com.phonegap.plugins.pushplugin" version="2.4.0" />

ng-cordova.js импортируется из пакета ngCordova, script тэг должен быть расположен после импорта angular.js, иначе появятся ошибки, не имеющие отношения к проекту:

<script src="scripts/angular.js"></script>
<script src="scripts/ng-cordova.js"></script>

Важно не забыть добавить зависимость ngCordova к модулю:

angular.module('application', [
    'ngCordova'
])

Каждый ngCordova wrapper имеет свою документацию. Плагин для Push уведомлений и QR сканер были использованы и протестированы в нашем проекте. Сканер QR кодов (Barcode Scanner) был интегрирован без особых проблем, можно даже сказать «out-of-the-box», но настройка Push плагина заняла довольно длительное время в связи с недостатком документации – информацию приходилось собирать, просматривая огромный список issues на GitHub’е.
?
Push уведомления для Android (Google Cloud Messaging)

Краткая документация доступна на странице плагина ngCordova.

Важно! Payload часть push уведомления, отправляемая с сервера должна следовать определённому формату, иначе возможны проблемы с автоматическим появлением уведомлений в системном трее.

Было обнаружено, что объект data должен обязательно иметь поле «message» (в качестве текста уведомления) и «title» (если отсутствует, то заголовок уведомления будет пустым). Поле «uri» необходимо для того, чтобы указать действие, которое совершается при открытии уведомления.

{
    "data": {
        "message": "New message. You have 5 unread messages",
        "title": "Your Application",
        "uri": "http://www.yourapp.com/messages"
    }
}

Также важно отметить, что notificationReceived listener срабатывает тогда, когда приложение находится в foreground, а также в случае, когда пользователь открывает уведомление (переход из background’а в foreground). Push уведомления появляются автоматически в background’е и продолжают приходить даже после перезагрузки системы.

Uri может быть получен в условии ‘message’ структуры switch case listener’а.
$rootScope.$on('$cordovaPush:notificationReceived', function(event, notification) {
    console.log(notification);
    switch (notification.event) {
        case 'registered':
            if (notification.regid.length > 0) {
                registerOnServer(notification.regid);
            }
            break;
        case 'message':
            console.log('message!');
            utils.goToApiUrl(notification.payload.uri);
            break;
        case 'error':
            console.log('GCM error: ' + notification.msg);
            break;
        default:
            console.log('An unknown GCM event has occurred: ' + notification.event);
            break;
    }
});


Push уведомления на iOS

Краткая документация доступна на странице плагина ngCordova.

В момент, когда разрабатывалось приложение, часть бэкенда, которая отвечает за отправку Apple Push уведомлений (APNS) была не готова. Решили использовать временное решение для тестирования и отладки. Node Push Server был выбран первоначально (т.к. по нему имелись рекомендации в некоторых мануалах по Phonegap/Cordova), но в ходе тестирования выяснилось, что в нём отсутствует поддержка кастомных полей для Push уведомлений на iOS (поддерживаются только badge, alert и sound, а нам нужно передавать uri для открытия определённой страницы) и из-за проблем с форматом некорректно работает на iOS 6 и iOS 7 (счётчик на иконке не отображается).

Существует несколько распространённых решений на рынке, но мы выбрали платформу Parse.com для наших тестовых уведомлений на iOS, т.к. условия Free Plan вполне достаточны для процесса разработки и тестирования.
Чтобы настроить уведомления: первым делом необходимо зарегистрироваться и зайти в настройки, раздел “Settings”, затем перейти в секцию “Push” для того, чтобы включить обработку push уведомлений и загрузить требуемый сертификат (*.p12). Вы можете узнать больше о работе Apple Push Notification Service здесь.

Пример кода на основе документации ngCordova
function registerInCordova() {
    var iosConfig = {
        "badge": true,
        "sound": true,
        "alert": true,
    };
    var authHeader = {
        headers: {
            'X-Parse-Application-Id': 'YOUR_APPLICATION_ID',
            'X-Parse-REST-API-Key': 'YOUR_REST_API_KEY',
            'Content-Type': 'application/json'
        }
    };
    $cordovaPush.register(iosConfig).then(function(deviceToken) {
        // Success -- send deviceToken to server, and store for future use
        console.log("deviceToken: " + deviceToken);
        $http.post("https://api.parse.com/1/installations", {
            "deviceType": "ios",
            "deviceToken": deviceToken,
            "channels": ["ALL"]
        });
    }, function(err) {
        console.log("Registration error: " + err);
    });
}
</spoiler>
Важно не забыть поменять 'YOUR_APPLICATION_ID' и ‘YOUR_REST_API_KEY' на значения из секции “Settings” -> “Keys”. Код listener’а выполняется, когда приложение запущено в foreground или переходит из background’а в foreground (после нажатия на push уведомление).
<spoiler title="Код listener'а">
<source lang="javascript">
function registerForegroundListener() {
    $rootScope.$on('$cordovaPush:notificationReceived', function(event, notification) {
        console.log("Notification: " + JSON.stringify(notification));
        if (notification.sound) {
            var snd = new Media(event.sound);
            snd.play();
        }
        if (notification.badge) {
            $cordovaPush.setBadgeNumber(notification.badge).then(function(result) {
                console.log("Badge set successfully");
            }, function(err) {
                console.log("Error on badge setting: " + err);
            });
        }
        if (notification.uri) {
            utils.goToApiUrl(notification.uri);
        }
    });
}

Для того, чтобы отправить Push уведомление через Parse.com на все зарегистрированные устройства, необходимо выполнить HTTP POST запрос
curl -X POST   -H "X-Parse-Application-Id: YOUR_APPLICATION_ID"   -H "X-Parse-REST-API-Key: YOUR_API_KEY"   -H "Content-Type: application/json"   -d '{
        "channels": [
          ""
        ],
        "data": {
            "alert": "New Messages",
            "badge": 3,
            "uri": "api/messages"
        }      }'   https://api.parse.com/1/push ?


PhoneGap Build


— Что такое PhoneGap Build?
PhoneGap Build это бесплатный облачный сервис, построенный на основе PhoneGap/Cordova, который позволяет собирать кросс-платформенные мобильные приложения.

— Зачем нам PhoneGap Build?
PhoneGap Build позволяет делать сборки для iOS, Android и Windows Phone одновременно, без необходимости устанавливать какие-либо SDK tools (конечно, в этом есть доля лукавства – при разработке всё равно лучше делать сборку локально, хотя бы на Android, перед отправкой на тестирование). Но что более важно, этот сервис позволяет делать сборки для iOS в облаке без наличия Mac.

PhoneGap Build имеет собственный REST API, который может использоваться для автоматизации создания и обновления проектов, запуска сборки под iOS, Android и Windows Phone (можно выбирать платформу). Если вы используете GitHub, есть возможность настроить сервис для автоматической сборки после каждого коммита в репозитории. REST API позволяет авторизовать каждый HTTP запрос к серверу с помощью токена, вместо того, чтобы передавать имя пользователя и пароль в header’е.

Для использования PhoneGap Build нужно сделать настройки:
— После регистрации заходим в «create new app». Необходимо загрузить упакованное в zip содержимое папки www, config.xml должен быть внутри. Доступ к приватным GitHub репозиториям доступен только в платной версии аккаунта).
— Далее нужно перейти в настройки аккаунта: кликнуть по иконке в правом углу, “Edit account” -> “Signing keys”, добавить требуемые сертификаты и ключи (сборка для iOS прервётся при отсутствии сертификата *.p12 и профиля, сборка для Android будет выполнена в режиме AdHoc, если ключ отсутствует).

После того как установочные пакеты для всех требуемых платформ сгенерированы с помощью PhoneGap Build, можно вручную загрузить их на сервис дистрибуции. Существует множество альтернативных вариантов: HockeyApp, TestFlight, TestFairy, но далее мы рассмотрим Ubertesters и изучим, как произвести автоматизацию сборки и дистрибуции с возможностью интеграции Ubertesters Upload API.

Ubertesters


— Почему Ubertesters?
Особенности и преимущества этого сервиса обсуждаются в этой статье.

Сервис Ubertesters предоставляет SDK для всех основных платформ (даже Phonegap/Cordova). Upload API, как уже было сказано, позволяет использовать continuous integration и автоматизировать дистрибуцию.

Чтобы открыть доступ к Upload API необходимо перейти на страницу профиля.
Документация доступна по ссылке.

Установочные пакеты (ipa/apk) могут быть загружены с помощью curl
curl
    -X POST
    http://beta.ubertesters.com/api/client/upload_build.json
    -H "X-UbertestersApiKey:PERSONAL_API_KEY"
    -F "file=@upload.ipa"
    -F "title=build title"
    -F "notes=build notes"
    -F "status=in_progress"
    -F "stop_previous=true"

Чтобы разрешить автоматическую дистрибуцию на устройства команды тестировщиков и разработчиков, необходимо создать группу дистрибуции по умолчанию: “Administration” -> “Distribution Groups” -> “Add distribution group”, выбрать чекбокс “Default group”. Так как в нашем случае поддерживаются 2 платформы, нужно не забыть совершить операцию для каждого из проектов (iOS и Android).
?

Автоматизация задач


Существует несколько способов автоматизации процесса сборки для приложений на PhoneGap/Cordova. В качестве task manager’a можно использовать Grunt, Ant, Maven а в качестве среды для continuous integration Jenkins CI или Team City.

Конфигурация Grunt

Grunt требует наличия двух файлов: package.json (он определяет зависимости и базовые настройки) и gruntfile.js (конфигурация задач).
Для начала нужно установить grunt-cli:

npm install -g grunt-cli

Можно использовать следующие настройки для package.json
{
    "name": "Your application",
    "version":"1.0.0",
    "description": "Your App",
    "main": "index.html",
    "author": "",
    "licenses": "",
    "devDependencies": {
        "form-data": "^0.2.0",
        "fs": "0.0.2",
        "grunt": "0.4.5",
        "grunt-contrib-compress": "0.9.1",
        "grunt-http": "^1.6.0",
        "grunt-magikarp": "^0.2.5",
        "grunt-modify-json": "^0.1.1",
        "grunt-xmlpoke": "^0.8.0",
        "needle": "",
        "read": "~1.0.4"
    }
}

Зависимости, заданные в package.json, могут быть удовлетворены с помощью npm install
Все необходимые модули будут установлены в /node_modules
Но также потребуется установить grunt-phonegap-build вручную:

npm install grunt-phonegap-build

На Dropbox доступен пример Gruntfile.js:

Несколько параметров необходимо установить перед использованием:
  • var PHONEGAP_API_ID = «YOUR_PHONEGAP_API_ID»;
  • var PHONEGAP_TOKEN = «YOUR_PHONEGAP_TOKEN»;
  • var UBERTESTERS_API_KEY = «YOUR_UBERTESTERS_API_KEY»;
  • В конфигурации задачи phonegap-build должен быть указан пароль для сертификата iOS.

Далее мы рассмотрим все используемые в проекте задачи task manager’а Grunt в порядке использования в скрипте.

Список задач Grunt

1) http:phonegap_build_version

Мы получаем текущую версию из сервиса PhoneGap Build с помощью HTTP GET запроса:

http://build.phonegap.com/api/v1/apps/' + PHONEGAP_API_ID + '?auth_token=' + PHONEGAP_TOKEN

Методы и документация PhoneGap Build Read API доступны по ссылке.

2) readCurrentVersion

Результат http:phonegap_build_version возвращается в формате JSON и сохраняется по указанному пути:

ubertesters_response/phonegap_app.json

В данный момент скрипт имеет баг: phonegap_app.json должен быть создан вручную до запуска (можно просто создать пустой JSON file). Текущая версия передаётся как параметр к modify_json.

3) modify_json

Обновляет значение текущей версии в package.json.

4) magikarp

Magikarp инкрементирует текущую версию в package.json. Опции доступны: major, minor и build.

5) readNextVersion

Инкрементированная версия из package.json передаётся в xmlpoke.

6) xmlpoke

Изменяет версию в файле www/config.xml.

7) compress

Сжимает содержимое папки www (не саму папку, это важно!), исключая ненужные файлы. Сжатый zip файл сохраняется по указанному пути target/phonegapp.zip

8) phonegap-build:debug

В данный момент debug и release ничем не различаются (release ключ ещё не сгенерирован для Android). Сжатый zip файл отправляется на сервис PhoneGap Build. Задача завершается только после сборки (ios/android) и сохранения установочных пакетов (ipa/apk).
Методы и документация PhoneGap Build Write API methods доступны по ссылке.

9) http:ubertesters_ios

Эта задача загружает ipa сборку на Ubertesters с помощью Upload API. Здесь можно использовать любой сервис дистрибуции мобильных приложений, если он имеет REST API.

10) http:ubertesters_android

Та же задача, но для Android apk.

11) PROFIT!

Grunt запускается локально с помощью команды ‘grunt’ или на сконфигурированном build сервере (TeamCity в нашем случае). Также есть возможность настроить TeamCity, чтобы вызывать процесс сборки и дистрибуции при каждом коммите.

Так можно сэкономить немало времени, используя continuous integration при сборке и тестировании мобильных приложений.

Полезные ссылки


Automating PhoneGap builds
Сервисы дистрибуции мобильных приложений для iOS. Часть 3: Ubertesters

Комментарии (18)


  1. BigD
    25.05.2015 12:48
    +1

    А расскажите плиз про Phonegap в целом — достоинства, недостатки, ограничения и т.д.


    1. boodda
      25.05.2015 13:50
      +3

      1. Сложно заставить нормально работать Socket.io, почти получилось, но все равно, то тут, то там появляются косяки с отваливающимся соединением.
      2. Любые CSS3 плюшки адски тормозят приложение, особенно если их надо тянуть пальцем(тут все тушите свет, даже на топовых моделях лагает сие чудо)
      3. Ужасный дебагинг, или я просто не понял как сделать нормально. Приходилось писать либо в console.log или в отдельную вкладку и скрывать ajax кнопкой.
      4. Постоянная засада со стилями HTML. Этот телефон нормально показывает, другая модель… пфф… все разъезжается в разные стороны, поправил, что то уехало или пропало на третьем телефоне, с учетом отсутствия дебага для html + css. Все это очень долго, нудно и бесит, что непонятно что не так в конкретном случае

      Не столько по самой кордове добавлю: собирал все локально, под apple это был какой то ад с сертификатами(Push, и т.д и т.п) в этом плане под Google было значительно проще.

      p.s А вообще делал личный кабинет для сайта (в качестве проверки на нужность вообще приложения). Намучался сильно (довольно простое приложение чат, с несколькими плюшками, и полной отрисовкой на стороне приложения, а с сервером только по апи общение) заняло почти 3 месяца.

      p.p.s Лучше бы отдали на аутсорс, написать 2 нативных приложения


      1. RouR
        25.05.2015 14:42
        +1

        Попробуйте запускать в эмуляторе ripple. Тогда можно будет открывать в хроме, а там отладка стилей вполне удобна. Правда он эмулирует только саму кордову, без плагинов.
        Отладка под андроид, со всеми плагинами кроме оплаты, возможна для версий 4.4+.


      1. Sergiy
        25.05.2015 17:39
        +2

        я вот немножко не соглашусь:

        1. в моем случае был не Socket.io, а PhotonSDK (от exitgames) отлично работает, даже не смотря на «beta» у JS библиотеки.
        2. тут не знаю, встроенные Ionic анимации очень даже шустро на Nexus 4 работали.
        3. developer.chrome.com/devtools/docs/remote-debugging?
        4. Есть панацея в виде CrossWalk, хоть и тащит лишних 10 мб

        5. У меня ушло ровно 7 часов, чтобы разобраться под обе платформы со всеми сертификатами, UDID, ad-hoc… Не могу сказать, что уж очень сложно.


        1. Sergiy
          25.05.2015 17:48

          Не то, чтобы я был в диком восторге от гибридных, но мой «саксес стори» был такой:
          Местный банк хотел выпустить аппликацию для электронного банкинга, iOS+Android обходился в 2500$ и месяц ожидания. С Ionic-ом я предоставил рабочую версию через 4 дня и бюджетом в 1000$.


        1. boodda
          25.05.2015 21:42

          1.socket.io уже на сервере для десктоп клиентов, так что тут выбирать вообще не пришлось) На него ушло как раз недели 2-3 борьбы с тупо отваливающимся коннектом, который сам что то не восстанавливается в половине случаев, пришлось городить костыли для реконнекта.

          2.а Ionic он на CSS3 или JS прорисовка, я так понял там просто CSS3 тормозят.

          5.У меня не сказать что ушло больше, но просто их много я насчитал около 10 штук)))

          ripple там чет у меня совсем не захотел работать походу из за плагинов.


    1. milkiway Автор
      25.05.2015 14:08

      В этой статье для краткости решил убрать общую информацию, т.к. Phonegap уже довольно широко обсуждался, существует множество обзоров и его сравнений с native разработкой (например, тут). Но в дальнейшем планируется написать больше о трудностях и багах, с которыми можно столкнуться при кросс-платформенной разработке.


  1. frizzyH
    25.05.2015 13:09

    И вы действительно пользуетесь бесплатной версией PhoneGap Build? Там же ограничение только на 1 приложение. К тому же, раньше он еще и вставлял свой логотип и свою же иконку, т.к. нельзя было это сконфигурировать. Так и осталось?


    1. milkiway Автор
      25.05.2015 14:13

      Т.к. у компании-клиента только одно приложение, то такого аккаунта достаточно, иконки и splash screen'ы сейчас можно указать любые в config.xml. PhoneGap Build берёт настройки из этого файла при сборке.


  1. Divers
    25.05.2015 13:24

    Мне вот всегда интересовало — хотя бы одно конкурентоспособное приложение было сделано за все годы существования этого подхода? Имею в виду конечно не всякий шлак для корпоративного пользования, где пользователей не жалко — им деньги за мучения платят, а приложения для рынка.


    1. frizzyH
      25.05.2015 13:30
      +1

      На сайте самого PhoneGap есть примеры же. Я, например, Untapped пользуюсь. Работает лучше, чем можно было бы ожидать


      1. Divers
        25.05.2015 14:01

        Что за Untapped? Не смог найти через GP, можете ссылку дать?

        btw, на сайте что-то все программы 2012-2013 года, видимо тогда люди еще верили, что так можно делать приложения.


        1. frizzyH
          25.05.2015 14:34

          Ошибся я немного он Untappd (pg, g play). Для андроида последнее обновление было 20 мая.


          1. Divers
            25.05.2015 14:44
            +1

            Попробовал — пользоваться действительно можно, но не хочется. Большой лаг на любые действия. Когда листаешь список, а потом останавливаешься — он моргает. Выглядит вообще не как Андроид приложение. Нет перехода свайпом между табами. Еще я подозреваю, что они потратили раза в 2 больше денег, чем на разработки 2х найтивных приложений.


  1. Makaveli
    25.05.2015 23:27

    Столько времени уже проекту, а заходишь в комменты — снова комментарии на тему тормозов и прочих проблем :\


    1. frol
      26.05.2015 09:28

      Ничего удивительного, это ж тормоза и ограничения от WebView. Кстати, с использованием CrossWalk, который позволяет упаковать WebView поновее прямо в приложение, жизнь становится чуть лучше в плане скорости, но иногда приложение просто разваливается…

      Я уже неколько лет жду (не горит, так что с Java я мириться не спешу) какой-то альтернативы в области кросплатформенных приложений под мобильные девайсы без компромисов в духе: всё что у вас есть — однопоточный JS, зоопарк версий WebView, ваш HelloWorld весит «всего» 50МБ (утрировано, но 15+МБ — это тоже не идеал), загрузка приложения занимает 5+ секунд.


      1. Makaveli
        26.05.2015 09:50

        То есть PhoneGap уже годами плохое решение, только за несколько лет Facebook осознал, что веб-приложение — плохое решение, сделал и выкатил свой React Native, а PhoneGap бьётся головой о стену годами?


        1. frol
          26.05.2015 13:52

          Я не говорил, что PhoneGap плох. Я указал на то, что PhoneGap ограничен возможностями WebView, и они, да, будут биться головой о стену до тех самых пор пока WebView не станет производительнее/стабильнее/… (Но я не думаю, что он имеет запас для оптимизации, которую мы сможем заметить визуально, если честно.) То, что крупные компании что-то делают в популярных сообществах — ни о чём не свидетельствует совершенно. Кроме того, в Google Play есть несколько Lite версий их главного приложения и они выпустили Facebook Lite, так что они понимают где находятся границы. PhoneGap несомненно подойдёт для быстрого прототипа, но если вы не считаете, что тормоза вашего приложения у пользователей — это их проблема из-за «слабого прошлогоднего флагмана», то вам очень скоро прийдётся писать нативные приложения (пока что я не видел альтернативы, к моему сожалению).