> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getdesmo.io/llms.txt
> Use this file to discover all available pages before exploring further.

# iOS SDK Quickstart

> Install the Desmo iOS SDK and record your first delivery session.

## What you'll build

In this quickstart you will:

* Install the **Desmo iOS SDK** via Swift Package Manager.
* Initialize the SDK with your **publishable key**.
* Start and stop a **delivery session** from your app.

This page assumes you already have a Desmo account and at least one **publishable key** that starts with `pk_...`.\
If you don't have a key yet, contact your Desmo representative to have one issued for your project.

## Requirements

* iOS 15.0 or later
* Xcode 15 or later
* Swift 5.9 or later

### App permissions

To let Desmo record sessions correctly, your app should request:

* **Location** – so sessions can be tied to where the delivery happened.
* **Motion & Fitness** – so Desmo can interpret movement patterns during the session.

Add these keys to your `Info.plist` with user-facing explanations that match your product:

```xml theme={null}
<key>NSLocationWhenInUseUsageDescription</key>
<string>We use your location during active deliveries to record proof of delivery.</string>
<key>NSMotionUsageDescription</key>
<string>We use motion data during active deliveries to understand movement for proof of delivery.</string>
```

You can customize the strings, but keep the intent clear: data is only used during active deliveries to power Desmo's proof‑of‑delivery intelligence.

## 1. Install the SDK (Swift Package Manager)

You can add the SDK either through **Xcode** or by editing your own `Package.swift`.

### Option 1 – Add via Xcode UI

1. In Xcode, open your app project.

2. Go to **File → Add Package Dependencies…**

3. In the search field, paste the package URL:

   ```text theme={null}
   https://github.com/kubocreate/desmo-iOS-sdk.git
   ```

4. When prompted for **Dependency Rule**, choose:

   * **Version** → "Up to Next Major"
   * Starting from: `1.0.2`

5. Select the product **`DesmoTraceSDK`** for your app target and finish.

If you previously added the SDK code manually (for example, as a local project), **remove that** and keep **only** the SPM package to avoid duplicates.

### Option 2 – Add to `Package.swift`

If you use SwiftPM directly, add this to your app's `Package.swift`:

```swift theme={null}
dependencies: [
    .package(
        url: "https://github.com/kubocreate/desmo-iOS-sdk.git",
        from: "1.0.2"
    )
],
targets: [
    .target(
        name: "YourAppTarget",
        dependencies: [
            .product(name: "DesmoTraceSDK", package: "DesmoTraceSDK")
        ]
    )
]
```

## 2. Initialize the SDK

Call `Desmo.setup` once at app startup, usually in your `App`'s `init` or in your `AppDelegate`.

```swift theme={null}
import SwiftUI
import DesmoTraceSDK

@main
struct YourApp: App {
    init() {
        Desmo.setup(
            key: "pk_sandbox_XXXXXXXXXXXXXXXX",  // your Desmo publishable key
            environment: .sandbox                // use .live in production
        )
    }

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}
```

* `key`: your **publishable** Desmo API key (starts with `pk_`).
* `environment`:
  * `.sandbox` – Desmo sandbox environment.
  * `.live` – Desmo production environment.

If `Desmo.setup` fails (for example, if the key does not start with `pk_`), the SDK will log an error and `Desmo.shared` will remain `nil`.

## 3. Request permissions

The SDK provides a helper to request all required permissions upfront. Call this during your app's onboarding or before starting the first session:

```swift theme={null}
import DesmoTraceSDK

func requestPermissionsOnLaunch() {
    Desmo.requestPermissions {
        // Permission prompts have been shown
        if Desmo.hasRequiredPermissions() {
            print("All permissions granted - ready to record!")
        } else {
            let missing = Desmo.missingPermissions()
            print("Missing permissions: \(missing)")
        }
    }
}
```

You can also check permission status without prompting:

```swift theme={null}
// Check what's required
let required = Desmo.requiredPermissions  // [.location, .motion]

// Check if all permissions are granted
if Desmo.hasRequiredPermissions() {
    // Ready to start sessions
} else {
    let missing = Desmo.missingPermissions()
    // Prompt user to grant permissions in Settings
}
```

