Like renewals, cancellation events ideally come from your billing system's webhooks. Cancellation initiated in your app (a settings-screen "cancel subscription" CTA) is also fair game for a client-side fire, but use the same event_name so the two paths aggregate together.
▸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 StoreKit
// In a settings screen, when the user taps 'Manage Subscriptions':
Button("Cancel subscription") {
// The user is *initiating* cancel — actual cancellation may happen on the App Store.
Respectlytics.track("subscription_cancel_initiated")
// Open the App Store subscription management screen:
if let url = URL(string: "https://apps.apple.com/account/subscriptions") {
UIApplication.shared.open(url)
}
}
The actual subscription_cancelled event (effective at billing-period end) should fire from your backend on App Store Server Notification V2's DID_CHANGE_RENEWAL_STATUS.
✦Privacy & implementation notes
Free-text cancellation surveys produce two outputs: useful product insight, and PII soup ("my name is X and I'm leaving because…"). Respectlytics's API rejects free-text fields outright — survey responses belong in a customer-support tool with proper retention controls and access policies, not in analytics.
Cancel-initiated and cancel-effective are different events with different product implications. Conflating them under one subscription_cancelled event loses the save-rate signal between them — typically the most actionable churn metric a subscription product has.
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
| Subscription cancel event | Firebase Analytics | Mixpanel | Respectlytics |
|---|---|---|---|
| Cancellation reason as parameter | Recommended | Recommended | Use distinct event_name |
| Free-text reason / feedback survey | Common | Common | Forbidden (PII) |
| Per-user identity | Yes | Yes | Never |
| Cancel-then-resubscribe linkage | Per-user | Per-user (Identity Merging) | Out of scope |
| Churn *rate* by country / platform | Yes | Yes | Yes (default aggregation) |
❓Frequently asked questions
How do we know *why* users cancel without storing reasons?
Two layers. For quantitative reasons (tier, payment-method failure, platform), use distinct event names: subscription_cancelled_voluntary, subscription_cancelled_payment_failed. For qualitative reasons ("feature X was missing"), run a customer-support intake — that's not analytics' job.
Should we fire when the user *initiates* cancel, or when it actually takes effect?
Both, with distinct event names: subscription_cancel_initiated (immediate intent signal) and subscription_cancelled (effective at billing-period end). Some teams convince ~10% of initiated-cancels to stay; the funnel between the two events is your save rate.
What about involuntary cancels (failed payment, account closed)?
Distinct event name: subscription_cancelled_involuntary. The reasons differ fundamentally from voluntary cancels, and so do the product responses (you might dunning-retry payment-failed, but not voluntary).
Do we still need this in Respectlytics if our billing system has cancellation data?
Yes — for in-app correlations. "What feature did users last touch before initiating cancel?" needs both the cancellation event and other in-app events in the same analytics pipeline. Your billing system can't answer that.