Перейти к содержанию

Интеграция с мобильным приложением

Обзор

Интеграция с мобильным приложением Inspector Cloud позволяет вызывать Inspector Cloud из стороннего приложения для выполнения задач фотографирования выкладки товаров и получать обратно управление после того как пользователь закончил работу. Детальные результаты распознавания можно получить у бекенда Inspector Cloud через Inspector Cloud Data API.

Для реализации интеграции с мобильным приложением Inspector Cloud предоставляются SDK для Android и iOS.

Плюсы:

  • самый простой в реализации вариант интеграции, минимальные доработки вызывающего приложения;
  • пользователям доступна полная функциональность приложения Inspector Cloud;
  • однократная авторизация пользователей в вызывающем приложении, повторная авторизация в приложении Inspector Cloud не требуется;
  • всегда актуальная версия Inspector Cloud, обновления устанавлиаются автоматически из магазина приложений операционной системы;
  • возможность совмещать в одном проекте как пользователей, работающих через интеграцию, так и пользователей только приложения Inspector Cloud.

Минусы:

  • необходимость установки двух приложений на устройство и обучения пользователей работе в приложении Inspector Cloud;
  • переключение между приложениями в процессе работы.

Схема взаимодействия

схема

Сущности

  • Inspector Cloud mobile app - мобильное приложение Inspector Cloud Camera 2, установленное на устройстве под управлением Android или iOS
  • 3rd party mobile app - стороннее мобильное приложение, установленное на том же устройстве
  • Inspector Cloud backend - бекенд сервисы приложения Inspector Cloud
  • 3rd party backend - бекенд сервисы стороннего мобильного приложения

Взаимодействия

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

  2. upload image - после съемки каждой фотографии приложение Inspector Cloud загружает ее на бекенд для распознавания;

  3. update results - после распознавания фотографии бекенд Inspector Cloud обновляет результаты визита и возвращает в мобильное приложение Inspector Cloud для отображения пользователю;

  4. return - после того, как пользователь выполнил все необходимые задачи в приложении Inspector Cloud и нажал кнопку "Вернуться", управление возвращается в стороннее приложение. Шаги 1-4 могут выполняться неоднократно в процессе одного визита.

  5. poll visit results - бекенд стороннего приложения может опрашивать бекенд Inspector Cloud для получения подробных результатов визита пользуясь Inspector Cloud Data API.

  6. return visit results - в ответ на запрос poll visit results бекенд Inspector Cloud возвращает результаты визита. Шаги 5-6 могут выполняться неоднократно для одного визита, а так же параллельно для многих визитов.

  7. update visit steps - при необходимости бекенд стороннего приложения может скорректировать шаги визита по результам от Inspector Cloud и передать эту информацию в свое мобильное приложение.

Использование SDK iOS

Установка

Для установки, файл ICDeepLink.framework в проект.

Настройка

Для начала работы необходимо настроить несколько параметров:

scheme - схема нужна для того чтобы можно было вернуться в паше приложение. Для этого добавьте новую схему в разделе URL Types и после выполните следующий код:

[ICDeepLink shared].scheme = @"string";

token - токен необходим для доступа в приложение IC Camera для того чтобы начать визит.

[ICDeepLink shared].token = @"string";

agentId - id пользователя необходим для идентификации в системе.

[ICDeepLink shared].agentId = @"string";

Синхронизация мастер-данных

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

[[ICDeepLink shared] startSyncListCustomerId:@[@"id1", @"id2", @"id3"]];

После завершения синхронизации, происходит передача управления из приложения Inspector Cloud обратно в вызывающее приложение. Вызывающее приложение получает статус синхронизации в методе делегата и код ошибки, если она прошла не успешно:

- (void)syncStatus:(BOOL)status withErrorCode:(NSNumber * _Nullable)errorCode;

status - статус синхронизации. если status YES, тогда синхронизация прошла успешно, а если NO - возникла проблема синхронизации. В этом случае нужно сделать повторную попытку синхронизации errorCode - код ошибки. если синхронизация прошла не успешно, будет передан код ошибки

Коды ошибок

  • 1201 - нет интернет соединения
  • 1202 - синхронизация была отменена пользователем
  • 1203 - превышен лимит времени
  • 1204 - проблемы при синхронизации в IC

Переход в приложение Inspector Cloud

Для начала или просмотра визита, необходимо вызвать функцию

- (void)openVisitId:(NSString *_Nonnull)visitId
     withCustomerId:(NSString *_Nonnull)customerId
         withFilter:(NSString *_Nullable)filter
       withReadonly:(BOOL)readonly;
  • visitId - id визита
  • customerId - id точки в которой вы хотите сделать визит
  • filter - фильтр задач (необязательно). Регулярное выражение (описание) для фильтрации задач по названию. Если задан фильтр, то визит будет отображать только задачи удовлетворяющие заданному фильтру.
  • readonly - задает режим открытия визита только для чтения. В таком режиме задачи доступны только для просмотра

Возврат из приложения Inspector Cloud

После того, как пользователь нажимает кнопку "Вернуться" происходит передача управления из приложения Inspector Cloud обратно в вызывающее приложение. Для обработки этого события, определите следующую функцию:

- (BOOL)application:(UIApplication *)app
            openURL:(NSURL *)url
            options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options {
    return [[ICDeepLink shared] proceedDeeplink:url];
}

Чтобы получить информацию о визите от приложения Inspector Cloud необходимо подписаться на делегат ICDeepLinkDelegate

[ICDeepLink shared].delegate = self;

и тогда метод

- (void)reciveVisitId:(NSString *_Nonnull)visitId 
           customerId:(NSString *_Nonnull)customerId 
             userInfo:(NSDictionary * _Nonnull)userInfo;

будет вызван при передаче управления в вызывающее приложение.

В словаре userInfo приходят дополнительные данные, в текущей версии доступны следующие ключи:

  • total_images - полное количество фотографий в визите.

В будущих версиях SDK набор ключей в userInfo может быть расширен.

Использование SDK Android

Для вызова приложения IC Camera необходимо создать Intent и вызвать с помощью startActivityForResult DeepLinkActivity. Есть несколько вариантов создания Intent для запуска IC Camera: - Если надо запустить любое приложение, установленное на устройстве (IC Camera 2 либо IC Camera 3), а при наличии обоих получить системный диалог выбора между ними:

Intent launchIntent = new Intent();
launchIntent.setAction(DeepLinkConst.IC_CAMERA_LAUNCH_ACTION);

В дальшейших примерах используется именно этот способ.

  • Если надо запустить строго версию приложения IC Camera 2:
Intent launchIntent = new Intent();
launchIntent.setComponent(new ComponentName(DeepLinkConst.IC_CAMERA_2_PACKAGE, DeepLinkConst.IC_CAMERA_2_ACTIVITY));
  • Если надо запустить строго версию приложения IC Camera 3:
Intent launchIntent = new Intent();
launchIntent.setComponent(new ComponentName(DeepLinkConst.IC_CAMERA_3_PACKAGE, DeepLinkConst.IC_CAMERA_3_ACTIVITY));

Синхронизация мастер-данных

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

Intent launchIntent = new Intent(DeepLinkConst.IC_CAMERA_LAUNCH_ACTION);

launchIntent.putExtra(DeepLinkConst.Parameters.TOKEN, getDemoToken());
launchIntent.putExtra(DeepLinkConst.Parameters.AGENT_ID, getDemoAgent());
launchIntent.putExtra(DeepLinkConst.Parameters.IC_COMMAND, DeepLinkConst.Commands.IC_SYNC); 

String[] listCustomerId = {"id1", "id2", "id3", "id4", "id5"}; // пример списка магазинов
launchIntent.putExtra(DeepLinkConst.Parameters.LIST_CUSTOMER_ID, listCustomerId);

startActivityForResult(launchIntent, ICDeepLink.DEFAULT_REQUEST_CODE);

После завершения синхронизации, управление автоматически возвращается вызывающему приложению.

Работа с визитами

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

Intent launchIntent = new Intent(DeepLinkConst.IC_CAMERA_LAUNCH_ACTION);

launchIntent.putExtra(DeepLinkConst.Parameters.DEBUG, true);
launchIntent.putExtra(DeepLinkConst.Parameters.TOKEN, getDemoToken());
launchIntent.putExtra(DeepLinkConst.Parameters.VISIT_ID, getDemoVisit());
launchIntent.putExtra(DeepLinkConst.Parameters.AGENT_ID, getDemoAgent());
launchIntent.putExtra(DeepLinkConst.Parameters.CUSTOMER_ID, getDemoCustomerID());
launchIntent.putExtra(DeepLinkConst.Parameters.TASK_FILTER, "regex");

startActivityForResult(launchIntent, ICDeepLink.DEFAULT_REQUEST_CODE);

Описание вызывающих параметров:

  • DeepLinkConst.Parameters.DEBUG (boolean) - Включение отладочного режима, который отображает лог с выводом основных ошибок и вызывающих параметров (необязательно)
  • DeepLinkConst.Parameters.TOKEN (String) - идентификатор вызывающего приложения (обязательно)
  • DeepLinkConst.Parameters.VISIT_ID (String) - идентификатор визита (обязательно). Если визит с таким VISIT_ID найден, то он будет открыт, если не найден, то будет создан новый визит. Если получено невалидное значение (параметр пустой либо "0"), будет возвращена ошибка.
  • DeepLinkConst.Parameters.AGENT_ID (String) - идентификатор агента (обязательно). Если агент с таким AGENT_ID не найден, то будет создан новый агент.
  • DeepLinkConst.Parameters.CUSTOMER_ID (String) - идентификатор магазина (обязательно). По CUSTOMER_ID будет осуществлен поиск магазина (по полю store -> customer_id). Если магазин не найден, вернется ошибка, визит начать нельзя. Если магазин найден то в визит будут добавлены все задачи данного магазина.
  • DeepLinkConst.Parameters.TASK_FILTER (String) - фильтр задач (необязательно). Регулярное выражение (описание) для фильтрации задач по названию. Если задан фильтр, то визит будет отображать только задачи удовлетворяющие заданному фильтру.

  • DeepLinkConst.Parameters.IC_COMMAND (String) - Управляющая команда. Список поддерживаемых команд:

    • sync - выполнить синхронизацию.
  • DeepLinkConst.Parameters.LIST_CUSTOMER_ID (String[]) - массив строк с CUSTOMER_ID кодами магазинов для синхронизации данных по этим магазинам

  • DeepLinkConst.Parameters.STRING_CUSTOMER_ID (String) - альтернативный вариант списка с CUSTOMER_ID кодами магазинов для синхронизации данных по этим магазинам. В данном формате передается строка с CUSTOMER_ID кодами разделенными символом "," (запятая), без пробелов. Если заданы оба способа, то будут использованы значения из STRING_CUSTOMER_ID
  • DeepLinkConst.Parameters.READONLY (Boolean) - задает режим открытия визита только для чтения. В таком режиме задачи доступны только для просмотра (необязательно)

