# Quick Start

{% hint style="info" %}
Check our public [sample application](https://github.com/dolphin-technologies/MOVE-sample-iOS) for an actual implementation of the snippets below and how they can be utilized.&#x20;
{% endhint %}

## Overall Code

A quick start snippet will look something like this in your app's [`willFinishLaunchWithOptions`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623032-application):

```swift
import MoveSDK

func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
 
    MoveSDK.shared.setAuthStateUpdateListener { ... }
    MoveSDK.shared.setSDKStateListener { ... }
    MoveSDK.shared.setTripStateListener { ... }
    MoveSDK.shared.setServiceFailureListener { ... }
    MoveSDK.shared.setServiceWarningListener { ... }

    MoveSDK.shared.initialize(launchOptions: launchOptions)
}
```

{% hint style="warning" %}
This snippet assumes that the required configurations and permissions are already setup to work. Check [permissions handling](https://docs.movesdk.com/move-platform/~/changes/1lLi1pFRKkteajbXv0hC/appendix/ios/permission-handling#required-permissions) section for more details.
{% endhint %}

### Setup

Users will be 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 be persisted and services will be automatically started when launching the app from the background.

```swift
import MoveSDK

...
let auth = MoveAuth(userToken: userToken, refreshToken: refreshToken, userID: userID, projectID: projectID)

let sdkConfig = MoveConfig(
                detectionService: [.driving([.drivingBehavior, .distractionFreeDriving]), .walking([.location]), .cycling, .places, 
                .publicTransport, .pointsOfInterest, .assistanceCall, .automaticImpactDetection)

MoveSDK.shared.setup(auth: auth, config: config)

...

MoveSDK.shared.startAutomaticDetection()
...
```

Let us break down the overall code block into the following:&#x20;

### SDK Authorization

The [MoveAuth](https://docs.movesdk.com/move-platform/~/changes/1lLi1pFRKkteajbXv0hC/sdk/models/moveauth) will look something like this:

```swift
let auth = MoveAuth(userToken: "", refreshToken: "", userID: "", projectID: "" )
```

An auth state listener must be implemented to fetch a new user token if necessary.

```swift
import MoveSDK

func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {

    ...

    MoveSDK.shared.setAuthStateUpdateListener { state in
        switch state {
        case .expired:
        /* you must fetch new auth object from your backend */
            MoveSDK.shared.update(auth: auth) { error in
        	/* will throw an error if sdk is not setup or userID changed */ 
            }
        }
    }

    MoveSDK.shared.initialize(launchOptions: launchOptions)

...
```

### Authentication Expiry

{% hint style="warning" %}
The host app is expected to monitor [MoveAuthState](https://docs.movesdk.com/move-platform/~/changes/1lLi1pFRKkteajbXv0hC/sdk/models/moveauthstate) updates via`authStateChangeListener`([iOS](https://docs.movesdk.com/move-platform/~/changes/1lLi1pFRKkteajbXv0hC/api-interface/ios/services#set-sdk-auth-state-listener)) API and handle those changes accordingly.

Check [Authentication updates and expiry](https://docs.movesdk.com/move-platform/~/changes/1lLi1pFRKkteajbXv0hC/models/moveauthstate#authentication-updates-and-expiry) for more details about authentication expiry and renewal.
{% endhint %}

### SDK Configuration

[MoveConfig](https://docs.movesdk.com/move-platform/~/changes/1lLi1pFRKkteajbXv0hC/sdk/models/moveauth) allows host apps to configure which of the licensed Move services should be enabled. It could be based on each user preference or set from a remote server.

{% hint style="danger" %}
**iOS System Permissions**

Based on the passed [MoveConfigs](https://docs.movesdk.com/move-platform/~/changes/1lLi1pFRKkteajbXv0hC/sdk/models/moveauth) on[`setup`](#setup), the SDK determines the required permissions to activate the requested services.\
\
The host app **must** verify that all the permissions required for the passed configs are granted.

Check [permission handling](https://docs.movesdk.com/move-platform/~/changes/1lLi1pFRKkteajbXv0hC/sdk/appendix/ios/permission-handling) for details about permissions required for each service.
{% endhint %}

The [MoveConfig](https://docs.movesdk.com/move-platform/~/changes/1lLi1pFRKkteajbXv0hC/sdk/models/moveauth) will look something like this:

```swift
let sdkConfig = MoveConfig(
                detectionService: [.driving([.drivingBehavior, .distractionFreeDriving]), .walking([.location]), .cycling, .places, 
                .publicTransport, .pointsOfInterest, .assistanceCall, .automaticImpactDetection)
```

### SDK State

The host app is expected to set its [`SDKStateListener`](https://docs.movesdk.com/move-platform/~/changes/1lLi1pFRKkteajbXv0hC/api-interface/ios/services#set-sdk-state-listener) **before** initializing the SDK to intercept the [MoveSDKState](https://docs.movesdk.com/move-platform/~/changes/1lLi1pFRKkteajbXv0hC/sdk/models/movestate) changes caused by calling the [`initialize`](https://docs.movesdk.com/move-platform/~/changes/1lLi1pFRKkteajbXv0hC/sdk/api-interface/ios/intialization) API.

The provided block could then start the SDK when [MoveSDKState](https://docs.movesdk.com/move-platform/~/changes/1lLi1pFRKkteajbXv0hC/sdk/models/movestate) is `ready` or handle errors if occurred. The provided block could look something like this:&#x20;

```swift
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
    }
}
```

### SDK Initialization&#x20;

{% hint style="warning" %}
The[`initialization`](https://docs.movesdk.com/move-platform/~/changes/1lLi1pFRKkteajbXv0hC/sdk/api-interface/ios/intialization)API must be executed before[`didFinishLaunchingWithOptions`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622921-application)returns. We recommend calling it in[`willFinishLaunchingWithOptions`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623032-application).\
\
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](https://docs.movesdk.com/move-platform/~/changes/1lLi1pFRKkteajbXv0hC/api-interface/ios/intialization#timing) for more details about the importance of adequately initializing the SDK.
{% endhint %}

```swift
MoveSDK.shared.initialize(launchOptions: launchOptions)
```

### 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.

```swift
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
        }
    }
}
```
