From 65c8155d16f592862cb8ced747c41a7102794bf1 Mon Sep 17 00:00:00 2001 From: Jordan Morgan Date: Tue, 30 Jun 2026 13:09:22 -0500 Subject: [PATCH] Document iOS event tracking behavior controls Adds iOS 4.16.0 release notes and updates SDK docs for the new `EventTrackingBehavior` API on `SuperwallOptions` and `Superwall.shared`. The docs now explain runtime consent updates, behavior modes (`.all`, `.superwallOnly`, `.none`), and deprecate `isExternalDataCollectionEnabled` with its compatibility mapping. Shared configuration guidance was also revised to reflect iOS migration details and clarify current behavior on Android, Flutter, and Expo. --- content/docs/ios/changelog.mdx | 14 +++++++ content/docs/ios/sdk-reference/Superwall.mdx | 18 +++++++- .../ios/sdk-reference/SuperwallOptions.mdx | 41 +++++++++++++++++++ .../configuring/using-superwalloptions.mdx | 36 +++++++++++++--- 4 files changed, 102 insertions(+), 7 deletions(-) diff --git a/content/docs/ios/changelog.mdx b/content/docs/ios/changelog.mdx index 486eca4a..e5724a4c 100644 --- a/content/docs/ios/changelog.mdx +++ b/content/docs/ios/changelog.mdx @@ -3,6 +3,20 @@ title: "Changelog" description: "Release notes for the Superwall iOS SDK" --- +## 4.16.0 + +### Enhancements + +- Adds install attribution matching support. If you set up performance marketing integrations on the Superwall dashboard, the SDK will attempt to match the install and track an `attribution_match` event. The attribution properties will be added to user attributes so that they can be used as breakdowns and filters in the charts. +- Adds support for annual subscriptions that are billed monthly. +- Added `EventTrackingBehavior` enum and `SuperwallOptions.eventTrackingBehavior` property for GDPR-compliant event collection control. Use `.all` (default) to track everything, `.superwallOnly` to suppress user-initiated tracking, trigger fires, and user-attribute updates while keeping internal SDK events, or `.none` to stop all event collection entirely. The behavior can also be changed at runtime via `Superwall.shared.eventTrackingBehavior`. +- Deprecated `SuperwallOptions.isExternalDataCollectionEnabled`. Setting it to `false` now maps to `.superwallOnly`; setting it back to `true` maps to `.all`. + +### Fixes + +- Fixes a crash due to concurrent calls to `preloadAllPaywalls`. +- Fixes an intro offer eligibility mismatch between the paywall and the payment sheet when upgrading/crossgrading/downgrading. + ## 4.15.4 ### Enhancements diff --git a/content/docs/ios/sdk-reference/Superwall.mdx b/content/docs/ios/sdk-reference/Superwall.mdx index 99a23d25..b63d41a9 100644 --- a/content/docs/ios/sdk-reference/Superwall.mdx +++ b/content/docs/ios/sdk-reference/Superwall.mdx @@ -98,6 +98,7 @@ Provides access to the configured Superwall instance after calling [`configure() ## Signature ```swift public static var shared: Superwall { get } +public var eventTrackingBehavior: EventTrackingBehavior { get set } ``` ## Parameters @@ -130,6 +131,21 @@ Superwall.shared.setUserAttributes([ ]) ``` +Change event collection at runtime: + +```swift +// Stop SDK event collection after the user opts out. +Superwall.shared.eventTrackingBehavior = .none + +// Keep Superwall's internal events, but suppress app-sent events and user attributes. +Superwall.shared.eventTrackingBehavior = .superwallOnly + +// Restore the default behavior. +Superwall.shared.eventTrackingBehavior = .all +``` + +This property is available in iOS SDK `4.16.0` and later. It updates the SDK's event queue and the currently displayed paywall, so your app can respond to consent changes without reconfiguring Superwall. If you need an initial value before the SDK is configured, set [`SuperwallOptions.eventTrackingBehavior`](/ios/sdk-reference/SuperwallOptions) before calling [`configure()`](/ios/sdk-reference/configure). + Reset the user: ```swift @@ -194,4 +210,4 @@ Manually refresh configuration (development-only): ```swift // Useful when hot-reloading paywalls during development await Superwall.shared.refreshConfiguration() -``` \ No newline at end of file +``` diff --git a/content/docs/ios/sdk-reference/SuperwallOptions.mdx b/content/docs/ios/sdk-reference/SuperwallOptions.mdx index def92aa7..669e7893 100644 --- a/content/docs/ios/sdk-reference/SuperwallOptions.mdx +++ b/content/docs/ios/sdk-reference/SuperwallOptions.mdx @@ -113,6 +113,9 @@ public final class SuperwallOptions: NSObject { public var logging: LoggingOptions public var localeIdentifier: String? public var shouldBypassAppTransactionCheck: Bool + public var eventTrackingBehavior: EventTrackingBehavior + @available(*, deprecated, renamed: "eventTrackingBehavior") + public var isExternalDataCollectionEnabled: Bool public var testModeBehavior: TestModeBehavior public var localResources: [String: AssetResource] } @@ -151,6 +154,18 @@ public final class SuperwallOptions: NSObject { description: "Disables the app transaction check on SDK launch. Useful in testing environments to avoid triggering the Apple ID sign-in prompt. Available in version 4.9.0+.", default: "false", }, + eventTrackingBehavior: { + type: "EventTrackingBehavior", + description: + "Controls which SDK events are sent to Superwall. Options: `.all`, `.superwallOnly`, and `.none`. Available in version 4.16.0+.", + default: ".all", + }, + isExternalDataCollectionEnabled: { + type: "Bool", + description: + "Deprecated in version 4.16.0. Use `eventTrackingBehavior` instead. Setting this to `false` maps to `.superwallOnly` unless the current behavior is already `.none`.", + default: "true", + }, testModeBehavior: { type: "TestModeBehavior", description: @@ -194,6 +209,9 @@ options.localeIdentifier = "en_GB" // Bypass app transaction check (useful for testing) options.shouldBypassAppTransactionCheck = true +// Control SDK event collection +options.eventTrackingBehavior = .superwallOnly + // Use with configure Superwall.configure( apiKey: "pk_your_api_key", @@ -201,6 +219,28 @@ Superwall.configure( ) ``` +## Event Tracking Behavior + +Use `eventTrackingBehavior` to decide which SDK events are sent to Superwall. Set it before `configure()` for the initial value, or update [`Superwall.shared.eventTrackingBehavior`](/ios/sdk-reference/Superwall) later when the user changes a privacy or consent setting. + +| Behavior | Result | +| --- | --- | +| `.all` | Sends all SDK event collection. This is the default. | +| `.superwallOnly` | Keeps internal Superwall event collection, but suppresses user-initiated `Superwall.track(...)` calls, trigger-fire events, and user-attribute updates. | +| `.none` | Sends no SDK events to Superwall. Install-attribution matching is also skipped, so `acquisition_*` user attributes are not populated and audience rules that rely on them will not match. | + +```swift +let options = SuperwallOptions() +options.eventTrackingBehavior = .none + +Superwall.configure( + apiKey: "pk_your_api_key", + options: options +) +``` + +`isExternalDataCollectionEnabled` is deprecated. Existing code that sets it to `false` now maps to `.superwallOnly`; use `.none` when your app needs to stop SDK event collection entirely. + PaywallOptions configuration: ```swift let paywallOptions = PaywallOptions() @@ -280,6 +320,7 @@ func configureSuperwallForDebug() { - [`PaywallOptions`](/ios/sdk-reference/PaywallOptions) - [`localResources`](/ios/sdk-reference/localResources) +- [`Superwall.eventTrackingBehavior`](/ios/sdk-reference/Superwall) ## Runtime Interface Style Configuration diff --git a/content/shared/configuring/using-superwalloptions.mdx b/content/shared/configuring/using-superwalloptions.mdx index 6f41a74b..2a634f73 100644 --- a/content/shared/configuring/using-superwalloptions.mdx +++ b/content/shared/configuring/using-superwalloptions.mdx @@ -307,34 +307,56 @@ Superwall.shared.preloadAllPaywalls(); Note: These methods will not reload any paywalls that have already been preloaded. -### External Data Collection +### Event Tracking Behavior -By default, Superwall sends all registered events and properties back to the Superwall servers. However, if you have privacy concerns, you can stop this by setting `isExternalDataCollectionEnabled` to `false`: +By default, Superwall allows the SDK to send event collection that supports paywall analytics, reporting, and targeting. Use the platform-specific options below when your app needs to control which SDK events are sent to Superwall. :::ios +On iOS SDK `4.16.0` and later, use `eventTrackingBehavior`: + +| Behavior | What Superwall sends | +| --- | --- | +| `.all` | All SDK event collection is enabled. This is the default. | +| `.superwallOnly` | Internal Superwall events continue to be sent, but user-initiated `Superwall.track(...)` calls, trigger-fire events, and user-attribute updates are suppressed. | +| `.none` | No SDK events are sent to Superwall. Paywalls still work because paywall logic runs on device, but dashboard analytics, attribution matching, and audience rules that depend on `acquisition_*` attributes will not receive this event data. | + +Set the initial behavior before calling `configure()`: + ```swift Swift let options = SuperwallOptions() -options.isExternalDataCollectionEnabled = false +options.eventTrackingBehavior = .none Superwall.configure(apiKey: "MY_API_KEY", options: options) ``` ```swift Objective-C SWKSuperwallOptions *options = [[SWKSuperwallOptions alloc] init]; -options.isExternalDataCollectionEnabled = false; +options.eventTrackingBehavior = SWKEventTrackingBehaviorNone; [Superwall configureWithApiKey:@"MY_API_KEY" purchaseController:nil options:options completion:nil]; ``` +You can also change the behavior at runtime after the SDK is configured. This is useful when a user changes a privacy or consent setting in your app. + +```swift +Superwall.shared.eventTrackingBehavior = .none +``` + +`isExternalDataCollectionEnabled` is deprecated on iOS SDK `4.16.0` and later. If older code sets it to `false`, the SDK maps that to `.superwallOnly`, not `.none`. Use `.none` when your app needs to stop SDK event collection entirely. + +After updating to an SDK and paywall runtime that supports this behavior, re-save your paywalls so the paywall content receives the current event tracking behavior. + ::: :::android +Android currently uses `isExternalDataCollectionEnabled`. Setting it to `false` suppresses user-initiated tracking, trigger-fire events, and user-attribute updates while keeping internal Superwall event collection enabled. + ```kotlin val options = SuperwallOptions() options.isExternalDataCollectionEnabled = false @@ -357,6 +379,8 @@ configureSuperwall("MY_API_KEY") { :::flutter +Flutter currently uses `isExternalDataCollectionEnabled`. Setting it to `false` suppresses user-initiated tracking, trigger-fire events, and user-attribute updates while keeping internal Superwall event collection enabled. + ```dart SuperwallOptions options = SuperwallOptions(); options.isExternalDataCollectionEnabled = false; @@ -371,6 +395,8 @@ Superwall.configure( :::expo +Expo currently uses `isExternalDataCollectionEnabled`. Setting it to `false` suppresses user-initiated tracking, trigger-fire events, and user-attribute updates while keeping internal Superwall event collection enabled. + ```typescript const options = SuperwallOptions() options.isExternalDataCollectionEnabled = false @@ -383,8 +409,6 @@ Superwall.configure( ::: -Disabling this will not affect your ability to create triggers based on properties. - ### Automatically Dismissing the Paywall By default, Superwall automatically dismisses the paywall when a product is purchased or restored. You can disable this by setting `automaticallyDismiss` to `false`: