Дисклеймер
Разрабатывать легко, но есть нюансы.
Вступление
Приветствую. С вами Дени Сергеевич, ведущий разработчик МТС Ticketland. В этой статье я расскажу о своем опыте разработки TWA: какие инструменты выбрать, на какие грабли наступил и костыли пришлось сделать, чтобы все заработало. В конце статьи поделюсь своими выводами на что обратить особое внимание.
Что такое TWA
TWA (Trusted Web Activities) — специальный режим запуска браузера на базе кастомных вкладок Android Custom Tab. В отличие от WebViews, решение от Google предоставляет больше функций веб-платформы, что делает переход для конечного пользователя между нативным и веб-контентом более плавным.
На практике TWA предоставляет сравнимые возможности PWAs (Progressive web apps) и добавляет дополнительный функционал для операционной системы Android. Это публикация в магазин приложений Google Play, интегрированная монетизация, поддержка веб-нотификаций и другие менее значимые возможности, вроде анимации и кастомизации окна приложения.
Инструменты создания
Создать TWA можно используя привычные языки веб-программирования и слоя генерации сборки приложения. Я рекомендую использовать TypeScript для создания бизнес-логики и Java для сборки Android App Bundle.
Vue.js
В 2022 году Vue.js окончательно переехал на третью мажорную версию с новым быстрым и меньшим по размерам ядром. По популярности Vue.js давно наступает на пятки React.JS, предлагая сравнимую функциональность с низкой кривой входа для новичков, благодаря заложенным в фреймворк паттернам проектирования.
При выборе написания кода, рекомендую сразу использовать Composition API как более современное решение. Оно имеет лучшую поддержку TypeScript, проще читается и не раздувает код как это делает Options API.
Quasar Framework
Базируясь на Vue.js Quasar Framework предоставляет удобные повторно используемые компоненты в стиле Material Design, которые можно кастомизировать через CSS и расширять через методы JavaScript. Этот фреймворк покрывает более 90% типовых решений, предлагая командный интерфейс quasar-cli для инициализации, запуска, тестирования и сборки проекта.
Из коробки Quasar генерирует PWA используя два следующих инструмента:
Manifest
Здесь задаются данные для приложения: стандартные размеры иконок, описание, цвета. Подробнее про настройку манифеста веб приложений, читайте здесь: https://developer.mozilla.org/ru/docs/Web/Manifest.
Service Worker
Service Worker (далее SW) - это скрипт, который работает в фоновом режиме предоставляя механизм роутинга и кеширования ресурсов веб-приложения.
Видов SW ровно два:
GenerateSW - самый простой способ добавить SW на сайт, создает отдельный заранее сгенерированный файл конфигурации.
InjectManifest - предоставляет дополнительную логику, основанную на Web Worker.
Более подробно про настройку можно прочитать здесь: https://developer.chrome.com/docs/workbox/modules/workbox-webpack-plugin.
Документация по конфигурация SW доступна по ссылке: https://quasar.dev/quasar-cli-webpack/developing-pwa/configuring-pwa.
Android Studio
Эта среда программирования для Android основанная на популярной ныне кроссплатформенной IDEA. Включает дополнительно необходимые отладчики и компиляторы для Java и Kotlin, Device Manager, монитор логов и другой необходимый софт для программирования на Android под ключ.
Скачать Android Studio можно здесь: https://developer.android.com/studio/.
Bubblewrap CLI
Этот инструмент позволяет через консоль создавать готовую сборку Gradle и Android Manifest из существующего веб-манифеста, находящегося в конфигурации Quasar Framework. Со своей задачей в принципе справляется, но сам инструмент плохо обновляется и как будет видно в конце статьи, неудобен в работе. Узнать как использовать Bubblewrap CLI вы можете здесь: https://developer.chrome.com/docs/android/trusted-web-activity/quick-start.
Скачать Bubblewrap CLI через npm: https://www.npmjs.com/package/@bubblewrap/cli.
Как работает PWA на iOS
Начиная с iOS 15, Apple включили частичный функционал PWA в системный браузер Safari. На главном экране действительно появляется иконка сайта, неотличимая от нативных приложений. При клике на нее запускается сайт без элементов управления браузера.
Создавая PWA под iOS нужно быть готовым что не получится в оффлайне использовать функции Touch ID или Face ID. Костылем может стать использование спецификации Web Authentication (WebAuthn), которая появилась в iOS 16, но данная спецификация требует доступ в онлайн.
Push-уведомления так же не работают в режиме PWA в мобильном Safari.
Еще одной особенностью PWA приложения на iOS становится невозможность переопределения квоты для IndexedDB, ругаясь на "QuotaExceededError: Failed to PutOrAdd in database". При этом такая функция работает если заходить через браузер Safari напрямую.
Сборка TWA
Создание сборки на выбранных инструментах выполняется двумя следующими командами.
Создать сборку PWA используя Quasar Framework:
quasar build -m pwa
Создать сборку Android используя Bubblewrap CLI:
bubblewrap build
После этого у вас будут созданы файлы приложения, которые можно установить на виртуальное устройство следующей командой:
bubblewrap install
Тестирование TWA
Этап тестирования ничем не отличается от тестирования мобильного сайта на физическом устройстве. Запускаем приложение с главного экрана, выбираем Inspect Tools и кликаем на Remote Target. Подробнее как включить тестирование на Android написано здесь: https://developer.chrome.com/docs/devtools/remote-debugging/.
Замечено, если у пользователя стоит по-умолчанию Firefox, то после установке TWA потребуется запускать отладчик на аналогичный платформе, то есть на Firefox Debugger.
Публикация в Google Play Market
Особенностью 2022 года стало то, что магазин приложений Google Play недоступен на территории РФ, что пока еще можно исправить используя VPN другой страны. Но так как Android определенным образом открыт, то сборочные файлы App Bundle можно использовать для прочих аналогов Google Play, с соответствующими проблемами веб-нотификаций и установки рекламы от Google Ads.
Установка и настройка TWA в Google Play Market не отличается от обычной установки, но добавляется установка Digital Asset Links в разделе App Integrity. Если вы подписывали приложение через ключ разработчика Google, тогда достаточно просто скопировать предложенные ключи из появляющегося раздела. Иначе установите те ключи, что сгенерировал вам Bubblewrap CLI. Сами ключи должны храниться на контролируемом вами сервере в пути .well-known/assetlinks.json.
Чтобы сгенерировать собственный файл assetlinks.json через Bubblewrap CLI и поместить его в нужную директорию выполните команду:
bubblewrap fingerprint generateAssetLinks --output=\"public/.well-known/assetlinks.json\"
Проверено, 301 редирект на файл assetlinks.json из корня сайта не работает. Поэтому переносить файл придется вручную следующим образом:
cp public/.well-known/assetlinks.json dist/pwa/.well-known/
В 2022 году для публикации в магазин Google Play требуется заполнить множество документов, одним из которых является Пользовательское соглашение. Вы можете не заполнять его самостоятельно, а воспользоваться бесплатным сервисом https://app-privacy-policy-generator.nisrulz.com.
Модерация у меня заняла почти пять дней. Заранее убедитесь, что у вас все работает и что сервер отвечает за приемлемое время. Для TWA критично чтобы рейтинг производительности был минимум 80/100 в Lighthouse.
ВЫВОДЫ
TWA - все еще плохая альтернатива нативным приложениям, которая может сгодится только если у вас уже готов хороший мобильный сайт и вы не желаете тратить время и деньги на разработку нативной Android версии.
Спустя время выбор настоящих инструментов показал следующее результаты:
Vuex - лучше заменить на Pinia. Vuex на данный момент имеет четвертую версию с избыточным синтаксисом при работе с Composition API и TypeScript. Pinia видится мне свежей альтернативой, которая к тому же регулярно обновляется.
Quasar Framework - в продакшене показал множество проблем на выпадающих списках и сложных формах. Часть из них требует самостоятельного исправления, часть являются багами мобильного браузера Safari. Установка шрифтов и иконок Material Design требует соединения с сервером Google из-за чего пропадает возможность открывать сайт вне PWA режима.
PWA - не годится для программирования больших и сложных приложений. Загрузка новой версии может занимать весомое время, которое на Android можно скрыть картинкой, тогда как пользователи iOS будут видеть черный экран браузера. Создавать что-то связанное с изображениями, камерой или устройствами Bluetooth, в настоящее время так же будет выглядеть плохо, как с точки зрения плавности интерфейса, так и с технической возможностью. Например, тег <img> в Safari способен отображать PDF документы, а в Chromium браузерах нет; так же замечено, что функционал navigator.share не работает в Firefox на момент написания статьи.
Bubblewrap CLI - в своем генераторе использует захардкоженные версии Gradle и Java и не имеет гибкой настройки конфигурации. Я решил после первичной инициализации Android Manifest им больше не пользоваться. Теперь вручную исправляю зависимости, обновляю версии Gradle и делаю сборки через Android Studio.
Веб-манифес - не все так радужно. TWA не поддерживает часть спецификации значений iarc_rating_id и categories. Кроме того, theme_color не поддерживается на iOS.
HTTP кеширование - не следует создавать кэширование скриптов и документов через сервер, тогда при обновлении билда загрузка ресурсов будет невозможна. Поэтому все кеширование вам предстоит перенести на плечи SW.
PDF - имейте в виду, что создание русскоязычных документов исключительно в браузере на популярной библиотеке jsPDF показывает глюки. Переход на библиотеку @pdfme/generator исправляет проблему.