Библиотека UI модулей CASHOFF включает в себя не только модули для встройки на сайты, но и модули, ориентированные на встройку в мобильные приложения iOS и Android. Такие модули требуют более тесной интеграции с приложением, т.к. требуют для использования интеграцию с некоторыми нативными функциями мобильных ОС, которые не доступны внутри webview.

Особенности встройки

Ключевым модулем для встройки в мобильное приложение является mobile-main, который внутри себя реализует полноценную подсистему с PFM, кешбеком и импортом данных. Данный модуль предназначен для отображения во весь экран устройства и включает в себя навигационную панель в верхней части экрана.

Т.к. модули CASHOFF основаны на web-технологиях, то для встройки в нативное приложение понадобится на форме разместить компонент webview. Поддерживаемые версии webview указаны в общей части, посвященной модулям.

Так же понадобиться реализовать промежуточную html-страницу, которая будет загружаться внутри webview и в свою очередь загружать libco.js и модули. Эта страница будет работать с js API libco.js и пересылать необходимые данные и вызовы в/из нативной части приложения.

Выбор языка

Мобильные модули на данный момент доступны в двух языках: русский и английский. Язык указывается на сессию и распространяется автоматически на все модули. Для выбора языка нужно вызвать функцию setLanguage:

session.setLanguage('en')


Сделать это лучше всего до открытия первого модуля. Однако изменение языка возможно и после того, как модуль был открыт – в таком случае язык открытых модулей тут же изменится.
Язык указывается в виде двухсимвольного кода стандарта ISO 639-1. 

Кнопка "назад" в Android

Устройства на платформе Android имеют встроенную кнопку «назад» либо её экранный аналог. Нажатие на эту кнопку необходимо пробрасывать в текущий открытый модуль CASHOFF что бы он мог осуществить навигацию внутри себя. Подход следующий:

  1. клиент в приложении открывает форму с модулем CASHOFF (например mobile-main)
  2. клиент в процессе работы с модулем углубляется на несколько уровней навигации внутри модуля 
  3. клиент нажимает кнопку "назад"
  4. приложение вызывает метод navigateBack модуля и ожидает от него результат:
    1. true будет означать, что модуль выполнил навигацию назад. В таком случае приложению ничего больше делать не нужно, нажатие считается обработанным.
    2. false будет означать, что модулю некуда идти назад и навигация должна быть осуществлена в самом приложении. В таком случае приложение осуществляет переход назад в своем интерфейсе.

Пример вызова метода:

module.runMethod('navigateBack').then(function(isNavigated){
	if (!isNavigated) {
		appCore.navigateBack();
	}
})

Интеграция с нативными компонентами

Ниже перечислены функции, необходимые для полноценной работы модулей CASHOFF, а так же механизм их предоставления. Однако не во всех случаях их все необходимо реализовывать - если используемый приложением функционал какие-то функции не использует, то их можно не реализовывать. 

Сканер QR кодов

Сканер используется преимущественно для сканирования QR кодов c чеков для импорта последних в CASHOFF (функционал кешбека и импорта данных). Для работы данной функциональности нужно прежде всего добавить сканер в приложение, а потом сделать его доступным для модулей. Доступ к сканеру предоставляется через метод openQRScanner:

session.exportMethod('openQRScanner', (args) => {
	return new window.Promise(function(resolve, reject) {
		...
		return {
			cancelled: false,
			text: 't=20181007T222000&s=3124.00&fn=8710000101915756&i=13363&fp=2419878849&n=1',
		}
	})
})

При вызове данного метода приложение должно открыть форму сканера QR кода, дождаться пока клиент отсканирует код, закрыть форму и вернуть результат сканирования в качестве возвращаемого значения. Скорее всего происходить это будет асинхронно, по этому результат будет возвращаться через Promise.

В качестве аргумента args приложение  получит объект с атрибутами:

  • prompt: текст сообщения, который желательно добавить на форму. Он является подсказкой для клиента, описывающей что нужно сделать.

Вернуть необходимо объект со следующими полями:

  • cancelled: булевое значение, сигнализирующее что клиент отменил сканирования
  • text: содержимое QR кода в виде текста. Не заполняется, если cancelled == true

Открыть ссылку в браузере телефона

Модулю может понадобится возможность открыть некоторую ссылку отдельно в браузере мобильного устройства. В частности это используется в функционале умных советов и кешбека. Данная возможность предоставляется через реализацию метода openLinkInBrowser:

session.exportMethod('openLinkInBrowser', (url) => {
	appCore.openBrowser(url)
})

В качестве аргумента передается строка - url для открытия в браузере.

Доступ к камере устройства

CASHOFF использует стандартные средства WebView для работы с камерой устройства, по этому дополнительных методов экспортировать не нужно. Однако необходимо, что бы у приложения были права на доступ к камере. Если используется запрос прав по необходимости, то потребуется реализовать соответствующий метод:

session.exportMethod('requestCameraPermissionForWeb', () => {
	return true;
})

Данный метод будет вызван при первом использовании камеры. В качестве результата ожидается булевое значение, которое сообщит предоставлен ли доступ или нет. Если метод не реализован, то модуль предполагает что все необходимые ему права предоставлены.

Доступ к камере используется для загрузки фотографий в систему.

Доступ к координатам устройства

Модуль в свое работе может использовать текущие координаты пользователя. Основная сфера применения геопозиции - аналитика финансов по географии и предоставление подсказок и советов в зависимости от геоположения клиента.

Для работы с координатами используется стандартное JS API Geolocation: https://developer.mozilla.org/en-US/docs/Web/API/Geolocation/getCurrentPosition

Если данное API доступно из iframe, то никаких дополнительных действий не требуется. Если же оно не доступно, то функцию с аналогичным интерфейсном необходимо экспортировать через объект сессии:

session.exportMethod('geolocationGetCurrentPosition', (url) => {/* ... */})

Встраивание в Android приложение с прозрачным статусбаром

Если модуль встраивается в приложение с прозрачным статусбаром и модуль расположен с самого верха экрана, то для корректного отображения необходимо передать ему высоту статусбара:

session.exportMethod('getTopbarHeight', () => {...})

Результатом ожидается число в единицах pt.

Встраивание в iOS приложение с поддержкой iPhone X и выше

Если модуль отображается полноэкранно, то для данной серии устройств необходим учёт области safe-area, что бы интерфейс не попадал под вырез сверху или элементы интерфейса iOS снизу. Т.к. модуль не может знать как он располагается в приложении, то ему требуется явно указывать необходимость добавления отступов. Делается это через два атрибута параметров интеграции:

  • isNeedTopInset: необходимо добавить отступ сверху. Размер определяется css-константой env(safe-area-inset-top).
  • isNeedBottomInset: необходимо добавить отступ снизу. Размер определяется css-константой env(safe-area-inset-bottom).

По умолчанию оба атрибута в отключены, т.е. отступ не добавляется. Пример включения отступов:

var module = session.loadModule(moduleName, moduleParams, {
	isNeedTopInset: true,
	isNeedBottomInset: true
});

Использование вибрации

Для улучшения обратной связи с пользователем можно предоставить модулю возможность отправлять паттерн вибрации:

session.exportMethod('vibrate', (pattern) => {...})

Где строковый аргумент pattern представляет из себя строку с числами, разделенными запятой, где нечетные числа - длина вибрации в ms, четные - длина паузы.

Пример: "100,30,100,30,100,200,200,30,200,30,200,200,100,30,100,30,100" - Вибрировать 'SOS' на азбуке Морзе.