Fire the call inside your deep-link handler — SceneDelegate.scene(_:continue:) on iOS, Intent filter receiver on Android, the equivalent React Native Linking handler, Flutter's uni_links callback. Don't pass the URL or its query parameters.
▸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.
▸Track the event in Swift (iOS)
import Respectlytics
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
// Universal Link entry — fire the event, don't pass the URL.
Respectlytics.track("deeplink_open")
if let url = userActivity.webpageURL {
router.handle(url) // routing keeps the URL; analytics doesn't.
}
}
}
For custom-scheme URLs, use scene(_:openURLContexts:) instead — same track call. If you use SwiftUI's .onOpenURL, fire track inside that closure.
✦Privacy & implementation notes
A deep-link URL often contains the user's tracking ID, the campaign source, the referrer, and sometimes a session token — concatenated into a single free-form string. Respectlytics's API rejects free-form strings as event metadata. Your routing code keeps the URL; analytics gets the event name.
Install attribution and deep-link open are different signals. Install attribution requires server-side callbacks from the App Store / Play Store. Deep-link open is the in-app signal that the user navigated via a link. Don't use the open event as a proxy for install — they fire at different times for different populations.
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
| Deep-link open event | Firebase Analytics | Mixpanel | Respectlytics |
|---|---|---|---|
| Full URL stored | Often (via Dynamic Links) | Often | Rejected by API |
| UTM parameters as event properties | Yes (default for web tracking) | Yes | Rejected by API |
| Referral code as parameter | Recommended | Recommended | Use distinct event_name (top-N) or skip |
| Per-campaign attribution | Per-user | Per-user | Session-scoped, top-N campaigns only |
| Click-through rate (link → app open) | With Dynamic Links | With server-side join | Out of scope (use server-side analytics) |
❓Frequently asked questions
How do we know which campaign drove an install?
Server-side, not in product analytics. App Store Connect (Apple Search Ads) and Play Console (Play Store referrer API) deliver install attribution to your backend via server-to-server callbacks. Respectlytics is for in-app product engagement — different question, different system of record.
What about top-N campaign tracking via event names?
If you have a small set of high-volume campaigns (under 10), distinct event names work: deeplink_open_summer_sale, deeplink_open_press_pickup. The long tail bucketed as deeplink_open_other. For high-cardinality campaign ID tracking, use server-side attribution instead.
Should we distinguish Universal Links / App Links from custom schemes?
If your app supports both (which is common during a migration), use distinct event names: deeplink_open_universal, deeplink_open_custom_scheme. The rate of each tells you how successfully you've migrated traffic to the modern API.
What if the deep link triggers in-app navigation but no other events?
Common with deep links to settings or specific content. Fire deeplink_open anyway — the open itself is the signal. If the user goes on to convert in the same session, the funnel groups them together via session_id.