Skip to main content

iOS SDK Examples & Troubleshooting

Complete implementation examples and solutions to common integration challenges.

Quickstart

The full lifecycle, stripped of UI:

import DoorstepDropoffSDK

// Once at startup
DoorstepAI.setApiKey(key: "YOUR_API_KEY_HERE")

// Per delivery, driven by your geofence
Task {
do {
try await DoorstepAI.startDeliveryByAddressString(
address: "123 Main St, Apt 4B, San Francisco, CA 94102",
deliveryId: "delivery_12345",
coordinates: LatLngObject(lat: 37.7749, lng: -122.4194)
)
try await DoorstepAI.markDropoff(deliveryId: "delivery_12345", dropoffType: .pod)
await DoorstepAI.stopDelivery(deliveryId: "delivery_12345")
} catch {
// Handle error
}
}

Full test-app view

The view below wires those calls to a UI for manual testing (SwiftUI):

Show full component
ContentView.swift
import SwiftUI
import DoorstepDropoffSDK

struct ContentView: View {
@State private var deliveryId: String = ""
@State private var placeId: String = ""
@State private var streetNumber: String = ""
@State private var route: String = ""
@State private var subPremise: String = ""
@State private var locality: String = ""
@State private var administrativeArea: String = ""
@State private var postalCode: String = ""
@State private var eventName: String = ""
@State private var statusMessage: String = ""
@State private var isDevMode: Bool = false

var body: some View {
DoorstepAIRoot()
NavigationView {
Form {
Section(header: Text("Configuration")) {
Toggle("Development Mode", isOn: $isDevMode)
.onChange(of: isDevMode) { newValue in
Task {
await DoorstepAI.enableDevMode(apiKey: Environment.DOORSTEP_API_KEY)
}
}
}

Section(header: Text("Delivery ID")) {
TextField("Delivery ID", text: $deliveryId)
}

Section(header: Text("Start Delivery")) {
Group {
TextField("Place ID", text: $placeId)
Button("Start by Place ID") {
Task {
do {
try await DoorstepAI.startDeliveryByPlaceID(placeID: placeId, deliveryId: deliveryId)
statusMessage = "Delivery started successfully with Place ID"
} catch {
statusMessage = "Error: \(error.localizedDescription)"
}
}
}

Button("Mark Dropoff (POD)") {
Task {
do {
try await DoorstepAI.markDropoff(deliveryId: deliveryId, dropoffType: .pod)
statusMessage = "Dropoff marked"
} catch {
statusMessage = "Error: \(error.localizedDescription)"
}
}
}
}

Group {
TextField("Street Number", text: $streetNumber)
TextField("Route", text: $route)
TextField("Sub Premise", text: $subPremise)
TextField("Locality", text: $locality)
TextField("Administrative Area", text: $administrativeArea)
TextField("Postal Code", text: $postalCode)

Button("Start by Address") {
Task {
do {
let address = AddressType(
streetNumber: streetNumber,
route: route,
subPremise: subPremise,
locality: locality,
administrativeAreaLevel1: administrativeArea,
postalCode: postalCode
)
try await DoorstepAI.startDeliveryByAddressType(address: address, deliveryId: deliveryId)
statusMessage = "Delivery started successfully with Address"
} catch {
statusMessage = "Error: \(error.localizedDescription)"
}
}
}
}
}

Section(header: Text("Delivery Actions")) {
TextField("Event Name", text: $eventName)
Button("Send Event") {
Task {
do {
// records a custom event on the delivery
try await DoorstepAI.newEvent(eventName: eventName, deliveryId: deliveryId)
statusMessage = "Event sent successfully"
} catch {
statusMessage = "Error: \(error.localizedDescription)"
}
}
}

Button("Stop Delivery") {
Task {
await DoorstepAI.stopDelivery(deliveryId: deliveryId)
statusMessage = "Delivery stopped"
}
}
}

if !statusMessage.isEmpty {
Section(header: Text("Status")) {
Text(statusMessage)
}
}
}
.navigationTitle("DoorstepAI Test")
.onAppear {
DoorstepAI.setApiKey(key: Environment.DOORSTEP_API_KEY)
}
}
}
}

#Preview {
ContentView()
}

Troubleshooting

1. SDK Initialization Errors

Solutions:

// Check API key validity
func validateAPIKey() {
// Ensure API key is not empty or placeholder
guard !apiKey.isEmpty && apiKey != "YOUR_API_KEY_HERE" else {
// Invalid API key
return
}

DoorstepAI.setApiKey(key: apiKey)
}

2. Location Permission Issues

Solutions:

Request permissions with DoorstepAI.requestAllPermissions() (see the Usage guide). If the user has already denied the prompt, iOS won't re-prompt, so guide them to Settings instead:

import UIKit
import CoreLocation

func handleDeniedLocationPermission(_ status: CLAuthorizationStatus) {
guard status == .denied || status == .restricted else { return }

// Guide the user to Settings to enable permissions manually
if let settingsURL = URL(string: UIApplication.openSettingsURLString) {
UIApplication.shared.open(settingsURL)
}
}

3. Background Execution Issues

See Best Practices in the Usage guide. The SDK handles backgrounding automatically; don't stop a delivery just because the app is backgrounded.

4. Callback Failures

Solutions:

func handleSDKError(_ error: Error) {
print("SDK error: \(error.localizedDescription)")

// Check for common error patterns
if error.localizedDescription.contains("network") {
// Network connectivity issue; retry or show offline message
} else if error.localizedDescription.contains("permission") {
// Permission issue; guide user to grant permissions
} else if error.localizedDescription.contains("api") {
// API key or authentication issue; check API key validity
}

// Log error for debugging
Logger.error("DoorstepAI SDK Error", metadata: [
"error": "\(error)",
"timestamp": "\(Date())"
])
}

Testing Checklist

Before releasing your iOS integration:

  • Delivery IDs are unique and meaningful
  • Error handling is implemented for all SDK methods
  • App handles background/foreground transitions

Support and Resources

Need additional help?