Получение результатов

Результаты возвращаются в функцию onActivityResult. Пример приема результатов:

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (data == null) {
        return;
    }
Log.d(TAG, "Result code: " + data.getIntExtra(DeepLinkConst.Parameters.RESULT_CODE, 0));
Log.d(TAG, "Result info: " + data.getStringExtra(DeepLinkConst.Parameters.RESULT_INFO));
Log.d(TAG, "Visit: " + data.getStringExtra(DeepLinkConst.Parameters.VISIT_ID));
Log.d(TAG, "Agent: " + data.getStringExtra(DeepLinkConst.Parameters.AGENT_ID));
Log.d(TAG, "Customer: " + data.getStringExtra(DeepLinkConst.Parameters.CUSTOMER_ID));
}

Описание параметров в результатах:

  • DeepLinkConst.Parameters.RESULT_CODE (int) - код результата

    • VISIT_VALID (int: 1) - успешный визит (новый или открытый), завершен с помощью кнопки закрытия визита
    • VISIT_ERR (int: 2) - Ошибка визита, подробная информация информация в RESULT_INFO
    • SYNC_OK (int: 3) - Синхронизация успешно выполнена
    • SYNC_ERR (int: 4) - Синхронизация не выполнена. Подробнее в RESULT_INFO.
  • DeepLinkConst.Parameters.RESULT_INFO (String) - описание ошибки или дополнительная информация (при наличии)

  • DeepLinkConst.Parameters.VISIT_ID (String) - идентификатор визита, как во входном параметре
  • DeepLinkConst.Parameters.AGENT_ID (String) - идентификатор агента, как во входном параметре
  • DeepLinkConst.Parameters.CUSTOMER_ID (String) - идентификатор магазина, как во входном параметре
  • DeepLinkConst.Parameters.VERSION_API (int) - версия встроенного АПИ в приложение
  • DeepLinkConst.Parameters.VERSION_APP (int) - код версии приложения

Константы, используемые в API

public class DeepLinkConst {
    public static final String IC_CAMERA_LAUNCH_ACTION = "inspector.cloud.camera.DeepLinkActivity";
    public static final String IC_CAMERA_2_PACKAGE = "inspector.cloud.camera";
    public static final String IC_CAMERA_2_ACTIVITY = "inspector.cloud.camera.DeepLinkActivity";
    public static final String IC_CAMERA_3_PACKAGE = "com.iccamera3.app";
    public static final String IC_CAMERA_3_ACTIVITY = "com.iccamera3.app.MainActivity";

    public static final class Parameters {
       public static final String TOKEN = "token";
        public static final String IC_COMMAND = "ic_command";
        public static final String LIST_CUSTOMER_ID = "list_customer_id";
        public static final String STRING_CUSTOMER_ID = "string_customer_id";
        public static final String AGENT_ID = "agent_id";
        public static final String VISIT_ID = "visit_id";
        public static final String CUSTOMER_ID = "customer_id";
        public static final String TASK_FILTER = "task_filter";
        public static final String READONLY = "readonly";
        public static final String DEBUG = "debug";
        public static final String VERSION_API = "version_api";
        public static final String VERSION_APP = "version_app";
        public static final String IS_NEW_VISIT = "is_new_visit";
        public static final String RESULT_CODE = "res_code";
        public static final String RESULT_INFO = "res_info";
    }

    public static final class ResultCode {
      public static final int VISIT_VALID = 1;
      public static final int VISIT_ERR = 2;
      public static final int SYNC_OK = 3;
      public static final int SYNC_ERR = 4;
    }

        public static final class Commands {
        public static final String IC_SYNC = "sync";
    }
}

Особые случаи

  • Если во время работы приложение IC Camera было закрыто системой или пользователем с помощью системной кнопки “Запущенные задачи / Удалить IC Camera”, то в результатах вернется VISIT_ERR.
  • Если во время работы приложения IC Camera произойдет сбой, то в зависимости от типа сбоя возможны два варианта:
    • в результатах вернется - VISIT_ERR
    • в результатах вернется Intent data со значением null.