▸Install the Swift (iOS) SDK
// Package.swift
dependencies: [
.package(url: "https://github.com/respectlytics/respectlytics-swift.git", from: "3.0.0")
]
// Or via Xcode → File → Add Packages → paste the URL above.
The SDK ships only via Swift Package Manager. CocoaPods and Carthage are not published — fewer integration paths means fewer surfaces to keep audited.
▸Initialize Respectlytics in Swift (iOS)
import Respectlytics
@main
struct MyApp: App {
init() {
Respectlytics.configure(appKey: "<YOUR_APP_KEY>")
}
var body: some Scene { WindowGroup { ContentView() } }
}
Call configure once at app launch — typically in your App struct's init. No Info.plist keys are required: the SDK does not call ATTrackingManager and does not request the IDFA, so NSUserTrackingUsageDescription should NOT be added.
✦Privacy & implementation notes
Apple's review team flags ~3% of apps for incorrectly omitting NSUserTrackingUsageDescription when their SDKs need ATT. The mirror case is also true: adding the key when your code does not call ATTrackingManager is a flag in the other direction. Don't add it on Respectlytics's account.
Most teams arriving here are migrating from a Firebase-style integration where IDFA was collected with consent. The simplification is not just removing the field — it's removing the consent UX, the privacy label tier, the conditional analytics paths in code, and the legal-team follow-up question "what do we do with the data?". Respectlytics's answer is: there is no IDFA, so there's nothing to do.
Apple rejected approximately 3% of apps in 2024 for incorrectly omitting NSUserTrackingUsageDescription when ATT was required by the SDKs they shipped. Respectlytics doesn't trigger ATT. The corollary is also true: do not add the key on Respectlytics's account — its presence implies you track across apps, even if your code never calls requestTrackingAuthorization.
Internally the Swift SDK uses Swift Concurrency: events are queued in an actor-isolated buffer (RAM-only), flushed on a 30-second timer and on UIApplication.willResignActiveNotification. Force-quit before flush drops queued events — by design. There is no UserDefaults or file backing.
⇋How this compares to other analytics SDKs
| IDFA handling | Firebase Analytics | Mixpanel | AppsFlyer | Respectlytics |
|---|---|---|---|---|
| Calls ATTrackingManager | Yes (with consent) | Yes (optional) | Yes (mandatory) | No |
| Stores IDFA in events | Yes (when consented) | Optional | Yes | Never |
| Re-requests IDFA after restart | Yes | Yes | Yes | N/A |
| Behavior when consent denied | IDFA absent | IDFA absent | Limited tracking | Identical (no IDFA path) |
| App Store Privacy Label impact | Triggers "Identifiers" tier | Triggers "Identifiers" | Triggers "Identifiers" | No "Identifiers" entry from us |
❓Frequently asked questions
How do we measure unique users without IDFA?
By session, not by user. Respectlytics's session_id rotates every two hours and on app restart, so unique-session counts (not unique-user counts) are what surface in dashboards. For most product decisions — funnel rates, feature reach, release deltas — sessions are the right unit. Per-user counts for billing or financial reporting live in your account system, not your analytics pipeline.
Do we still need an `NSUserTrackingUsageDescription` Info.plist key?
No — and you should NOT add one for Respectlytics. The presence of that key implies your app tracks across other apps and websites, which Apple interprets as a signal even if your code never calls ATTrackingManager.requestTrackingAuthorization. Add the key only if another SDK in your app legitimately needs it.
Will Respectlytics ever collect IDFA in a future version?
No. The 5-field event schema is enforced at the API boundary — additions would be a versioned breaking change with explicit migration. The privacy posture is architectural, not policy-level.
What about IDFV (vendor identifier) — is that collected?
Also no. The SDK does not read UIDevice.current.identifierForVendor. Session-scoped analytics doesn't need a per-device or per-vendor identifier — the session_id is sufficient for funnel grouping and rotates before any cross-day tracking would emerge.