iOS Swift SDK
Swift quickstart for the Amba SDK — Swift Package Manager install, Amba.configure, Amba.events.track, Sign in with Apple, and APNs push registration in under 10 minutes.
Amba for iOS is a Swift Package distributed via layers/amba-sdk-ios. Single import; everything else in this guide assumes you've added it to your target.
Supported platforms: iOS 14+, macOS 12+, tvOS 14+, watchOS 7+.
1. Install via Swift Package Manager
In Xcode
File → Add Package Dependencies… → enter:
Pick the dependency rule Up to Next Major with 1.0.0, then add the Amba product to your app target.
In Package.swift
The package resolves to a prebuilt binary published as a release asset on each tagged version — first build downloads ~12 MB, subsequent builds use Xcode's cache.
2. Configure at app launch
For UIKit, do the same in application(_:didFinishLaunchingWithOptions:):
Don't ship a hard-coded key. Inject AmbaClientKey via your .xcconfig, an Info.plist build-setting, or arkana — and reference it via Bundle.main.object(forInfoDictionaryKey:) or your secrets framework.
Which key goes here
For an iOS app, always use the client key that npx @layers/amba init issued for you (printed as clientKey in the CLI output; visible in the amba console under your project's API keys tab). The client key is designed to ship to end-user devices.
Never put a server key in an iOS build. Server keys are for trusted server contexts only — a server-side cron job, a backend endpoint, an edge function — and grant elevated privileges that would let any reverse-engineered IPA impersonate your tenant. The SDK rejects server keys at configure time with AmbaSwiftError.invalidConfig("server key not allowed in client SDK").
3. Verify the SDK reached amba
Amba.configure(...) is synchronous and only validates the key string locally — a typo or wrong env passes it without complaint. To prove the SDK actually reached the platform, call Amba.diagnostics.ping() and log the server-echoed serverProjectId. Drop this into your @main App's init (or application:didFinishLaunchingWithOptions:) right after Amba.configure:
Build and run. In the Xcode console (View → Debug Area → Activate Console, or ⌘⇧Y):
If you see that line, your AmbaClientKey resolved to a real project on the server and the wire round-tripped end-to-end. Compare serverProjectId against the project id you think you configured — a mismatch means the wrong .xcconfig is loading. If you don't see the line:
- No
amba:line at all —Amba.configure(...)threw before the verify Task ran. Check for theamba: failed to configure — ...log from thecatchblock in the snippet above. Most common cause:AmbaClientKeyis empty (.xcconfigdidn't propagate to the build, or the Info.plist key name is misspelled). amba: verify failed — AmbaApiError.unauthorized— the key string is malformed or revoked. Re-runnpx @layers/amba initto mint a fresh one and update your.xcconfig.- Hangs for >5s with no output — the device can't reach
api.amba.dev. Check the Network section of Xcode's debug navigator; a TLS error or DNS failure shows up there.
For CI or test-time gates, escalate the print to an assert/assertionFailure so a misconfiguration fails the build instead of producing a silent log.
4. First sign-in (anonymous + Sign in with Apple)
Amba.events.track is authenticated server-side — the request needs a session token. Sign in (anonymously is fine) before the first track call:
5. First event
Once a session exists, track engagement events:
Amba.events.track is async throws — wrap in a Task { } from UI code, or await directly from another async context.
Sign in with Apple
Add the Sign in with Apple capability in Xcode → Signing & Capabilities before the first build.
6. Register for APNs push
Add the Push Notifications capability + Background Modes → Remote notifications in Xcode before building. Upload your APNs auth key (or .p8) to the amba console once per bundle ID.
7. First collection insert
The Swift SDK uses Codable for typed reads + writes:
8. AI proxy
Calling from SwiftUI
All SDK methods are async throws. From a View, wrap calls in a Task — either implicit on a button action or explicit in .task { } for view-lifecycle work:
.task { } is preferred over .onAppear for async work — it ties the Task's lifetime to the view's lifetime, so a fast nav-back cancels the in-flight call cleanly.
App lifecycle (background, foreground, scene phases)
Amba's HTTP client survives backgrounding — there's no special hook to call when the app goes inactive or returns to foreground. A few things to know:
- Session token refresh happens automatically on the next API call; you don't need to manually refresh on
scenePhase == .active. - In-flight requests are cancelled when the OS suspends the app. They'll resume on the next call after foreground; if you need at-least-once delivery (e.g. an event triggered just before backgrounding), enqueue it from a
BGProcessingTaskor your own retry queue rather than firing it directly inapplicationWillResignActive. - Push registration tokens can rotate when iOS reinstalls the app or restores from backup. Re-call
Amba.push.register(...)on everydidRegisterForRemoteNotificationsWithDeviceToken— the server treats it as idempotent.
Construct an AmbaClient directly (testing / multi-tenant)
For tests or multi-tenant apps, instantiate AmbaClient directly instead of using the singleton facade:
Tests can inject a mock via the internal initializer — see the package's Tests/ directory for the protocol shape.
PrivacyManifest
The SDK ships PrivacyInfo.xcprivacy declaring its data-collection categories per Apple's PrivacyManifest spec. App Store review aggregates this with your app's own manifest — you don't need to copy entries from the SDK into yours.
Common pitfalls
- Events silently vanish —
Amba.events.trackqueues, batches, and retries by design; a wrong key, wrong env, or revoked credential does not throw at the call site. Always run the verify step in section 3 on every fresh build (or gate behind#if DEBUG) so a misconfiguration shows up as a loud failure, not silence. This is the failure mode that ends with "I shipped to TestFlight and no events showed up for a week." - Wrong env in a build flavour — a
clientKeyminted for staging will happily configure against the production stack and quietly write to the wrong project. The verify snippet in section 3 prints the server-resolvedserverProjectId+environment; compare against the values your build expects on first launch instead of finding the drift in retention dashboards a week later. Amba.configurenot called before any otherAmba.*access throwsAmbaSwiftError.notConfigured. Configure ininitof your@mainApp /application:didFinishLaunchingWithOptions:.- Binary not building for simulator — the prebuilt binary includes simulator + device slices for both arm64 and x86_64. If
swift buildfails with "no compatible binary for the current platform," your Xcode is older than 15.0 — upgrade Xcode. - APNs token registered but no delivery — verify the APNs auth key in the amba console matches the bundle ID Xcode signed your app with. The token is valid; the server-side lookup fails 404 if bundle IDs drift.
- Sign in with Apple identity token expired —
credential.identityTokenis short-lived. Always pass it toAmba.auth.signInWithAppleimmediately; don't cache and reuse.
See also
- Client API reference — HTTP endpoint reference for every namespace.
- Code samples — same operations side-by-side with the other 7 SDKs.
- Push notifications — campaign API, scheduling, fan-out.
- SDK source:
layers/amba-sdk-ios(Swift Package Manager mirror).