Skip to main content

iOS SDK Examples & Troubleshooting

Complete implementation examples and solutions to common integration challenges.

Complete Implementation Example

DoorstepAI SDK Test App

This is a complete example of a test app that demonstrates all SDK functionality using SwiftUI:

ContentView.swift
import SwiftUI
import DoorstepDropoffSDK

struct ContentView: View {
@State private var deliveryId: String = ""
@State private var placeId: String = ""
@State private var plusCode: 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
DoorstepAI.enableDevMode()
}
}

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)"
}
}
}

TextField("Plus Code", text: $plusCode)
Button("Start by Plus Code") {
Task {
do {
try await DoorstepAI.startDeliveryByPlusCode(plusCode: plusCode, deliveryId: deliveryId)
statusMessage = "Delivery started successfully with Plus Code"
} 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 {
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

Common Issues and Solutions

1. SDK Initialization Errors

Problem: SDK fails to initialize or API key errors occur.

Solutions:

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

DoorstepAI.setApiKey(key: apiKey)
print("✅ API key set successfully")
}

2. Location Permission Issues

Problem: Location permissions are denied or not properly requested.

Solutions:

import CoreLocation

class LocationPermissionManager: NSObject, ObservableObject, CLLocationManagerDelegate {
private let locationManager = CLLocationManager()
@Published var authorizationStatus: CLAuthorizationStatus = .notDetermined

override init() {
super.init()
locationManager.delegate = self
}

func requestPermissions() {
switch authorizationStatus {
case .notDetermined:
locationManager.requestWhenInUseAuthorization()
case .denied, .restricted:
// Guide user to settings
showSettingsAlert()
case .authorizedWhenInUse:
// Request always authorization for background tracking
locationManager.requestAlwaysAuthorization()
case .authorizedAlways:
print("✅ All location permissions granted")
@unknown default:
break
}
}

func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
DispatchQueue.main.async {
self.authorizationStatus = manager.authorizationStatus
}
}

private func showSettingsAlert() {
// Show alert directing user to app settings
}
}

3. Background Execution Issues

Problem: SDK stops working when app goes to background.

Solutions:

// Ensure proper Info.plist configuration
// Add UIBackgroundModes with "location" value

class AppDelegate: UIResponder, UIApplicationDelegate {
func applicationDidEnterBackground(_ application: UIApplication) {
// SDK automatically handles background processing
// Ensure location permissions include "Always" authorization
print("📱 App entered background - SDK continues tracking")
}

func applicationWillEnterForeground(_ application: UIApplication) {
// App returning to foreground
print("📱 App returning to foreground")
}
}

4. Callback Failures

Problem: SDK methods fail with unclear error messages.

Solutions:

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

// Check for common error patterns
if error.localizedDescription.contains("network") {
print("📡 Network connectivity issue")
// Retry logic or show offline message
} else if error.localizedDescription.contains("permission") {
print("🔒 Permission issue")
// Guide user to grant permissions
} else if error.localizedDescription.contains("api") {
print("🔑 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 integration:

  • ✅ API key is valid and properly configured
  • ✅ All required permissions are in Info.plist
  • ✅ Location permissions are properly requested at runtime
  • ✅ Background location permission is granted
  • ✅ Error handling is implemented for all SDK methods
  • ✅ App handles background/foreground transitions
  • ✅ Delivery IDs are unique and meaningful

Support and Resources

Need additional help?

Best Practices

Remember to test your integration thoroughly in both foreground and background scenarios, and always implement proper error handling for production applications.