importDolphinMoveSDK#if canImport(DolphinMoveSDKHealth)importDolphinMoveSDKHealth#endiffuncapplication(_application: UIApplication, willFinishLaunchingWithOptionslaunchOptions: [UIApplication.LaunchOptionsKey:Any]?=nil)->Bool{#if canImport(DolphinMoveSDKHealth) sdk.enable(healthKit: MoveSDKHealth.shared)#endif MoveSDK.shared.setSDKStateListener{ sdkState inswitch state {case .uninitialized:print("/* SDK uninitialized*/")breakcase .ready:print("/* SDK initialised and ready to start the service*/")breakcase .running:print("/* SDK Started Detection*/")break}} MoveSDK.shared.setAuthStateUpdateListener{ authState in...} MoveSDK.shared.setTripStateListener{ tripState in...} MoveSDK.shared.setServiceFailureListener{ failures in...} MoveSDK.shared.setServiceWarningListener{ warnings in...} MoveSDK.shared.initialize(launchOptions: launchOptions)}
This snippet assumes that the required configurations and permissions are already setup to work. Check the permissions handling section for more details.
SDK Authentication
Users will need to be authenticated. This authentication will persist until shutdown is called. It will persist over the termination of the app. The configuration to enable functionality is passed here. startAutomaticDetection will start the services. This too will persist and services will automatically start when launching the app from the background.
The authentication object is constructed with tokens that need to be acquired from the backend (either from the SDK backend directly, or via your product backend). See MOVE Backend.
Authentication Invalidation
The host app is expected to monitor MoveAuthState updates viaauthStateChangeListener(iOS) API and handle those changes accordingly.
An auth state listener must be implemented to handle user invalidation, which can happen due to a user being blocked or having multiple conflicting installations with the same user.
SDK State
The host app is expected to set its SDKStateListenerbefore initializing the SDK to intercept the MoveSDKState changes.
The provided block could then start the SDK when MoveSDKState is ready or handle errors if occurred. The provided block could look something like this:
SDK Initialization
TheinitializationAPI must be executed beforedidFinishLaunchingWithOptionsreturns. We recommend calling it inwillFinishLaunchingWithOptions.
Exceptions might apply, where the SDK is not initialized on app launch. First initialization is a good example, where the app would only initialize the SDK after onboarding the user and requesting permissions.
Check Initialization Timing for more details about the importance of adequately initializing the SDK.
Warnings and Errors
When services are not running properly because they are missing permissions or are not authorized on the backend, warnings or errors will be reported in the corresponding listeners.
import DolphinMoveSDK
// Response from the API Request.
// {
// "authCode": "string"
// }
func authenticateUser(authCode: String) {
let config = MoveConfig(
detectionService: [
.driving([.drivingBehavior, .distractionFreeDriving, .deviceDiscovery]),
.walking([.location]), .cycling, .places,
.publicTransport,
.pointsOfInterest,
.assistanceCall,
.automaticImpactDetection
])
MoveSDK.shared.setup(authCode: authCode, config: config) { status in
switch status {
case .success:
MoveSDK.shared.startAutomaticDetection()
case let .invalidCode(code):
print("Invalid auth code: \(code). Auth codes may only be used once")
case let .networkError(error):
print("There was an error contacting the server. Please try again later. \(error)"
}
}
}
import DolphinMoveSDK
// Response from the API Request.
// {
// "authCode": "string"
// }
func authenticateUser(authCode: String) async {
let config = MoveConfig(
detectionService: [
.driving([.drivingBehavior, .distractionFreeDriving, .deviceDiscovery]),
.walking([.location]), .cycling, .places,
.publicTransport,
.pointsOfInterest,
.assistanceCall,
.automaticImpactDetection
])
let status = await MoveSDK.shared.setup(authCode: authCode, config: config)
switch status {
case .success:
await MoveSDK.shared.startAutomaticDetection()
...
case let .invalidCode(code):
print("Invalid auth code: \(code). Auth codes may only be used once")
case let .networkError(error):
print("There was an error contacting the server. Please try again later. \(error)"
}
}
import DolphinMoveSDK
func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
...
MoveSDK.shared.setAuthStateUpdateListener { state in
switch state {
case .invalid:
MoveSDK.shared.shutdown()
}
}
MoveSDK.shared.initialize(launchOptions: launchOptions)
...
MoveSDK.shared.setSDKStateListener { state in
switch state {
case .uninitialized:
/* SDK uninitialized*/
break
case .ready:
/* SDK initialised and ready to start the service*/
break
case .running:
/* SDK Started Detection*/
break
}
}
MoveSDK.shared.setServiceFailureListener { failures in
for failure in failures {
/* a list of MoveServiceFailure objects */
switch failure.reason {
case .unauthorized:
/* a service is not configured on the backend */
break
case let .missingPermission(permissions):
/* a required permission is missing */
break
}
}
}
MoveSDK.shared.setServiceWarningListener { warnings in
for warning in warnings {
/* a list of MoveServiceWarning objects */
switch warning.reason {
case let .missingPermission(permissions):
/* an optional permission is not provided, data collection will be reduced */
break
}
}
}
import UIKit
import CoreMotion
import CoreLocation
import DolphinMoveSDK
@main
class AppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate {
var locationManager = CLLocationManager()
let activityManager = CMMotionActivityManager()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// ACQUIRE PERMISSIONS
setupPermissions()
// INITIALIZE MOVE SDK
initializeSDK()
return true
}
/// INITIALIZE MOVE SDK
func initializeSDK(launchOptions: [UIApplication.LaunchOptionsKey: Any]?) {
setupSDKListeners()
MoveSDK.shared.initialize(launchOptions: launchOptions)
if MoveSDK.shared.getSDKState() == .uninitialised {
self.setupUser()
}
}
/// SETUP LISTENERS
func setupSDKListeners() {
MoveSDK.shared.setSDKStateListener { state in
switch state {
case .uninitialized:
print("SDK uninitialized")
break
case .ready:
print("SDK initialised and ready to start the service")
break
case .running:
print("SDK Started Detection")
break
}
}
MoveSDK.shared.setServiceFailureListener { failures in
for failure in failures {
/* a list of MoveServiceFailure objects */
switch failure.reason {
case .unauthorized:
/* a service is not configured on the backend */
print("unauthorized")
case let .missingPermission(permission):
/* a required permission is missing */
print(permission)
break
}
}
}
MoveSDK.shared.setServiceWarningListener { warnings in
for warning in warnings {
/* a list of MoveServiceWarning objects */
switch warning.reason {
case let .missingPermission(permissions):
/* an optional permission is not provided, data collection will be reduced */
print(permissions)
break
}
}
}
}
/// ACQUIRE PERMISSIONS
func setupPermissions() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
switch CMMotionActivityManager.authorizationStatus() {
case .restricted, .denied:
print("UNAUTHORIZED")
case .authorized:
print("AUTHORIZED")
case .notDetermined:
let activityManager = CMMotionActivityManager()
activityManager.queryActivityStarting(from: Date(), to: Date(), to: .main) { (activity, error) in
}
}
}
/// SETUP USER
func setupUser() {
// API REQUEST - Post Request for Auth Code:
// Example: https://stackoverflow.com/a/26365148
let authCode = ...
// SDK CONFIGURATION WITH SERVICES
let sdkConfig = MoveConfig(
detectionService: [
.driving([.drivingBehavior, .distractionFreeDriving]),
.walking([]),
.cycling,
.places,
.publicTransport,
.pointsOfInterest,
.assistanceCall,
.automaticImpactDetection
])
// SETUP THE SDK WITH AUTH AND SDK CONFIG OBJECTS
MoveSDK.shared.setup(authCode: authCode, config: sdkConfig) { status in
}
// START THE SDK SERVICES
MoveSDK.shared.startAutomaticDetection()
}
}