Skip to content

Commit dce09a8

Browse files
committed
Merge flow-builder: iOS v4 attribution/setIntegrationIdentifier breaking change + CocoaPods removal
2 parents 5ba016f + ecbf057 commit dce09a8

11 files changed

Lines changed: 126 additions & 80 deletions
130 KB
Loading
130 KB
Loading

src/content/docs/ios/ios-sdk-call-order.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ If you have the customer user ID at app launch, pass it into `activate()` direct
2525
| 1 | Initialize your MMP or analytics SDK (AppsFlyer, Adjust, PostHog, Branch) | App launch, first | Wait for the MMP's UID callback, for example `getAppsFlyerUID`. |
2626
| 2a | `Adapty.activate(with: config)` with `customerUserId` set on the config | App launch, after step 1, if you have the customer user ID | Recommended. No anonymous profile is ever created. |
2727
| 2b | `Adapty.activate(with: config)` without `customerUserId` | App launch, after step 1, if you don't have the customer user ID (or never collect one) | Adapty creates an anonymous profile. |
28-
| 3 | `Adapty.setIntegrationIdentifier(key:value:)` for each MMP | After step 2, before any user-action call | Required so MMP IDs land on the correct profile. |
28+
| 3 | `Adapty.setIntegrationIdentifier(...)` for each MMP | After step 2, before any user-action call | Required so MMP IDs land on the correct profile. |
2929
| 4 | `try await Adapty.identify("YOUR_USER_ID")` | After step 3 (or step 2 if no MMP), before step 5 — only on path 2b with authentication | Always `await`. Concurrent calls during `identify` produce `#3006 profileWasChanged`. |
3030
| 5 | `getPaywall`, `getPaywallProducts`, `restorePurchases`, `makePurchase`, `updateAttribution`, `updateProfile` | After step 4 if you call `identify`; otherwise after step 3 (or step 2 if no MMP) | These calls need a stable profile. |
3131

