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?
- 📧 Support Email - Direct technical support
Best Practices
Remember to test your integration thoroughly in both foreground and background scenarios, and always implement proper error handling for production applications.