diff --git a/content/docs/integrations/adjust.mdx b/content/docs/integrations/adjust.mdx index 96d1377..a827126 100644 --- a/content/docs/integrations/adjust.mdx +++ b/content/docs/integrations/adjust.mdx @@ -51,6 +51,154 @@ Fill out the following fields and **click** the **Enable Adjust** button at the } ``` +### SDK setup + +After enabling Adjust in the dashboard, you need to pass the Adjust device ID from your app so Superwall can attribute subscription events. Without the `adjustId`, events are silently skipped. + +#### Prerequisites + +- Superwall SDK installed and configured +- Adjust SDK installed ([iOS](https://github.com/adjust/ios_sdk), [Android](https://github.com/adjust/android_sdk)) +- For iOS: `AppTrackingTransparency` and `AdSupport` frameworks linked + +#### iOS (Swift) + +Add the `NSUserTrackingUsageDescription` key to your `Info.plist` to enable IDFA access: + +```xml +NSUserTrackingUsageDescription +We use this identifier to measure ad performance and attribute subscriptions. +``` + +Then pass the Adjust device ID and IDFA to Superwall after both SDKs have initialized: + +```swift +import SuperwallKit +import AdjustSdk +import AppTrackingTransparency +import AdSupport + +func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? +) -> Bool { + // 1. Configure Superwall + Superwall.configure(apiKey: "YOUR_SUPERWALL_API_KEY") + + // 2. Configure Adjust + let adjustConfig = ADJConfig( + appToken: "YOUR_ADJUST_APP_TOKEN", + environment: ADJEnvironmentProduction + ) + Adjust.initSdk(adjustConfig!) + + // 3. Request ATT permission, then pass identifiers + ATTrackingManager.requestTrackingAuthorization { _ in + self.syncAdjustIdentifiers() + } + + return true +} + +private func syncAdjustIdentifiers() { + Adjust.adid { adid in + guard let adid else { return } + + // Required — events are skipped without this + Superwall.shared.setIntegrationAttribute(.adjustId, adid) + + // Optional — enriches attribution data on iOS + if ATTrackingManager.trackingAuthorizationStatus == .authorized { + let idfa = ASIdentifierManager.shared().advertisingIdentifier.uuidString + Superwall.shared.setUserAttributes(["idfa": idfa]) + } + } +} +``` + + + The `adjustId` is the **only required** identifier. If the user denies the ATT prompt, the IDFA will be unavailable but events will still be attributed via the Adjust device ID. + + +#### Android (Kotlin) + +Pass the Adjust device ID and GPS advertising ID to Superwall after initialization: + +```kotlin +import com.superwall.sdk.Superwall +import com.superwall.sdk.analytics.IntegrationAttribute +import com.adjust.sdk.Adjust +import com.google.android.gms.ads.identifier.AdvertisingIdClient + +// After Superwall.configure() and Adjust.initSdk() + +Adjust.getAdid { adid -> + if (adid != null) { + // Required — events are skipped without this + Superwall.instance.setIntegrationAttributes( + mapOf(IntegrationAttribute.ADJUST_ID to adid) + ) + } +} + +// Optional — enriches attribution on Android +// Must be called off the main thread +lifecycleScope.launch(Dispatchers.IO) { + try { + val adInfo = AdvertisingIdClient.getAdvertisingIdInfo(applicationContext) + if (!adInfo.isLimitAdTrackingEnabled) { + Superwall.instance.setUserAttributes( + mapOf("gps_adid" to adInfo.id) + ) + } + } catch (e: Exception) { + // Advertising ID not available + } +} +``` + +#### Flutter (Dart) + +```dart +import 'package:superwallkit_flutter/superwallkit_flutter.dart'; +import 'package:adjust_sdk/adjust.dart'; + +// After Superwall.configure() and Adjust.initSdk() + +final adid = await Adjust.getAdid(); +if (adid != null) { + await Superwall.shared.setIntegrationAttribute( + IntegrationAttribute.adjustId, + adid, + ); +} +``` + +#### Expo / React Native + +```tsx +import { useUser } from "expo-superwall"; +import { Adjust } from "react-native-adjust"; + +// Inside your component, after Superwall is configured +const { setIntegrationAttributes } = useUser(); + +// After Adjust has initialized +Adjust.getAdid((adid) => { + if (adid) { + setIntegrationAttributes({ adjustId: adid }); + } +}); +``` + +#### Identifier reference + +| Identifier | How to set | Required | +|------------|-----------|----------| +| `adjustId` | `setIntegrationAttribute(.adjustId, adid)` | **Yes** — events are skipped without it | +| `idfa` (iOS) | `setUserAttributes(["idfa": idfa])` | No — enriches iOS attribution | +| `gps_adid` (Android) | `setUserAttributes(["gps_adid": gpsAdId])` | No — enriches Android attribution | + ### Event mapping Superwall events are transformed into Adjust event names using the standard mapper: diff --git a/content/docs/ios/sdk-reference/setIntegrationAttributes.mdx b/content/docs/ios/sdk-reference/setIntegrationAttributes.mdx index 91e8840..9bd9a22 100644 --- a/content/docs/ios/sdk-reference/setIntegrationAttributes.mdx +++ b/content/docs/ios/sdk-reference/setIntegrationAttributes.mdx @@ -59,9 +59,16 @@ print("Current attributes: \(attributes)") ## IntegrationAttribute Types Common integration attributes include: +- `.adjustId` - Adjust device ID (required for Adjust integration) +- `.amplitudeDeviceId` - Amplitude device ID - `.amplitudeUserId` - Amplitude user ID +- `.appsflyerId` - AppsFlyer user ID +- `.brazeAliasName` - Braze alias name +- `.brazeAliasLabel` - Braze alias label - `.mixpanelDistinctId` - Mixpanel distinct ID +- `.firebaseAppInstanceId` - Firebase app instance ID - `.firebaseInstallationId` - Firebase installation ID (4.10.8+) +- `.clevertapId` - CleverTap user ID - `.appstackId` - Appstack identifier (4.12.11+) - `.custom(String)` - Custom attribute key