src/content/docs/ios/migration-to-ios-sdk-v4.mdx

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ Adapty iOS SDK 4.0 (beta) introduces flows and renames the paywall APIs accordin
2020
| `.paywall()` (SwiftUI modifier) | `.flow()` |
2121
| `AdaptyPaywallView` | `AdaptyFlowView` |
2222
| `didFailRenderingWith:` / `didFailRendering:` | `didReceiveError:` |
23+
| `Adapty.updateAttribution(_:source:)` (`source: String`) | `Adapty.updateAttribution(_:source:)` (`source: AdaptyAttributionSource`) |
24+
| `Adapty.setIntegrationIdentifier(key:value:)` | `Adapty.setIntegrationIdentifier(_:)` (`AdaptyIntegrationIdentifier`) |
25+
26+
## Installation: CocoaPods no longer supported
27+
28+
Adapty iOS SDK 4.0 drops CocoaPods support. Install the SDK with [Swift Package Manager](sdk-installation-ios#install-adapty-sdk).
29+
30+
If your project still uses CocoaPods, remove the `Adapty` and `AdaptyUI` pods from your `Podfile`, run `pod install` to clean them up, then add the package in Xcode via **File → Add Package Dependency** using `https://github.com/adaptyteam/AdaptySDK-iOS.git`.
2331

2432
## Removed APIs
2533

@@ -221,3 +229,55 @@ Two changes affect every existing call site:
221229
+ case remote(url: URL, preview: AdaptyUICustomImageAsset?, resolution: CGSize?)
222230
+ case player(item: AVPlayerItem, player: AVPlayer, preview: AdaptyUICustomImageAsset?, resolution: CGSize?)
223231
```
232+
233+
## Attribution and integration identifiers
234+
235+
### updateAttribution(_:source:)
236+
237+
The `source` parameter changes from `String` to the new `AdaptyAttributionSource` type, and the previously nested `AdaptyProfile.AttributionSource` is renamed to the top-level `AdaptyAttributionSource`. Use one of the predefined sources, or pass a string literal for any other source — `AdaptyAttributionSource` conforms to `ExpressibleByStringLiteral`, so existing string-literal calls keep compiling.
238+
239+
```diff showLineNumbers
240+
- try await Adapty.updateAttribution(attribution, source: "adjust")
241+
+ try await Adapty.updateAttribution(attribution, source: .adjust)
242+
```
243+
244+
Predefined sources: `.appleAds`, `.adjust`, `.appsflyer`, `.branch`, `.tenjin`. If you keep the source in a `String` variable, wrap it: `AdaptyAttributionSource(rawValue: yourSource)`.
245+
246+
### setIntegrationIdentifier(_:)
247+
248+
`setIntegrationIdentifier(key:value:)` is replaced by a variadic method that takes one or more `AdaptyIntegrationIdentifier` values. Use the predefined factory methods instead of raw string keys:
249+
250+
```diff showLineNumbers
251+
- try await Adapty.setIntegrationIdentifier(key: "appsflyer_id", value: uid)
252+
+ try await Adapty.setIntegrationIdentifier(.appsflyerId(uid))
253+
```
254+
255+
You can set several identifiers in a single call:
256+
257+
```swift showLineNumbers
258+
try await Adapty.setIntegrationIdentifier(
259+
.appsflyerId(uid),
260+
.adjustDeviceId(adid)
261+
)
262+
```
263+
264+
Replace each old key string with its factory method:
265+
266+
| v3 key | v4 factory |
267+
|---|---|
268+
| `"adjust_device_id"` | `.adjustDeviceId(_:)` |
269+
| `"airbridge_device_id"` | `.airbridgeDeviceId(_:)` |
270+
| `"amplitude_user_id"` | `.amplitudeUserId(_:)` |
271+
| `"amplitude_device_id"` | `.amplitudeDeviceId(_:)` |
272+
| `"appmetrica_device_id"` | `.appmetricaDeviceId(_:)` |
273+
| `"appmetrica_profile_id"` | `.appmetricaProfileId(_:)` |
274+
| `"appsflyer_id"` | `.appsflyerId(_:)` |
275+
| `"branch_id"` | `.branchId(_:)` |
276+
| `"facebook_anonymous_id"` | `.facebookAnonymousId(_:)` |
277+
| `"firebase_app_instance_id"` | `.firebaseAppInstanceId(_:)` |
278+
| `"mixpanel_user_id"` | `.mixpanelUserId(_:)` |
279+
| `"one_signal_subscription_id"` | `.oneSignalSubscriptionId(_:)` |
280+
| `"one_signal_player_id"` | `.oneSignalPlayerId(_:)` |
281+
| `"posthog_distinct_user_id"` | `.posthogDistinctUserId(_:)` |
282+
| `"pushwoosh_hwid"` | `.pushwooshHWID(_:)` |
283+
| `"tenjin_analytics_installation_id"` | `.tenjinAnalyticsInstallationId(_:)` |

src/content/docs/version-3.0/adjust.mdx

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -141,20 +141,24 @@ For Adjust version 5.0 or later, use the following example:
141141

142142
```swift showLineNumbers
143143
class AdjustModuleImplementation {
144-
145-
func updateAdjustAdid() {
146-
Adjust.adid { adid in
147-
guard let adid else { return }
148-
Adapty.setIntegrationIdentifier(key: "adjust_device_id", value: adid)
144+
func updateAdjustAdid() {
145+
Adjust.adid { adid in
146+
guard let adid else { return }
147+
// Adapty SDK 4.x
148+
Adapty.setIntegrationIdentifier(.adjustDeviceId(adid))
149+
// Adapty SDK 3.x
150+
Adapty.setIntegrationIdentifier(key: "adjust_device_id", value: adid)
151+
}
149152
}
150-
}
151-
func updateAdjustAttribution() {
152-
Adjust.attribution { attribution in
153-
guard let attribution = attribution?.dictionary() else {
154-
return
153+
154+
func updateAdjustAttribution() {
155+
Adjust.attribution { attribution in
156+
guard let attribution = attribution?.dictionary() else { return }
157+
// Adapty SDK 4.x
158+
Adapty.updateAttribution(attribution, source: .adjust)
159+
// Adapty SDK 3.x
160+
Adapty.updateAttribution(attribution, source: "adjust")
155161
}
156-
157-
Adapty.updateAttribution(attribution, source: "adjust")
158162
}
159163
}
160164
```

src/content/docs/version-3.0/appsflyer.mdx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,10 @@ class YourAppsFlyerLibDelegateImplementation {
181181
// and update onConversionDataSuccess method:
182182
func onConversionDataSuccess(_ conversionInfo: [AnyHashable : Any]) {
183183
let uid = AppsFlyerLib.shared().getAppsFlyerUID()
184+
// Adapty SDK 4.x
185+
Adapty.setIntegrationIdentifier(.appsflyerId(uid))
186+
Adapty.updateAttribution(conversionInfo, source: .appsflyer)
187+
// Adapty SDK 3.x
184188
Adapty.setIntegrationIdentifier(key: "appsflyer_id", value: uid)
185189
Adapty.updateAttribution(conversionInfo, source: "appsflyer")
186190
}

src/content/docs/version-3.0/branch.mdx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ Adapty will send subscription events to Branch using a server-to-server integrat
9494

9595
```swift showLineNumbers
9696
do {
97+
// Adapty SDK 4.x
98+
try await Adapty.setIntegrationIdentifier(.branchId(<BRANCH_IDENTITY_ID>))
99+
// Adapty SDK 3.x
97100
try await Adapty.setIntegrationIdentifier(
98101
key: "branch_id",
99102
value: <BRANCH_IDENTITY_ID>
@@ -156,12 +159,14 @@ Adapty will send subscription events to Branch using a server-to-server integrat
156159
// Pass the attribution you receive from the initializing method of Branch iOS SDK to Adapty.
157160
Branch.getInstance().initSession(launchOptions: launchOptions) { (data, error) in
158161
if let data {
162+
// Adapty SDK 4.x
159163
Adapty.updateAttribution(data, source: .branch)
164+
// Adapty SDK 3.x
165+
Adapty.updateAttribution(data, source: "branch")
160166
}
161167
}
162168
}
163169
}
164-
165170
```
166171
</TabItem>
167172
<TabItem value="kotlin" label="Android (Kotlin)" default>

src/content/docs/version-3.0/onesignal.mdx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,9 @@ Make sure to send `playerId` (for OneSignal SDK pre-v5) or `subscriptionId` (for
147147
// SubscriptionID
148148
OneSignal.Notifications.requestPermission({ accepted in
149149
Task {
150+
// Adapty SDK 4.x
151+
try await Adapty.setIntegrationIdentifier(.oneSignalSubscriptionId(OneSignal.User.pushSubscription.id))
152+
// Adapty SDK 3.x
150153
try await Adapty.setIntegrationIdentifier(
151154
key: "one_signal_subscription_id",
152155
value: OneSignal.User.pushSubscription.id
@@ -255,6 +258,9 @@ OneSignal.User.pushSubscription.addEventListener('change', (subscription) => {
255258
func onOSSubscriptionChanged(_ stateChanges: OSSubscriptionStateChanges) {
256259
if let playerId = stateChanges.to.userId {
257260
Task {
261+
// Adapty SDK 4.x
262+
try await Adapty.setIntegrationIdentifier(.oneSignalPlayerId(playerId))
263+
// Adapty SDK 3.x
258264
try await Adapty.setIntegrationIdentifier(
259265
key: "one_signal_player_id",
260266
value: playerId

src/content/docs/version-3.0/paywall-device-compatibility-preview.mdx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,30 @@ metadataTitle: "Previewing Flow Device Compatibility | Adapty Docs"
55
keywords: ['ipad', 'ipad view', 'preview']
66
---
77

8+
You have two ways to preview your flow on different screen types:
9+
- **Preview on devices**: Check how your flow looks on real devices at any stage of development.
10+
- **Preview in the Adapty dashboard**: Preview your flow while designing it.
11+
12+
## Preview on devices
13+
14+
To preview your flow on a real device:
15+
16+
1. [Download the Adapty app from the App Store](https://apps.apple.com/us/app/adapty/id6739359219).
17+
2. In the flow builder, click **Test on device**.
18+
19+
<ZoomImage id="flow-test-on-device.webp" width="700px" alt="Test on device button in the flow builder" />
20+
21+
3. Select the flow locale.
22+
4. Scan the QR code with the device camera or open the link. This opens your flow in the Adapty mobile app.
23+
24+
:::note
25+
In the test mode, Adapty can't access your products in stores, so the prices displayed in the flow are not real.
26+
:::
27+
28+
<ZoomImage id="flow-test-on-device-qr.webp" width="400px" alt="Locale selector and QR code in the Test on device dialog" />
29+
30+
## Preview in the Adapty dashboard
31+
832
You can preview your flow on different screen types using the preview area in the flow builder. This helps ensure your flow looks great across various devices and screen sizes.
933

1034
Using the preview controls below the preview, you can:

src/content/docs/version-3.0/sdk-installation-ios.mdx

Lines changed: 3 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,7 @@ Adapty SDK 3.15.7+ is required when building with Xcode 26.4 or later.
5656

5757
[![Release](https://img.shields.io/github/v/release/adaptyteam/AdaptySDK-iOS.svg?style=flat&logo=apple)](https://github.com/adaptyteam/AdaptySDK-iOS/releases)
5858

59-
<Tabs>
60-
<TabItem value="spm" label="Swift Package Manager (recommended)" default>
61-
In Xcode, go to **File** -> **Add Package Dependency...**. Note that the steps to add package dependencies may vary between Xcode versions, so refer to Xcode documentation if needed.
59+
Adapty SDK is installed via Swift Package Manager. In Xcode, go to **File** -> **Add Package Dependency...**. Note that the steps to add package dependencies may vary between Xcode versions, so refer to Xcode documentation if needed.
6260

6361
1. Enter the repository URL:
6462
```
@@ -76,36 +74,10 @@ In Xcode, go to **File** -> **Add Package Dependency...**. Note that the steps t
7674
4. Click **Add Package** to complete the installation.
7775
5. **Verify installation:** In your project navigator, you should see "Adapty" (and "AdaptyUI" if selected) under **Package Dependencies**.
7876

79-
</TabItem>
80-
81-
<TabItem value="cocoapods" label="CocoaPods (legacy)" default>
82-
83-
:::info
84-
85-
CocoaPods is now in maintenance mode, with development officially stopped. We recommend switching to [Swift Package Manager](sdk-installation-ios#install-adapty-sdk).
86-
77+
:::important
78+
Adapty iOS SDK 4.0 is a pre-release. Swift Package Manager does not resolve beta versions through the **Up to Next Major Version** (`from:`) rule, so you must pin the exact version. In Xcode, set the **Dependency Rule** to **Exact Version** and enter `4.0.0-beta.1`. In `Package.swift`, use `.exact("4.0.0-beta.1")`. See [Migrate Adapty iOS SDK to v4](migration-to-ios-sdk-v4).
8779
:::
8880

89-
1. Add Adapty to your `Podfile`. Choose the modules you need:
90-
91-
1. **Adapty** is the mandatory module.
92-
2. **AdaptyUI** is an optional module you need if you plan to use the [Adapty Paywall Builder](adapty-paywall-builder).
93-
94-
```shell showLineNumbers title="Podfile"
95-
pod 'Adapty'
96-
pod 'AdaptyUI' # optional module needed only for Paywall Builder
97-
```
98-
99-
2. Run:
100-
101-
```sh showLineNumbers title="Shell"
102-
pod install
103-
```
104-
105-
This will create a `.xcworkspace` file for your app. Use this file for all future development.
106-
</TabItem>
107-
</Tabs>
108-
10981
## Activate Adapty module of Adapty SDK
11082

11183
Activate the Adapty SDK in your app code.
@@ -401,38 +373,3 @@ targetSettings: [
401373
"AdaptyUIBuilder": .init().swiftVersion("6"),
402374
]
403375
```
404-
405-
#### Swift 6 build errors caused by Podfile SWIFT_VERSION override
406-
407-
When building for iOS with [CocoaPods](sdk-installation-ios#install-adapty-sdk), you may see Swift 6 compilation errors on Adapty pod targets. Typical symptoms include `@Sendable` mismatches in `AdaptyUIBuilderLogic`, missing `Sendable` conformance on Adapty types, or actor isolation errors.
408-
409-
The Adapty pods declare `s.swift_version = '6.0'` and require Swift 6 to build. Your own app code can stay on Swift 5 — only the Adapty pod targets (`Adapty`, `AdaptyUI`, `AdaptyUIBuilder`, `AdaptyLogger`) need to build with Swift 6.
410-
411-
The most common cause is a `post_install` hook in your `Podfile` that rewrites `SWIFT_VERSION` for every pod target:
412-
413-
```ruby showLineNumbers title="Podfile"
414-
post_install do |installer|
415-
installer.pods_project.targets.each do |target|
416-
target.build_configurations.each do |config|
417-
config.build_settings['SWIFT_VERSION'] = '5.9'
418-
end
419-
end
420-
end
421-
```
422-
423-
**Fix**: Exclude the Adapty pod targets from the override:
424-
425-
```ruby showLineNumbers title="Podfile"
426-
post_install do |installer|
427-
installer.pods_project.targets.each do |target|
428-
next if %w[Adapty AdaptyUI AdaptyUIBuilder AdaptyLogger].include?(target.name)
429-
target.build_configurations.each do |config|
430-
config.build_settings['SWIFT_VERSION'] = '5.9'
431-
end
432-
end
433-
end
434-
```
435-
436-
Then run `pod install` and rebuild.
437-
438-
To verify, open `Pods.xcodeproj`, select the `Adapty` pod target → **Build Settings****Swift Language Version**. It should be **Swift 6**.

0 commit comments

Comments
 (0)