For every Execution Taskďťż, a corresponding pre-coded module is expected in the app as part of SDK. This module executes the Task on the device running the Delivery Agent app. Thus, the Dispatcher SDK allows you to build this app with the minimum amount of effort.
The Mobile App SDK will orchestrate the execution of Tasks. Objective status updates will flow back as objective events to dispatch service through API calls made by the SDK and they will be stored in the Objective Events Store. This SDK can be used to render execution task screens on UI, maintain their states, and manage Motion Tracking Systemďťż.
Dispatch SDK is an expo-based SDK that is written in Typescript and some Modules in Java/Kotlin.
Currently supports SDK>=21 (Android).
Features
Sync Manager: Provides Sync Manager for syncing events & Docs in the background with retry functionality.
Execution Tasks: Provides a list of Execution Tasks which are as follows: Deliver, Capture Input, Deliver Cash, Complete-Success, Complete-Failure, Pickup, Doodle, Forms, Display, Verify Location, Verify OTP, Verify String, Scan QR/Barcode, Image Capture, Init Payment, Process Payment, and Complete Payment.
Execution Engine: Provides methods for Executing a given Workflow/Job in a dispatch.
Firebase Cloud Messaging: Provides a method for receiving Firebase Cloud Messaging.
Async Storage: Provides async storage for storing key-value pairs.
Higher-Order ETs: Provides a way to customize Execution Task UI.
Asynchronous Event Handling: Provides a method for handling Execution Tasks asynchronously.
import{ DispatchStateContainer }from'@os1-platform/dispatch-mobile';/**
* Call this function when dispatch data is fetched successfully
* @param dispatchID
* @param jobs
* @param logging
* @param maxTaskReattempt
*/await DispatchStateContainer.getInstance().initDispatchExecutor(
dispatchID,
dispatch.data.dispatch.jobs.data as Job[],false);
interfacesdkError{code: string;message: string;}// Error Handling from the calling Screen
React.useEffect(()=>{if(route.params?.sdkError){
console.log(JSON.stringify(route.params.sdkError));
Alert.alert('Error',JSON.stringify(route.params.sdkError));}},[route.params?.sdkError]);
navigation.navigate('DispatchExec',{success:true,objectives:[],// Pass objective ListsuccessRoute:'SuccessScreen',failureRoute:'FailureScreen',initRoute:'TaskDetail',// Calling Screen name (optional parameter). Used to throw errors back to calling screen});
ďťż
FCM
Setup (Android only)
Add the Firebase Android configuration file to your app:
Create a Firebase project (Check Firebase instructions for creating an app).
Click Download google-services.json to obtain your Firebase Android config file (google-services.json).
Move your config file into the module (app-level) directory of your app.
To enable Firebase products in your app, add the Google services plugin to your Gradle files.
In your module (app-level) Gradle file (usually app/build.gradle), apply the Google Services Gradle plugin:
JSON
apply plugin: 'com.android.application'
// Add the following line:
apply plugin: 'com.google.gms.google-services' // Google Services plugin
android {// ...}
ďťż
In your root-level (project-level) Gradle file (build.gradle), add rules to include the Google Services Gradle plugin. Check that you have Google's Maven repository, as well.
JS
buildscript {
repositories {// Check that you have the following line (if not, add it):google()// Google's Maven repository}
dependencies {// ...// Add the following line:
classpath 'com.google.gms:google-services:4.3.10'// Google Services plugin}}
allprojects {// ...
repositories {// Check that you have the following line (if not, add it):google()// Google's Maven repository// ...}}
ďťż
Get FCM Token
JS
import{
getFCMToken,
requestFirebasePermissions,}from'@os1-platform/dispatch-mobile';//Get FCM Tokenlet token =awaitgetFCMToken();//Request Notifications permissions (ios)// It will ask for user permissions for showing alert/notificationslet enabled =awaitrequestFirebasePermissions();
ďťż
Background FCM Messages
Register a callback for receiving FCM Messages in the background.
đ NOTEďťż
Call this function in the root component, i.e, in the `index.js file of the app.
useFcmMessage() custom hook in functional components to receive FCM Messages in Foreground.
JS
import{ useFCMMessage }from'@os1-platform/dispatch-mobile';const fcmMessage =useFCMMessage();if(fcmMessage !=null){// update UI here to show the message}
ďťż
OR
Extend FCM base class in case of class components
JS
import{FCM}from'@os1-platform/dispatch-mobile';classClassComponentextendsFCM{//implement these methodshandleFcmMessage(remoteMessage: object):void{}//implement these methodshandleNotification(remoteMessage: object):void{}}
ďťż
MTS
In the case of the dispatch mobile app, the Location Tracking module of the SDK provides a configurable way to capture and stream location data from the mobile device to the MTSďťżservice, without any user intervention. To learn more, see Dispatch Documentationďťż.
MTS Default Config
JSON
export class MTSDefaults {
locationFrequency: number = 10000; // in milli seconds (no. of seconds after which location updates will happen)
distanceAccuracyLimit: number = 250; // in metres
speedLimit: number = 28; // in m/s
mode: MTSMode = MTSMode.HYBRID;
environment: MTSEnv = MTSEnv.DEV;
batchSize: number = 25;
isMqttCleanSession: boolean = true;
mqttKeepAliveInterval: number = 15 * 60; //in seconds
maxLocationAge: number = 15000; // in milliseconds
maxTraceSession: number = 24 * 3600 * 100; //in milliseconds
isOdometerEnabled: boolean = true;
retriesBeforeFallback: number = 1;
httpFailureLimit: number = 5;
dataSendDelay: number = 30000; // in milli seconds
alarmTime: number = 60000; // in milli seconds
missingSeqCheckDuration: number = 5 * 60 * 1000; // in milli seconds
odometerPushFrequency: number = 5 * 60 * 1000; // in milli seconds
qosLevel: number = 1; // values can be 0 ,1}
ďťż
Check For Mandatory MTS Permissions
JSON
let granted = await MtsLib.requestPermissionsForMTS();
// if granted = true : all permissions granted// granted = false : one or more permissions denied
ďťż
Init MTS
JSON
import type { MTSInitRequest } from '@os1-platform/mts-mobile';
let mtsDefaults = new MtsLib.MTSDefaults();
mtsDefaults.speedLimit = 5000;
mtsDefaults.locationFrequency = 10000;
mtsDefaults.environment = MtsLib.MTSEnv.PRE_PROD;
mtsDefaults.isOdometerEnabled = false;
//Change MTS default values as per your use case// ...Use this for Initiating MTS
let mtsInitReq: MTSInitRequest = {
appName: 'app_name',
appVersion: '1',
mtsDeviceID: 'deviceId',// use FCM ID here
configData: mtsDefaults,
baseURL: 'https://{tenantId}.example.io/{mtsEndpoint}',
accessToken: 'token',
tenantID: 'TENANTID',};
await MtsLib.initMTS(mtsInitReq);
//See Error Codes for Possible error types
ďťż
Start MTS
JSON
let startReq: MTSStartRequest = {
accessToken: 'token',// update access token
resetSequence:false,
dispatchID: '12345',// pass dispatch ID here
expiryTime: Date.now() + 24 * 2600 * 1000,// expiry time after which MTS will stop automatically};
await MtsLib.startMTS(startReq);
PERMISSIONS_ERROR[2500] = 'Mandatory Android Permissions not provided';
MTS_INIT_ERROR[2501] = 'MTS INIT Not called! MTS Device ID is Empty';
PARAM_MISSING[2502] = 'Mandatory Paramater is missing in request';
ďťż
Sync Manager
Import Sync Manager
JSON
import { AppSyncManager, SdkSyncType } from '@os1-platform/dispatch-mobile';
// Start Events sync
await AppSyncManager.getInstance().startSyncing(
false,// pass true for force sync
SdkSyncType.EVENTS_SYNC
);
//Start Documents sync
await AppSyncManager.getInstance().startSyncing(
false,// pass true for force sync
SdkSyncType.DOCUMENT_SYNC
);
//Get All Events By Dispatch ID
await AppSyncManager.getInstance().getAllEvents('dsp_id');
//Get all documents By Dispatch ID
await AppSyncManager.getInstance().getAllDocuments('dsp_id');
ďťż
Start Sync Manager as a Foreground Service in Android
JSON
import { NativeSyncManager } from '@os1-platform/dispatch-mobile';
NativeSyncManager.startSyncManager(
interval,
notificationTitle,
notificationText
);
// interval will be in seconds
NativeSyncManager.startSyncManager(
2000,
'Dispatch Service',
'Syncing events...'
);
//To stop the foreground android service
NativeSyncManager.stopSyncManager();
ďťż
Asynchronous Event Handling
The Dispatch SDK support handling Execution Tasks asynchronously by emitting two events for each ET. This lets your apps to listen to these events and perform necessary actions.
For every ET, two events will be triggered in a fire-and-forget mode:
Task Start event: Triggered upon arrival of the ET, along with input data
Task End event: Triggered just before moving to the next ET, with the output data of objectives executed in that ET and the ID of the next ET to be executed.
To use this feature, you need to work with the eventListener method, which is used to listen and remove events. It contains the following methods:
.on: To listen to a specific event
.remove: To remove a specific event
JS
eventListener ={on(event, callback){//Add event listener and execute callback with event data }remove(event){//Add remove event listener fn }}
import{ SdkUtils }from'@os1-platform/dispatch-mobile';await SdkUtils.getRemoteConfig(3000);// 3000 is the number of seconds to cache the config
ďťż
Download API from Public URL
JS
/**
* Function to download apk file from a public URL
* @param apkURL - URL where apk is hosted
* @param version - expected version of apk (used for naming the file)
* @param callback - callback for getting progress of download
*/await SdkUtils.downloadAPK('https://apk_url.com','1',(progress)=>
console.log(progress.totalBytesWritten));
ďťż
Open and Install an APK file
JS
/**
* Opens & Install an APK file
* @param uri - source of apk file
*/await SdkUtils.openAPKFile(result.uri);