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?
- 📧 Support Email - Direct technical support