Недавно я изучал, как можно обернуть приложение Angular в нативную оболочку, чтобы расширить приложение с помощью собственных возможностей и обеспечить более богатый пользовательский интерфейс.
В качестве второстепенной цели я стремился избежать дублирования кода и обеспечить то же самое. Исходный код может использоваться как веб-пользователями, так и мобильными пользователями, устанавливая его версию с встроенной оболочкой.
Что касается взаимодействия с пользователем, я намеревался улучшить навигацию между внутренними и внешними URL-адресами и сократить время загрузки приложения.

Знакомство с Кордовой

Cordova - зрелый проект с открытым исходным кодом и сплоченным и активным сообществом. Cordova имеет очень простое и минималистичное ядро, которое можно легко расширить, установив дополнительные плагины. Кроме того, в Cordova есть очень удобный интерфейс командной строки для быстрой загрузки нового проекта и управления расширениями.

В следующих разделах я кратко объясню основные концепции Cordova и как настроить минимальный проект для обертывания приложения Angular.

Проще говоря, Cordova действует как веб-сервер, обслуживающий веб-ресурсы, размещенные в папке www. Вдобавок ко всему, Cordova предоставляет API, доступный через выделенную службу JS:

<script type=”text/javascript” src=”cordova.js”></script>

Служба JS действует как мост между веб-приложением и собственной оболочкой, позволяя, например, открывать определенные URL-адреса внутри окна браузера в приложении.

<script type=”text/javascript”>
   cordova.InAppBrowser.open(url,“_blank”);
</script>

Платформы и плагины

После создания пустого проекта Cordova можно добавлять платформы и плагины. Добавление платформ в проект расширит поддержку дополнительных платформ, таких как iOS, Android и т. Д., А добавление плагинов расширит функциональные возможности и обеспечит специальные нативные функции.

Плагины и платформы можно просто добавить с помощью Cordova CLI:

cordova platform add ios
cordova plugin add cordova-plugin-statusbar

Создание проекта в Кордове

Установка Apache Cordova

Установить Cordova в локальной системе очень просто. Это также установит Cordova CLI, который мы будем использовать для создания нового проекта.

npm install -g cordova

Создание нового проекта

cordova create CordovaMobileApp com.acme.app "CordovaMobileApp"

Тестирование проекта Кордова

Самый простой способ протестировать только что созданный проект - добавить платформу браузера и запустить проект.

cd CordovaMobileApp
cordova platform add browser
cordova run browser

Пустой проект Cordova поставляется со скелетом приложения по умолчанию, включая файл index.html и index.js. сценарий. Что еще более важно, проект уже включает службу Cordova JS для доступа к API Cordova.

Упаковка приложения Angular - настройка MVP

Обернуть приложение Angular в Cordova так же просто, как создать приложение Angular и поместить его в папку проекта www Cordova.
Я бы посоветовал хранить проект Angular и проект Cordova в двух разных папках, чтобы избежать смешивания соответствующих папок node_modules и зависимостей проекта. При создании приложения Angular параметр output-path можно настроить так, чтобы приложение сборки помещалось непосредственно в папку www Кордовы. Кроме того, следует использовать параметр base-href, чтобы установить для базовой ссылки значение «. в качестве абсолютных путей. не очень хорошо обрабатываются Кордовой.

ng build --prod --base-href . --output-path ../CordovaMobileApp/www/

Добавление скрипта Cordova JS

Наконец, для полной интеграции Cordova необходимо указать ссылку на ее файл сценария в файле index.html. Это обеспечит загрузку API Cordova и запуск события «deviceready».
Примечание. Файл сценария cordova. js, автоматически обслуживается оболочкой Cordova; вам не нужно никуда его размещать.

<script type=”text/javascript” src=”cordova.js”></script>

Интеграция с жизненным циклом Cordova

Cordova запускает различные события, чтобы сигнализировать веб-приложению о текущем статусе жизненного цикла; наиболее важными из них являются «устройство готово», «пауза» и «возобновить . "

Приложение Angular следует загружать только после запуска события Cordova «deviceready». Это гарантирует, что все ресурсы загружены и API службы Cordova готов к вызову. Для этого достаточно изменить файл Angular main.ts следующим образом:

let onDeviceReady = () => {
  platformBrowserDynamic().bootstrapModule(AppModule);
};
document.addEventListener('deviceready', onDeviceReady, false);

Тест на iOS

После адаптации приложения Angular для загрузки файла cordova.js и ожидания события готовности устройства перед загрузкой мы можем протестировать интеграцию.

cordova platform add ios
cordova emulate ios

Расширенная интеграция

В следующих разделах будет рассмотрена более продвинутая интеграция, которая обеспечивает бесшовное соединение приложения Angular с API Cordova через специальную службу Angular.

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

Кордова Сервис

Создание инъекционного сервиса Angular, предоставляющего служебные функции и ссылку на объект Cordova Javascript.

ng g service Cordova

Минимальная версия службы Cordova позволит нам запросить службу, запущено ли приложение на Cordova, получить объект JS Cordova для доступа к API и подписаться на событие возобновления. Прослушивание события возобновления особенно полезно, если необходимо обновить содержимое приложения.

import { Injectable,NgZone } from ‘@angular/core’;
import { Subject } from 'rxjs/Subject';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/fromEvent';
import 'rxjs/add/operator/map';

function _window(): any {
 // return the global native browser window object
 return window;
}
@Injectable()
export class CordovaService {
   
   private resume: BehaviorSubject<boolean>;
   constructor(private zone: NgZone) {
      this.resume = new BehaviorSubject<boolean>(null);
      Observable.fromEvent(document, 'resume').subscribe(event => {
         this.zone.run(() => {
            this.onResume();
         });
      });
    }
   