<Note>
  Requesting permissions upfront ensures sensor data flows immediately when a session starts. If you skip this step, the SDK will request permissions during `startSession()`, but the first few seconds of data may be missing while the user responds to the prompts.
</Note>

## 4. Understanding session types

Every session requires a **session type** that indicates what the driver is doing:

| SessionType | When to use                                              |
| ----------- | -------------------------------------------------------- |
| `.pickup`   | Driver is collecting a package from a merchant/warehouse |
| `.drop`     | Driver is delivering a package to a customer             |
| `.transit`  | Driver is traveling between stops (no specific address)  |

<Note>
  For `.pickup` and `.drop` sessions, you must provide an `address`. For `.transit` sessions, the address is optional.
</Note>

## 5. Understanding the Address model

The SDK provides a structured `Address` model for delivery locations:

```swift theme={null}
import DesmoTraceSDK

// Option 1: Raw address string (when you only have unstructured data)
let rawAddress = Address.fromRaw("123 Main Street, San Francisco, CA 94102")

// Option 2: Structured address (preferred for better insights)
let structuredAddress = Address(
    line1: "123 Main Street",
    line2: "Apt 4B",
    city: "San Francisco",
    state: "CA",
    postalCode: "94102",
    country: "US"
)
```

Use structured addresses when possible — they provide better location context for delivery insights.

## 6. Start a delivery session

Call this when you begin recording a delivery (for example, when the driver starts a drop-off):

```swift theme={null}
import DesmoTraceSDK

func startDeliverySession() async {
    guard let client = Desmo.shared else {
        print("Desmo SDK is not configured")
        return
    }

    do {
        let session = try await client.startSession(
            deliveryId: "DELIVERY_123",
            sessionType: .drop,
            address: Address.fromRaw("123 Main Street, San Francisco")
        )
        print("Started session: \(session.sessionId)")
    } catch {
        print("Failed to start session: \(error)")
    }
}
```

### Required parameters

| Parameter     | Type          | Description                             |
| ------------- | ------------- | --------------------------------------- |
| `deliveryId`  | `String`      | Your internal delivery/order identifier |
| `sessionType` | `SessionType` | `.pickup`, `.drop`, or `.transit`       |

### Optional parameters

| Parameter         | Type             | Description                                                                |
| ----------------- | ---------------- | -------------------------------------------------------------------------- |
| `address`         | `Address?`       | Delivery address (required for `.pickup`/`.drop`, optional for `.transit`) |
| `externalRiderId` | `String?`        | Your system's driver/rider ID                                              |
| `startLocation`   | `StartLocation?` | Override the starting GPS position (auto-captured if not provided)         |

### Full example with all parameters

```swift theme={null}
let session = try await client.startSession(
    deliveryId: "ORDER_12345",
    sessionType: .drop,
    externalRiderId: "DRIVER_789",
    address: Address(
        line1: "456 Oak Avenue",
        city: "San Francisco",
        state: "CA",
        postalCode: "94102",
        country: "US"
    ),
    startLocation: StartLocation(lat: 37.7749, lng: -122.4194)
)
```

Behind the scenes, the SDK:

* Calls Desmo's backend to create a session.
* Starts collecting telemetry on-device (IMU, GPS, barometer, magnetometer).
* Begins batching telemetry to Desmo while the session is recording.
* Persists data locally if offline and retries when connectivity returns.

## 7. Stop a delivery session

Call this when the delivery is complete:

```swift theme={null}
func stopDeliverySession() async {
    guard let client = Desmo.shared else {
        print("Desmo SDK is not configured")
        return
    }

    do {
        let session = try await client.stopSession()
        print("Stopped session: \(session.sessionId)")
    } catch {
        print("Failed to stop session: \(error)")
    }
}
```

When you stop the session, the SDK:

* Flushes any remaining telemetry.
* Notifies the backend that the session is complete.
* Lets Desmo's workers start processing PoD intelligence for that session.

## Next steps

From here:

* **Configure keys and environments** in [Auth & Environments](/essentials/ios-auth-environments).
* **Enable logging and troubleshoot** in [Logging, Debugging & Troubleshooting](/essentials/ios-logging-debugging).
* Revisit the **Desmo Integration Overview** at [Integrating Desmo](/) to see how the iOS SDK fits with your backend APIs and dashboard.
