Skip to content

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

ParameterDefaultNotes
hostrequiredAZ-Five deployment base URL
project"default"Target project slug
batchSize10Queue length that triggers a flush
flushIntervalSeconds5Background flush period
maxQueueSize1000Queue bound; oldest events dropped on overflow
gzipfalseContent-Encoding: gzip on event POSTs
optOutfalseStart opted out (persisted opt-out wins)
disableDecidefalseSkip flags/surveys/recording bootstrap
sessionIdleTimeout1800 (30 min)Session rotation on inactivity, in seconds
storageUserDefaultsStoreCustom AzFiveStore persistence backend
autocaptureScreensfalseUIViewController az.screen_view autocapture (UIKit)
enableSessionRecordingfalseSession replay opt-in; recording still requires the server to enable it
platformPropsauto-detectedOverride 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_id is stamped on every event.
  • Failed batches — 429 included — 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.