# Permissions Handling

## Required Permissions

{% hint style="danger" %}
Due to Apple's static code analysis, additional strings must be configured in the *Info.plist* to pass validation when uploading to the *AppStore* and *Testflight* even for features that are not used.

Required Strings:

* NSBluetoothAlwaysUsageDescription
* NSHealthShareUsageDescription
* NSHealthUpdateUsageDescription
* NSLocationAlwaysAndWhenInUseUsageDescription
* NSLocationAlwaysUsageDescription
* NSLocationWhenInUseUsageDescription
* NSMotionUsageDescription
  {% endhint %}

On SDK initialization, the host app passes a [MoveConfig](https://docs.movesdk.com/move-platform/sdk/models/moveconfig) object to configure which of the SDK services should be activated. Some of those services require system permissions to be granted, or other features to be available.&#x20;

{% hint style="info" %}
&#x20;From a usability perspective, Apple provides some guidelines about [Requesting Permissions](https://developer.apple.com/design/human-interface-guidelines/ios/app-architecture/requesting-permission/) as part of their Human Interface Guidelines.
{% endhint %}

\
The table below shows each of the [MoveConfig](https://docs.movesdk.com/move-platform/sdk/models/moveconfig) options and the corresponding required and optional permissions or sensors.

| **Service**        |                          | **Required permissions**                                                                                                 | **Optional permissions\[\*]**                                 |
| ------------------ | ------------------------ | ------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------- |
| Driving            | Driving                  | Location Permission Precise Location                                                                                     | Motion Permission Background Location Permission              |
|                    | Distraction-Free-Driving | Gyroscope and Accelerometer availability                                                                                 |                                                               |
|                    | Driving Behavior events  | Gyroscope and Accelerometer availability                                                                                 |                                                               |
|                    | Device Detection         |                                                                                                                          | Bluetooth Permission                                          |
| Cycling            | Bicycle                  | <p>Location Permission</p><p>Motion Permission Precise Location</p>                                                      | Background Location Permission                                |
| Walking            | Walking                  | Motion Permission                                                                                                        | Background Location Permission                                |
|                    | Location                 | LocationPermission Precise Location                                                                                      | Background Location Permission                                |
| Places             | Places                   | LocationPermission Precise Location                                                                                      |                                                               |
| Points of Interest | Points of Interest       | Location Permission Precise Location                                                                                     | Background Location Permission                                |
| Public Transport   | Public Transport stops   | Location Permission Precise Location                                                                                     | Background Location Permission                                |
| Impact Detection   | Impact Detection         | <p>Location Permission Precise Location</p><p>Gyroscope and Accelerometer availability</p>                               | <p>Motion Permission</p><p>Background Location Permission</p> |
| Assistance Call    | Assistance Call          | <p><del>Location Permission Precise Location</del><br><strong>(required permission deprecated with v2.4.0+)</strong></p> | <p>Location Permission Precise Location<br></p>               |
| Health             | Health Steps             | HealthKit, steps read Permission                                                                                         |                                                               |

{% hint style="info" %}
\[\*] Optional permissions can be set to required on `setup` by passing a [MoveOptions](https://docs.movesdk.com/move-platform/models/moveoptions#ios) object with the flags `motionPermissionMandatory` and `backgroundLocationPermissionMandatory` to `true.`
{% endhint %}

## **Location Permission**

### **Authorization**

{% hint style="info" %}
This section considers the iOS 13 system location permissions changes.&#x20;
{% endhint %}

Starting iOS 13, system location is split into 2 layers: [`CLAuthorizationStatus`](https://developer.apple.com/documentation/corelocation/clauthorizationstatus) and [`CLAccuracyAuthorization`](https://developer.apple.com/documentation/corelocation/claccuracyauthorization)

#### [`CLAuthorizationStatus`](https://developer.apple.com/documentation/corelocation/clauthorizationstatus):

can be granted with one of the multiple access levels. Focusing only on the MOVE SDK relevant ones:

* [`CLAuthorizationStatus.authorizedAlways`](https://developer.apple.com/documentation/corelocation/clauthorizationstatus/authorizedalways): The user authorized the app to start and access location services at any time. Can be requested by calling [requestWhenInUseAuthorization()](https://developer.apple.com/documentation/corelocation/cllocationmanager/1620562-requestwheninuseauthorization).
* [`CLAuthorizationStatus.authorizedWhenInUse`](https://developer.apple.com/documentation/corelocation/clauthorizationstatus/authorizedwheninuse): The user authorized the app to start location services only while the app is in use. Can be requested by calling [requestAlwaysAuthorization()](https://developer.apple.com/documentation/corelocation/cllocationmanager/1620551-requestalwaysauthorization).

Starting with iOS 13, when an app requests[`.authorizedAlways`](https://developer.apple.com/documentation/corelocation/clauthorizationstatus/authorizedalways)the system prevents apps from directly receiving the[`.authorizedAlways`](https://developer.apple.com/documentation/corelocation/clauthorizationstatus/authorizedalways)access level. Instead, the operating system breaks the access into 2 steps.

* First, the operating system shows the user the permission prompt for [`.authorizedWhenInUse`](https://developer.apple.com/documentation/corelocation/clauthorizationstatus/authorizedwheninuse)
* Later on, the operating system shows the [`.authorizedAlways`](https://developer.apple.com/documentation/corelocation/clauthorizationstatus/authorizedalways) permission prompt when the app (in our case the MOVE SDK embedded in your app) fetches the location in the background for the first time.

Check this WWDC19 [session](https://developer.apple.com/videos/play/wwdc2019/705/) and [apple documentation](https://developer.apple.com/documentation/corelocation/cllocationmanager/1620551-requestalwaysauthorization) for further information about the iOS 13 authorization status changes.

{% hint style="danger" %}

#### Automatic Detection

The MOVE SDK can automatically wake up the app and activate its services (like trip detection, etc..) fully in the background and without any user interaction. Even if the app was killed by the user.

None of the SDK automatic detection services will work except if background location permission[`authorizationAlways`](https://developer.apple.com/documentation/corelocation/clauthorizationstatus/authorizedalways)is granted. Otherwise, the services will only work when the host app is in the foreground.
{% endhint %}

#### [`CLAccuracyAuthorization`](https://developer.apple.com/documentation/corelocation/claccuracyauthorization):

Starting iOS 13, Apple introduced 2 levels of accuracy access:

* [`.fullAccuracy`](https://developer.apple.com/documentation/corelocation/claccuracyauthorization/fullaccuracy): The user authorized the app to access location data with full accuracy.
* [`.reducedAccuracy`](https://developer.apple.com/documentation/corelocation/claccuracyauthorization/reducedaccuracy): The user authorized the app to access location data with reduced accuracy.

{% hint style="warning" %}
The MOVE SDK **requires** full accuracy access to precisely detect trips and deliver high-quality service.
{% endhint %}

### **Plist**

Apple requires apps requesting any system permission to provide reasoning for granting the permission. This reasoning is known as "purpose string" and is defined in the app's  `Info.plist` file. Those purpose strings are displayed as an explanation of why the app needs those access types, in the alert shown by the system to ask the user for permission.

In the case of location permission, each access level requires including one or more corresponding keys with purpose strings.

| **Key**                                                                                                                                                                            | Required if                                                                  |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| [`NSLocationWhenInUseUsageDescription`](https://developer.apple.com/documentation/bundleresources/information_property_list/nslocationwheninuseusagedescription)                   | Your app requests "*When In Use*" authorization or "*Always*" authorization. |
| [`NSLocationAlwaysAndWhenInUseUsageDescription`](https://developer.apple.com/documentation/bundleresources/information_property_list/nslocationalwaysandwheninuseusagedescription) | Your app requests "*Always"* authorization.                                  |
| [`NSLocationAlwaysUsageDescription`](https://developer.apple.com/documentation/bundleresources/information_property_list/nslocationalwaysusagedescription)                         | Your app supports iOS 10 and earlier and requests "*Always"* authorization.  |

### **Background Mode**

Moreover, for background location access, Location update Background Modes must be enabled:

1. Go to the **Capabilities** tab of your target settings
2. Turn on **Background Modes** and enable **Location updates**

![Location updates background mode capability](https://394612935-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MXD5xlIFUYU8eK_kkLo%2F-Ma7-Qp0tvRtlszHh2aC%2F-MaWrFoEnyiReo8XoJL3%2Fimage.png?alt=media\&token=171c219f-f0e1-4d9a-9fe8-a0ccb47078a6)

{% hint style="info" %}
For more details about how to request location permissions, check out this Apple [document](https://developer.apple.com/documentation/corelocation/requesting_authorization_for_location_services).
{% endhint %}

### Sample Code

Requesting[`.authorizedAlways`](https://developer.apple.com/documentation/corelocation/clauthorizationstatus/authorizedalways)location authorization looks something like this:

```swift
import CoreLocation
 
class Permission: NSObject {
    let locationManager = CLLocationManager()
 
    func requestLocationPermission() {
        locationManager.delegate = self
        locationManager.requestAlwaysAuthorization()
    }  
}
 
extension Permission: CLLocationManagerDelegate {
    public func locationManager(_: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        // status
    }
}
```

## **Motion Permission**

### **.plist**

Same as with Location permission, Motion permission requires including the [NSMotionUsageDescription](https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW21) with its corresponding purpose string in the app's `Info.plist` file.

```
// Example .plist for permissions.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>NSBluetoothPeripheralUsageDescription</key>
	<string></string>
	<key>NSBluetoothAlwaysUsageDescription</key>
	<string></string>
	<key>CMMotionActivity</key>
	<string>We need your motion..</string>
	<key>CLAccuracyAuthorization</key>
	<string>We need your location...</string>
	<key>NSMotionUsageDescription</key>
	<string>We need your motion...</string>
	<key>NSLocationAlwaysUsageDescription</key>
	<string>We need your location..</string>
	<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
	<string>We need your location..</string>
	<key>NSLocationWhenInUseUsageDescription</key>
	<string>We need your location..</string>
	
...
```

### **Permission**

There is no direct way to request Motion Activities access permission like with Locations. Instead, the permission prompts the first time the Motions API is called.

Requesting the motion permission will look something like this:

```swift
import CoreMotion
 
func requestCoreMotionPermission() {
    let manager = CMMotionActivityManager()
    let now = Date()
    
    switch CMMotionActivityManager.authorizationStatus() {
    case .restricted, .denied:
	// "NotAuthorized
    case .authorized:
	// "Authorized"
    case .notDetermined:
        manager.queryActivityStarting(from: now, to: now, to: .main) { activities, error in
        if let error = error as? NSError, error.code == Int(CMErrorMotionActivityNotAuthorized.rawValue) {
	    // "NotAuthorized"
	    } else {
	    // "Authorized"
	    }
        }
    }   
}
```

## Bluetooth Permission

When using the *Device Detection* feature it's possible to get warnings for the Bluetooth permission and power status from the SDK.

These checks will only be performed when the App itself has requested Bluetooth permission from the user, specifically if[`CBCentralManager.authorization`](https://developer.apple.com/documentation/corebluetooth/cbmanager/3377595-authorization) is anything other than `.notDetermined`.

Requesting the Bluetooth permission is done by creating an instance of the *CBCentralManager* type. This is entirely optional, and it's still possible to use the *Device Detection* service without this.

### **Plist**

<table data-header-hidden><thead><tr><th width="384">Key</th><th>Required if</th></tr></thead><tbody><tr><td><strong>Key</strong></td><td>Required if</td></tr><tr><td><a href="https://developer.apple.com/documentation/bundleresources/information_property_list/nsbluetoothalwaysusagedescription"><code>NSBluetoothAlwaysUsageDescription</code></a></td><td>Submitting an App to Testflight or AppStore.</td></tr><tr><td><a href="https://developer.apple.com/documentation/bundleresources/information_property_list/nsbluetoothperipheralusagedescription">NSBluetoothPeripheralUsageDescription</a> </td><td>Required only your application is built for iOS 13.0 or below.</td></tr></tbody></table>

## Health Permissions

{% hint style="warning" %}
MoveSDK 2.15: Health permissions are only required when [Health](https://docs.movesdk.com/move-platform/move-services#health) services are needed, and the additional MoveSDKHealth framework is used. See [Installation](https://docs.movesdk.com/move-platform/sdk/getting-started/ios/installation).
{% endhint %}

The *Health* service requires additional permission strings and entitlements.

The [NSHealthShareUsageDescription](https://developer.apple.com/documentation/BundleResources/Information-Property-List/NSHealthShareUsageDescription) permission string in the Info.plist is required when submitting to the AppStore regardless of whether the Health service is in use, similar to bluetooth permission strings.

<table><thead><tr><th width="279.765625">Key</th><th>Required if</th><th>Comment</th></tr></thead><tbody><tr><td><a href="https://developer.apple.com/documentation/BundleResources/Information-Property-List/NSHealthShareUsageDescription">NSHealthShareUsageDescription</a></td><td>Submitting an App to Testflight or AppStore.</td><td>This text must be at least 12 characters long.</td></tr><tr><td><a href="https://developer.apple.com/documentation/BundleResources/Information-Property-List/NSHealthUpdateUsageDescription">NSHealthUpdateUsageDescription</a></td><td>Submitting an App to Testflight or AppStore.</td><td>This text must be at least 12 characters long.</td></tr></tbody></table>

### Entitlements

Additional entitlements are required to guarantee health data synchronization:

<table><thead><tr><th width="279.765625">Entitlement</th><th>Comment</th></tr></thead><tbody><tr><td>com.apple.developer.healthkit</td><td>Required for Health service.</td></tr><tr><td>com.apple.developer.healthkit.background-delivery</td><td>Health data remains encrypted while the device is locked and cannot be accessed. This entitlement is necessary to wake up the app when health data is available.  It is not guaranteed when the App wakes up for health reasons. </td></tr></tbody></table>

### Provisioning

When the above entitlements are enabled HealthKit must be added to the App Identifier under the corresponding section in **Certificates, Identifiers & Profiles** in the [Apple Developer Portal](https://developer.apple.com/account/resources/identifiers/list).
