Initializing the SDK

The SDK needs to be initialized with some basic settings (such as the directory the SDK can use for data storage and logs), and with a TokenSigner that is provided by the host application. This must occur early in the lifecycle of the app.
import Common
// Choose a directory that the SDK can access and will own.
let sdkDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!.appendingPathComponent("sdk", isDirectory: true)
// The AppTokenSigner is a stub for the TokenSigner implementation developed within the host application.
try! initialize(Directories(root: sdkDirectory), tokenSignerFactory: { AppTokenSigner() })
WARNING: Failing to initialize the SDK before using its functionality will result in unexpected behaviour.

Beginning Trip Detection Manager

To upload trip data, the current mobile device must be activated for data collection through the Portal. This is to ensure trip data can be analyzed properly on the IMS backend. Depending on the mode of activation the host application chooses and the design of the app, device activation may only need to be performed once for a device.

Identity

The host application shares the identity of its currently authenticated user by sharing an Identity object with the SDK. An Identity is constructed with the host application's API Key and the host application's unique user identifier, provided during the enrolment process.

UploadRoute

The host application can choose upload route for uploading trip files which can be passed during the initialization of the SDK.
For more details about upload routes check Controlling how the files are uploaded

Feature

The features: [Feature] parameter of TripDetectionManager's initializer specifies which features are used for Trip Detection and Trip Validation. A combination of Trip Detectors and Trip Validators can be passed into the initializer to meet the needs of the App. Simply declare all Feature components that are needed.
A standard setup would include at least one Trip Detector and one Trip Validator. For example, a phone only trip detection configuration would include [Feature.Geofence] and [Feature.PhoneOnlyValidation].

Trip Detection

Feature.Geofence: To use geofences for trip detection, pass in [Feature.Geofence].This feature provides trip detection using Core Motion and Core Location functionalities.
Feature.Bluetooth: To use Bluetooth devices for trip detection, pass in [Feature.Bluetooth].This feature uses Core Bluetooth functionality to have trip detection using a bluetooth device (i.e. wedge).
NOTE: If there is no Trip Detection Feature parameter passed in the configuration, Trip Detection functionality will be limited.

Trip Validation

Starting with the SDK 1.15.0, the host app can provide the trip validation features as in the example above during the initialization of SDK.
Feature.PhoneOnlyValidation: To use phone-only trip validation feature, pass in [Feature.PhoneOnlyValidation]. This feature allows a trip to be validated using the onboard sensors of the phone.
Feature.DeviceValidation: To use Bluetooth devices for trip validation feature, pass [Feature.DeviceValidation]. This feature allows a trip to be validated by the presence of an associated Bluetooth device during the trip.
NOTE: If there is no Trip Validation Feature parameter passed in the configuration, trips will be validated as soon as they are detected.

Complete Example

import Common
import Portal
import TripDetection
import TripDetectionUmbrella
class Example {
// The identity of the user.
private let identity: Identity
private let tripDetectionManager: TripDetectionManager?
init() {
identity = Identity(apiKey: "HOST-APP-API-KEY",
externalReferenceID: "HOST-APP-USER-IDENTIFIER")
// Choose a directory that the SDK can access and will own.
let sdkRootDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
.first!.appendingPathComponent("sdk", isDirectory: true)
// The AppTokenSigner is a stub for the TokenSigner implementation developed within the host application.
let appTokenSigner = AppTokenSigner()
try! initialize(Directories(root: sdkRootDirectory),
logLevel: .debug,
tokenSignerFactory: {appTokenSigner})
// The telemetry events to be recorded
let telemetryEvents: Set<TelemetryEvent> = [.gps,
.speed,
.gyroscope(.oneHz),
.gravity(.oneHz),
.accelerometer(.oneHz),
.userAcceleration(.oneHz),
.magnetometer(.oneHz)])]
// Feature for phone trip detection
let features: [Feature] = [Feature.Geofence, Feature.PhoneOnlyValidation]
// Feature for device trip detetction
// let features = [Feature.Bluetooth, Feature.DeviceValidation]
// Feature for phone-only and device trip detection
// let features: [Feature] = [Feature.Geofence, Feature.PhoneOnlyValidation, Feature.Bluetooth, Feature.DeviceValidation]
// Initializes trip detection by way of the `TripDetectionManager`.
tripDetectionManager = TripDetectionManager(identity: identity,
uploadRoute: uploadRouteType
telemetryEvents: telemetryEvents,
features: features)
}
func activateTheDevice() {
let deviceService = DeviceService(identity: identity)
deviceService.activate(mode: .activate) { result in
guard let device = result.value else {
print("Something went wrong.")
return
}
// Additional activation for the device.
}
}
func enableTripDetection() {
// Enable Trip Detection
tripDetectionManager?.enable(tripStartHandler: { date in
// Do something with the trip start date ...
}, tripEndHandler: { date in
// Do something with the trip end date ...
})
}
func disableTripDetection() {
tripDetectionManager?.disable()
}
}

Configure Bluetooth Device Provider

  • Starting with SDK 1.19.0, host app has the capabilities to configure the device providers
  • Host app can use the new Devices and IMSBluetooth frameworks to configure the bluetooth usage for TripDetection. Both frameworks are required to be included in the project if the trip detection variant is using bluetooth and devices to detect trips.

Concrete example:

Below is the snappshot for understanding the configuration required to utilize the new modules
import Combine
import Devices
import IMSBluetooth
import Primitives
// Configure the provider
// Pass the regex for device's name, i.e. Starts with "IMS-"
let bluetoothDeviceProvider = BluetoothDeviceProvider(wedgeRegex: "IMS-")
IMSDeviceManager.configure(providers: [bluetoothDeviceProvider])
  • The Devices module provides APIs as listed below:
    • scanForDevices: To scan bluetooth devices
    • associateDevice: To associate an IMS device
    • disassociateDevice: To disassociate an IMS device
    • clearAllAssociatedDevices: To clear all associated devices
    • associatedDevices: To retrieve already associated devices
  • Usage of the APIs:
private var cancellables: Set<AnyCancellable> = []
// scanForDevices
let devices = [IMSDevice]()
IMSDeviceManager.scanForDevices(withTimeout: 20.0)
.sink { completion in
switch completion {
case .finished:
break
case . failure(let error):
log.e("Scan error: \(error)")
}
} receiveValue: { devices.append($0) }
.store(in: &cancellables)
// associateDevice
let bluetoothDevice = IMSDevice(deviceId: deviceId, deviceName: deviceName)
IMSDeviceManager.associateDevice(bluetoothDevice, toVehichleId: nil)
// disassociateDevice
IMSDeviceManager.associatedDevices.forEach { device in
IMSDeviceManager.disassociateDevice(device)
}
// clearAllAssociatedDevices
IMSDeviceManager.clearAllAssociatedDevices()
// associatedDevices
IMSDeviceManager.associatedDevices.compactMap { device in
// use the device
}

SDK initialization feedback

Starting with the SDK 1.10, it is possible to add a handler to be notified of SDK status changes. Setting a handler:
tripDetectionManager.setStatusHandler { status in
print("Trip detection status \(status.code)")
}
Removing the current handler:
tripDetectionManager.setStatusHandler(nil)
The list of statuses will be expanded in future releases.