Skip to main content

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:
<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:
    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:
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.
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:
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:
// 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
}
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.

4. Understanding session types

Every session requires a session type that indicates what the driver is doing:
SessionTypeWhen to use
.pickupDriver is collecting a package from a merchant/warehouse
.dropDriver is delivering a package to a customer
.transitDriver is traveling between stops (no specific address)
For .pickup and .drop sessions, you must provide an address. For .transit sessions, the address is optional.

5. Understanding the Address model

The SDK provides a structured Address model for delivery locations:
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):
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

ParameterTypeDescription
deliveryIdStringYour internal delivery/order identifier
sessionTypeSessionType.pickup, .drop, or .transit

Optional parameters

ParameterTypeDescription
addressAddress?Delivery address (required for .pickup/.drop, optional for .transit)
externalRiderIdString?Your system’s driver/rider ID
startLocationStartLocation?Override the starting GPS position (auto-captured if not provided)

Full example with all parameters

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:
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: