iOS SDK
Capture events from iOS and macOS apps with AzFiveCapture — identity, sessions, feature flags, surveys and opt-in session replay, zero dependencies.
AzFiveCapture brings AZ-Five product analytics to iOS and macOS: events, identity, sessions, persistence, feature flags & experiments, surveys, and opt-in session replay. SwiftPM package, iOS 15+ / macOS 12+, zero dependencies, under the shared behavioral spec.
Install
In Xcode: File → Add Package Dependencies → https://github.com/az-five/azfive-ios. Or in Package.swift:
dependencies: [
.package(url: "https://github.com/az-five/azfive-ios", from: "0.1.0")
]
Create a public ingest token with “Mobile app token” enabled (Settings → API Keys) — native requests carry no browser Origin, and tokens without that flag fail closed.
Initialize
import AzFiveCapture
let azfive = AzFive.initialize(token: "azfive_pub_…",
config: AzFiveConfig(host: "https://app.az-five.com"))
AzFive.initialize(token:config:) creates and stores the shared client (AzFive.shared). Persistence defaults to UserDefaults; identity and cached flags survive restarts.
Capture events
azfive.capture("signed_up", properties: ["plan": "pro"])
azfive.screen("Checkout") // az.screen_view + survey eligibility re-check
// Super properties — merged into every event
azfive.register(["deployment": "eu-1"])
azfive.registerOnce(["first_touch": "ad-campaign"])
azfive.unregister("deployment")
Opt-in UIViewController screen autocapture is available with autocaptureScreens: true in the config (UIKit only, off by default).
Identify & person properties
azfive.identify("ava@example.com", set: ["plan": "pro"])
azfive.alias("legacy-77")
azfive.peopleSet(["favorite_color": "teal"])
azfive.peopleSetOnce(["signup_date": "2026-08-01"])
// on logout:
azfive.reset() // new anonymous id; reset(resetDeviceId: true) also rotates the device id
identify merges the anonymous session into the person (az.identify with $anonymous_id) and refetches flags; calling it again with the same id only updates properties. Opt-out controls — optInCapturing() / optOutCapturing() / hasOptedOutCapturing() — drop events at capture time, persist, and survive reset().
Feature flags
Flags load from /v1/decide on init, persist for stale-while-revalidate startup, and refetch on identify / reset:
let unsubscribe = azfive.onFlags { flags in
let variant = azfive.getFlag("exp-checkout") // true | false | "variant" | nil
if azfive.isFlagEnabled("new-billing") {
let payload = azfive.getFlagPayload("new-billing") // no exposure event
}
}
azfive.reloadFlags() // force a refetch
getFlag and isFlagEnabled capture an az.flag_called exposure automatically, deduped per session:flag:value. getFlagPayload never does.
Surveys
SwiftUI — one modifier renders decide-delivered surveys:
ContentView().azfiveSurveys(azfive.surveys)
UIKit or custom UI: drive azfive.surveys (a SurveyFlowController) via onChange, currentQuestion, submitAnswer(_:), dismiss(). Responses ship as az.survey_shown / az.survey_dismissed / az.survey_sent events; suppression persists per survey.
Session replay (opt-in, default off)
Screenshot-frame v1: set enableSessionRecording: true in the config and enable recording server-side. Capture is ~1 fps masked JPEG frames plus touches. Masking is best-effort rect occlusion of text inputs and views you tag — weaker than browser rrweb — so review your screens before enabling in production.
Flush & shutdown
Delivery is automatic (10 events / 5 s), and the queue flushes when the app backgrounds. flush() forces delivery now and takes an optional completion handler:
azfive.flush()
Reference
AzFiveConfig
| Parameter | Default | Notes |
|---|---|---|
host | required | AZ-Five deployment base URL |
project | "default" | Target project slug |
batchSize | 10 | Queue length that triggers a flush |
flushIntervalSeconds | 5 | Background flush period |
maxQueueSize | 1000 | Queue bound; oldest events dropped on overflow |
gzip | false | Content-Encoding: gzip on event POSTs |
optOut | false | Start opted out (persisted opt-out wins) |
disableDecide | false | Skip flags/surveys/recording bootstrap |
sessionIdleTimeout | 1800 (30 min) | Session rotation on inactivity, in seconds |
storage | UserDefaultsStore | Custom AzFiveStore persistence backend |
autocaptureScreens | false | UIViewController az.screen_view autocapture (UIKit) |
enableSessionRecording | false | Session replay opt-in; recording still requires the server to enable it |
platformProps | auto-detected | Override the computed static platform properties |
API
capture · screen · identify · alias · reset · getDistinctId · getSessionId · register / registerOnce / unregister · peopleSet / peopleSetOnce · optInCapturing / optOutCapturing / hasOptedOutCapturing · getFlag / isFlagEnabled / getFlagPayload / onFlags / reloadFlags · flush.
Behavior notes
- Sessions rotate after 30 minutes idle or 24 hours total;
$session_idis stamped on every event. - Failed batches —
429included — re-queue at the front and retry next flush; the public API never throws for delivery or flag problems. - Custom event names: anything except the reserved
az.prefix, ≤ 200 characters; properties ≤ 64 KiB serialized.