   get cordova(): any {
      return _window().cordova;
   }
   get onCordova(): Boolean {
    return !!_window().cordova;
    }
   public onResume(): void {
      this.resume.next(true);
   }
}

Регистрация и распространение событий жизненного цикла

Cordova запускает событие возобновления каждый раз, когда приложение возобновляет работу в фоновом режиме. Чтобы правильно обработать это событие в области приложения Angular, NgZone используется для запуска прослушивателя событий внутри зоны Angular.

constructor(private zone: NgZone) {
   this.resume = new BehaviorSubject<boolean>(null);
   Observable.fromEvent(document, 'resume').subscribe(event => {
      this.zone.run(() => {
            this.onResume();
      });
   });
}

Просмотр в приложении

Распространенный вариант использования мобильных приложений - необходимость открывать внешние ссылки. Без оболочки веб-приложения эти ссылки обычно открываются на другой вкладке браузера. На рабочем столе это может быть приятным поведением; однако навигация между вкладками на мобильном устройстве - довольно неприятное занятие. Вместо этого встроенный в приложение браузер позволяет открывать внешние ссылки в одном приложении и не заставляет пользователя покидать приложение.

Это достигается путем установки подключаемого модуля браузера Cordova в приложении «cordova-plugin-inappbrowser». Лично я предпочитаю альтернативный подключаемый модуль «cordova- plugin-safariviewcontroller », который использует современные представления SafariViewController (iOS) и Chrome Custom Tabs (Android) для отображения веб-страниц в приложении.

cordova plugin add cordova-plugin-inappbrowser
cordova plugin add cordova-plugin-safariviewcontroller

Чтобы открыть внешние URL-адреса, мы можем расширить нашу Angular CordovaService, чтобы использовать установленный плагин.

public openLinkInBrowser(url: string) {
    _window().SafariViewController.isAvailable(function(available) {
        if (available) {
           _window().SafariViewController.show({
              url: url,
              barColor: “#f7f7f9”,
              tintColor: “#1ca8dd”,
              controlTintColor: “#1ca8dd”,
           });
        } else {
             _window().cordova.InAppBrowser.open(url,“_blank”);
        }
   })
}

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

Решение проблем с маршрутизацией

У Cordova есть некоторые проблемы при работе с Angular по умолчанию PathLocationStrategy, поскольку он, похоже, не полностью поддерживает одностраничные приложения HTML5. Вместо этого маршрутизатор должен быть проинструктирован использовать HashLocationStrategy.

RouterModule.forRoot(appRoutes, { useHash: true})

Заменить ресурсы, обслуживаемые через CDN

Хотя использование ресурсов, доставляемых через CDN (например, шрифтов, CSS или JS-фреймворков и т. Д.), Отлично подходит для веб-приложений, это не относится к упакованным мобильным приложениям, особенно если эти приложения можно использовать в автономном режиме. Чтобы завернутые приложения работали в автономном режиме, все необходимые ресурсы должны быть получены локально. Для этого достаточно загрузить эти ресурсы, поместить их в папку ресурсов Angular и изменить их ссылочные URL-адреса.

Отключить выбор пользователя

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

Чтобы отключить выбор текста пользователем, достаточно добавить настраиваемое правило CSS, которое применяется к любому элементу HTML, кроме полей ввода.

* {
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}

input {
-webkit-user-select: auto !important;
-khtml-user-select: auto !important;
-moz-user-select: auto !important;
-ms-user-select: auto !important;
user-select: auto !important;
}

Кордова крючки

Перехватчики Cordova позволяют регистрировать пользовательские скрипты, которые будут вызываться системой сборки
Cordova.

Используя хуки Cordova, мы можем применять изменения к приложению Angular, которые относятся только к обернутой версии. Наиболее очевидным отличием является наличие сценария cordova.js в файле index.html. В дополнение к этому у нас могут быть некоторые ресурсы, обслуживаемые через CDN, которые вместо этого выбираются локально.

В следующем примере сценарий используется для переключения конфигурации в файле index.html, раскомментируя часть, относящуюся к Кордове, и комментируя веб-версию.

<!-- web-version-config-on -->
  <meta name="viewport" content="width=device-width">
  <style>
    @import url('//fonts.googleapis.com/cssfamily=Montserrat:100');
  </style>
<!-- end-web-version-config-on -->
<!-- cordova-version-config-off
   <meta name="viewport" content="width=device-width, user-sc...">
   <script type="text/javascript" src="cordova.js"></script>
   <link rel="stylesheet" href="assets/fonts/montserrat-font.css">
   <style>
       * {user-select: none;...}
       input {user-select: auto !important;}
  </style>
end-cordova-version-config-off -->

Сценарий, используемый для комментариев и необычных разделов файла index.html, должен быть помещен в папку хуков before_prepare Cordova: /CordovaMobileApp/hooks/before_prepare/01_switch_donfiguration.js

В результате, когда Cordova создает новую версию, сценарий заменяет комментарии в файле index.html, включая часть, относящуюся к Cordova, и отключает веб-часть. Такой подход помогает избежать дублирования кода и требует лишь нескольких отклонений между Cordova и веб-версией приложения Angular.

Заключение

Эта статья призвана помочь вам начать работу, представив Cordova и предоставив некоторые важные настройки, необходимые для хорошей работы Angular в среде с исходной оболочкой.
Если вы чувствуете, что в статье не упоминаются другие важные аспекты, оставьте комментарий ниже. Соответственно буду улучшать статью.

p.s. Если вы нашли эту статью полезной, похлопайте ее в ладоши или поделитесь ею, чтобы другие были найдены.

использованная литература