Migrate iOS SDK to V7

Before you begin

This guide walks you through migrating your iOS app from AppsFlyer SDK 6 to SDK 7. SDK 7 introduces a new session control model, removes several deprecated APIs, and aligns iOS behavior with Android. Use this guide to identify what you need to change, understand why each change was made, and update your integration in the right order.

📘

Note

The vast majority of AppsFlyerLib methods remain unchanged between SDK 6 and SDK 7. This guide covers only the changes you need to make. You don't need to rewrite your integration from scratch.

SDK 6 support policy

SDK 6 continues to be supported, but only for critical fixes. All new features are planned for SDK 7 only. We recommend migrating as soon as possible to stay current with new capabilities.

What to expect

  • Low risk: method renames in link generation and event logging — update call sites, no logic changes.
  • Medium risk: delegate migration and parameter type changes — replace callbacks and update method signatures.
  • High risk: session readiness initialization pattern — if not handled correctly, the SDK will not start.

Estimated migration time: 1–4 hours, depending on your app's complexity and use of removed APIs.


The iOS SDK 7 session model

The SDK 7 gives you control over when to start the first session. In SDK 6, the session started automatically. The SDK would fire a session as soon as the app called start() in the didBecomeActive lifecycle. In SDK 7, session startup is explicit: you call start inside a registerSessionReadyListener callback when your app is ready.

This change addresses a real-world need. Many iOS apps must complete steps before sending a launch event to AppsFlyer — for example, requesting ATT authorization, collecting CMP consent, or retrieving a customer user ID.

SDK 7 also tightens initialization: appsFlyerDevKey and appleAppID are now read-only properties. Credentials must be set exactly once using initialize(devKey:appId:), preventing accidental re-initialization.


Upgrade checklist

Work through these in order — higher-risk changes first. The Risk column tells you whether skipping a step causes a compile error (caught at build time) or a silent regression (compiles but misbehaves at runtime).

#ActionRiskSection
High-risk changes
1Replace direct assignments to appsFlyerDevKey and appleAppID with initialize(devKey:appId:). Call it before any other SDK call.Compile error§1
2Remove onAppOpenAttribution and onAppOpenAttributionFailure from your AppsFlyerLibDelegate. Migrate to AppsFlyerDeepLinkDelegate.didResolveDeepLink.Compile error§3
3Replace waitForATTUserAuthorization(timeoutInterval:) with registerSessionReadyListener. Call start inside the listener block if you're starting the SDK only after collecting ATT consent from the user.Compile error§2
4Swap setHost arguments: rename to setHost(_:hostName:), reverse order — prefix first, host name second.Silent regression§5
5Set deepLinkDelegate before start fires.Silent regression§3
6Call handleLaunchOptions before registering the listener (Universal Links only).Silent regression§2
Helper class updates
7generateInviteUrl(linkGenerator:)generateInviteLink(linkGenerator:). Add the Error handler to the completion block.Compile error§8
8logInvite(_:parameters:)logInvite(_:eventParameters:).Compile error§8
9Update logCrossPromoteImpression: appID:appId:, parameters:userParams:.Compile error§9
10Update logAndOpenStore: appID:promotedAppId:, parameters:userParams:.Compile error§9
11Update AppsFlyerLinkGenerator: remove setAppleAppID and setDeeplinkPath; setReferrerImageURLsetReferrerImageUrl; setBaseDeeplinksetBaseDeepLink; addParametersaddUserParams.Compile error§10
Deprecated API removals
12Replace the 6-parameter validateAndLogInAppPurchase with validateAndLogInAppPurchase(purchaseDetails:purchaseAdditionalDetails:) using AFSDKPurchaseDetails.Compile error§6
13Replace setSharingFilterForAllPartners with setSharingFilterForPartners(["all"]).Compile error§7
Renames
14getSDKVersiongetSdkVersion.Compile error§11
15Update Swift: appendParametersToDeeplinkURLappendParametersToDeepLinkingURL.Compile error (Swift)§11
16Update Swift: setPartnerData(partnerId:partnerInfo:)setPartnerData(partnerId:data:).Compile error (Swift)§11
17Update Swift: DeepLinkDelegateAppsFlyerDeepLinkDelegate.Compile error (Swift)§4
Optional
18Add AppsFlyerLibConfig.plist for constant SDK configuration values.-Part 2

Part 1: Breaking changes

The following changes will cause compile errors — or, in one case, a silent runtime regression — if not addressed. Work through them in the order below.

1. Initialize credentials

What changed: appsFlyerDevKey and appleAppID are now read-only. You can no longer assign to them directly. Instead, call initialize(devKey:appId:) once before any other SDK call. KVC paths that write to these properties fail silently at runtime.

Compile error: Existing code breaks on upgrade

📘

Note

For SDK-level configuration (debug mode, currency, identifier collection, SKAdNetwork, custom host), you can use AppsFlyerLibConfig.plist instead of code. See Part 2 for details.

// 6.x - DO NOT use in 7.0
[AppsFlyerLib shared].appsFlyerDevKey = @"YOUR_DEV_KEY";
[AppsFlyerLib shared].appleAppID = @"123456789";

// 7.0
[[AppsFlyerLib shared] initWithDevKey:@"YOUR_DEV_KEY" appleAppId:@"123456789"];
// 6.x - DO NOT use in 7.0
AppsFlyerLib.shared().appsFlyerDevKey = "YOUR_DEV_KEY"
AppsFlyerLib.shared().appleAppID = "123456789"

// 7.0
AppsFlyerLib.shared().initialize(devKey: "YOUR_DEV_KEY", appId: "123456789")

2. Call start with the session readiness listener

This is the most significant change in SDK 7. You must call registerSessionReadyListener before calling start. Call start inside the listener block. The listener fires once per foreground cycle when the SDK is ready to start.

waitForATTUserAuthorization(timeoutInterval:) is deprecated and no longer controls when start fires — the SDK no longer manages ATT timing internally.

If your app supports Universal Links, call handleLaunchOptions before registering the listener. This registers cold-launch deep link context so the listener can wait for deep link resolution before firing.

Call start without preconditions

Use this if your app has no pre-start conditions.

// 6.x - DO NOT use in 7.0
[[AppsFlyerLib shared] waitForATTUserAuthorizationWithTimeoutInterval:60];
[[AppsFlyerLib shared] start];

// 7.0
- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    [[AppsFlyerLib shared] initWithDevKey:@"YOUR_DEV_KEY" appleAppId:@"123456789"];

    // Optional - only needed if supporting Universal Links
    [[AppsFlyerLib shared] handleLaunchOptions:launchOptions];

    [[AppsFlyerLib shared] registerSessionReadyListener:^{
        // Collect ATT here if required before start
        [[AppsFlyerLib shared] start];
    }];
    return YES;
}
// 6.x - DO NOT use in 7.0
AppsFlyerLib.shared().waitForATTUserAuthorization(timeoutInterval: 60)
AppsFlyerLib.shared().start()

// 7.0
func application(_ application: UIApplication,
                 didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    AppsFlyerLib.shared().initialize(devKey: "YOUR_DEV_KEY", appId: "123456789")

    // Optional - only needed if supporting Universal Links
    AppsFlyerLib.shared().handleLaunchOptions(launchOptions)

    AppsFlyerLib.shared().registerSessionReadyListener {
        // Collect ATT here if required before start
        AppsFlyerLib.shared().start()
    }
    return true
}

Readiness conditions:

  • devKey and appleAppID must be set before the listener fires.
  • If a Universal Link is present at cold launch, the SDK waits for deep link resolution (with a bounded timeout; the listener always fires).

Call start with preconditions

If start must wait for both SDK readiness and your consent flow (CMP, ATT, or a custom gate), use a lightweight coordinator. Each side sets a flag independently — the SDK when the listener fires, your app when the consent flow completes — and start is called only when both are set.

// AppDelegate.m
@interface AppDelegate ()
@property (nonatomic) BOOL consentGranted;
@property (nonatomic) BOOL sdkReady;
@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    [[AppsFlyerLib shared] initWithDevKey:@"YOUR_DEV_KEY" appleAppId:@"123456789"];
    [[AppsFlyerLib shared] handleLaunchOptions:launchOptions];

    __weak typeof(self) weakSelf = self;
    [[AppsFlyerLib shared] registerSessionReadyListener:^{
        weakSelf.sdkReady = YES;
        [weakSelf startIfReady];
    }];

    // Trigger your CMP / ATT flow here.
    // When it completes, set:
    //   self.consentGranted = YES;
    //   [self startIfReady];

    return YES;
}

- (void)startIfReady {
    if (self.consentGranted && self.sdkReady) {
        [[AppsFlyerLib shared] start];
        self.sdkReady = NO; // prevent duplicate starts in the same cycle
    }
}

@end
class AppDelegate: UIResponder, UIApplicationDelegate {

    private var consentGranted = false
    private var sdkReady = false

    func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        AppsFlyerLib.shared().initialize(devKey: "YOUR_DEV_KEY", appId: "123456789")
        AppsFlyerLib.shared().handleLaunchOptions(launchOptions)

        AppsFlyerLib.shared().registerSessionReadyListener { [weak self] in
            self?.sdkReady = true
            self?.startIfReady()
        }

        // Trigger your CMP / ATT flow here.
        // When it completes, call:
        //   consentGranted = true
        //   startIfReady()

        return true
    }

    private func startIfReady() {
        guard consentGranted, sdkReady else { return }
        AppsFlyerLib.shared().start()
        sdkReady = false
    }
}

SwiftUI — use @UIApplicationDelegateAdaptor to wire the same AppDelegate:

@main
struct MyApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

    var body: some Scene {
        WindowGroup { ContentView() }
    }
}

Unregistering

// Objective-C
[[AppsFlyerLib shared] unregisterSessionReadyListener];
// Swift
AppsFlyerLib.shared().unregisterSessionReadyListener()

Check session readiness

isSessionReady returns YES (true in Swift) once the session-ready listener has fired in the current foreground cycle. Use it to check readiness status from code paths that execute outside the listener callback — for example, deferred logic that runs after the initial startup sequence.

No SDK 6 equivalent.

BOOL ready = [[AppsFlyerLib shared] isSessionReady];
let ready = AppsFlyerLib.shared().isSessionReady()

3. Migrate to the deep link delegate

What changed: onAppOpenAttribution: and onAppOpenAttributionFailure: have been removed from AppsFlyerLibDelegate. Migrate to AppsFlyerDeepLinkDelegate.didResolveDeepLink, which provides equivalent data via AppsFlyerDeepLinkResult.

Compile error: Existing code breaks on upgrade

// 6.x - remove these from your AppsFlyerLibDelegate conformance
- (void)onAppOpenAttribution:(NSDictionary *)attributionData {
    // handle attribution data
}

- (void)onAppOpenAttributionFailure:(NSError *)error {
    // handle error
}

// 7.0 - conform to AppsFlyerDeepLinkDelegate instead
- (void)didResolveDeepLink:(AppsFlyerDeepLinkResult *)result {
    if (result.status == AFSDKDeepLinkResultStatusFound) {
        NSDictionary *deepLinkData = result.deepLink.clickEvent;
        // handle attribution data
    } else if (result.status == AFSDKDeepLinkResultStatusFailure) {
        NSError *error = result.error;
        // handle error
    }
}
// 6.x - remove these from your AppsFlyerLibDelegate conformance
func onAppOpenAttribution(_ attributionData: [AnyHashable: Any]) { }
func onAppOpenAttributionFailure(_ error: Error) { }

// 7.0 - conform to AppsFlyerDeepLinkDelegate instead
func didResolveDeepLink(_ result: DeepLinkResult) {
    switch result.status {
    case .found:
        let deepLinkData = result.deepLink?.clickEvent
        // handle attribution data
    case .failure:
        let error = result.error
        // handle error
    case .notFound:
        break
    }
}

Assign the delegate before calling start:

// Objective-C
[AppsFlyerLib shared].deepLinkDelegate = self;
// Swift
AppsFlyerLib.shared().deepLinkDelegate = self

Swift type names for the deep link result

The Swift implementation of didResolveDeepLink uses renamed types — here's the mapping from the Objective-C API:

  • AppsFlyerDeepLinkResult is exposed to Swift as DeepLinkResult (NS_SWIFT_NAME(DeepLinkResult)).
  • AFSDKDeepLinkResultStatus is exposed as DeepLinkResultStatus; switch cases are .found, .failure, and .notFound.
  • The deepLink property on DeepLinkResult is of type DeepLink (NS_SWIFT_NAME(DeepLink)).
  • clickEvent is a direct property on DeepLink — not a nested call.

4. Update the deep link delegate name in Swift

What changed: DeepLinkDelegateAppsFlyerDeepLinkDelegate (Swift name, NS_SWIFT_NAME). ObjC code compiles unchanged. Swift code that references the old name fails to compile.

// 6.x
class MyDeepLinkHandler: DeepLinkDelegate {
    func didResolveDeepLink(_ result: AppsFlyerDeepLinkResult) { }
}

// 7.0
class MyDeepLinkHandler: AppsFlyerDeepLinkDelegate {
    func didResolveDeepLink(_ result: AppsFlyerDeepLinkResult) { }
}

Assignment to deepLinkDelegate is unaffected in both languages.


5. Swap the host method argument order

What changed: The method was renamed from setHost(_:withHostPrefix:) to setHost(_:hostName:), and the argument order was reversed to align with the Android SDK. The first argument is now the host prefix; the second is the host name.

If you don't swap the arguments, the code compiles without errors but routes traffic to the wrong host, causing a silent runtime regression.

// 6.x - host first, prefix second
[[AppsFlyerLib shared] setHost:@"example.com" withHostPrefix:@"custom"];

// 7.0 - prefix first, host second
[[AppsFlyerLib shared] setHost:@"custom" hostName:@"example.com"];
// 6.x
AppsFlyerLib.shared().setHost("example.com", withHostPrefix: "custom")

// 7.0
AppsFlyerLib.shared().setHost("custom", hostName: "example.com")

6. Switch to the purchase details object

What changed: The 6-parameter validateAndLogInAppPurchase signature has been removed. Use validateAndLogInAppPurchase(purchaseDetails:purchaseAdditionalDetails:) with an AFSDKPurchaseDetails object.

Compile error: Existing code breaks on upgrade

// 6.x - DO NOT use in 7.0
[[AppsFlyerLib shared] validateAndLogInAppPurchase:@"product_id"
                                             price:@"9.99"
                                          currency:@"USD"
                                     transactionId:@"txn_123"
                              additionalParameters:nil
                                           success:^(NSDictionary *result) {}
                                           failure:^(NSError *error, id response) {}];

// 7.0
AFSDKPurchaseDetails *details = [[AFSDKPurchaseDetails alloc]
    initWithProductId:@"product_id"
        transactionId:@"txn_123"
         purchaseType:AFSDKPurchaseTypeOneTimePurchase];
[[AppsFlyerLib shared] validateAndLogInAppPurchase:details
                         purchaseAdditionalDetails:nil
                                        completion:^(NSDictionary *response, NSError *error) {}];
// 6.x - DO NOT use in 7.0
AppsFlyerLib.shared().validateAndLogInAppPurchase(
    "product_id", price: "9.99", currency: "USD",
    transactionId: "txn_123", additionalParameters: nil,
    success: { _ in }, failure: { _, _ in }
)

// 7.0
let details = AFSDKPurchaseDetails(productId: "product_id",
                                   transactionId: "txn_123",
                                   purchaseType: .oneTimePurchase)
AppsFlyerLib.shared().validateAndLogInAppPurchase(
    purchaseDetails: details,
    purchaseAdditionalDetails: nil
) { response, error in }

7. Remove the all-partners sharing filter

What changed: This method was deprecated in 6.4.0 and has been removed in 7.0. Pass ["all"] to setSharingFilterForPartners to prevent data sharing with all partners.

Compile error: Existing code breaks on upgrade

// 6.x - DO NOT use in 7.0
[[AppsFlyerLib shared] setSharingFilterForAllPartners];

// 7.0
[[AppsFlyerLib shared] setSharingFilterForPartners:@[@"all"]];
// 6.x - DO NOT use in 7.0
AppsFlyerLib.shared().setSharingFilterForAllPartners()

// 7.0
AppsFlyerLib.shared().setSharingFilterForPartners(["all"])

8. Update ShareInviteHelper method signatures

Rename the invite link method

What changed: The method is renamed (UrlLink), and the completion handler gains an NSError * parameter. Update your handler to accept both url and error. A signature mismatch is a compile error in both Objective-C and Swift.

// 6.x
[AppsFlyerShareInviteHelper generateInviteUrlWithLinkGenerator:^AppsFlyerLinkGenerator *(AppsFlyerLinkGenerator *gen) {
    [gen setChannel:@"email"];
    return gen;
} completionHandler:^(NSURL * _Nullable url) {
    // use url
}];

// 7.0
[AppsFlyerShareInviteHelper generateInviteLinkWithLinkGenerator:^AppsFlyerLinkGenerator *(AppsFlyerLinkGenerator *gen) {
    [gen setChannel:@"email"];
    return gen;
} completionHandler:^(NSURL * _Nullable url, NSError * _Nullable error) {
    if (error) { /* handle */ return; }
    // use url
}];
// 6.x
AppsFlyerShareInviteHelper.generateInviteUrl(linkGenerator: { gen in
    gen.setChannel("email")
    return gen
}) { url in
    // use url
}

// 7.0
AppsFlyerShareInviteHelper.generateInviteLink(linkGenerator: { gen in
    gen.setChannel("email")
    return gen
}) { url, error in
    if let error { /* handle */ return }
    // use url
}

Update the logInvite parameter label

What changed: parameters:eventParameters:

Compile error: Existing code breaks on upgrade

// 6.x
[AppsFlyerShareInviteHelper logInvite:@"email" parameters:@{@"af_sub1": @"val"}];

// 7.0
[AppsFlyerShareInviteHelper logInvite:@"email" eventParameters:@{@"af_sub1": @"val"}];
// 6.x
AppsFlyerShareInviteHelper.logInvite("email", parameters: ["af_sub1": "val"])

// 7.0
AppsFlyerShareInviteHelper.logInvite("email", eventParameters: ["af_sub1": "val"])

9. Update CrossPromotionHelper parameter labels

Update logCrossPromoteImpression parameter labels

What changed: appID:appId:, parameters:userParams:

Compile error: Existing code breaks on upgrade

// 6.x
[AppsFlyerCrossPromotionHelper logCrossPromoteImpression:@"123456789"
                                                campaign:@"summer"
                                              parameters:@{@"af_sub1": @"val"}];

// 7.0
[AppsFlyerCrossPromotionHelper logCrossPromoteImpression:@"123456789"
                                                campaign:@"summer"
                                              userParams:@{@"af_sub1": @"val"}];
// 6.x
AppsFlyerCrossPromotionHelper.logCrossPromoteImpression("123456789",
    campaign: "summer", parameters: ["af_sub1": "val"])

// 7.0
AppsFlyerCrossPromotionHelper.logCrossPromoteImpression("123456789",
    campaign: "summer", userParams: ["af_sub1": "val"])

Update logAndOpenStore parameter labels

What changed: appID:promotedAppId:, parameters:userParams:

Compile error: Existing code breaks on upgrade

// 6.x
[AppsFlyerCrossPromotionHelper logAndOpenStore:@"123456789"
                                      campaign:@"summer"
                                    parameters:@{@"af_sub1": @"val"}
                                     openStore:^(NSURLSession *session, NSURL *url) {}];

// 7.0
[AppsFlyerCrossPromotionHelper logAndOpenStore:@"123456789"
                                      campaign:@"summer"
                                    userParams:@{@"af_sub1": @"val"}
                                     openStore:^(NSURLSession *session, NSURL *url) {}];
// 6.x
AppsFlyerCrossPromotionHelper.logAndOpenStore("123456789",
    campaign: "summer", parameters: ["af_sub1": "val"]) { session, url in }

// 7.0
AppsFlyerCrossPromotionHelper.logAndOpenStore("123456789",
    campaign: "summer", userParams: ["af_sub1": "val"]) { session, url in }

10. Update LinkGenerator call sites

Remove two methods with no replacement

What changed: Both methods are removed with no replacement. Remove all call sites.

Compile error: Existing code breaks on upgrade

// 6.x - remove these calls entirely in 7.0
[generator setAppleAppID:@"123456789"];
[generator setDeeplinkPath:@"/product/detail"];
// 6.x - remove these calls entirely in 7.0
generator.setAppleAppID("123456789")
generator.setDeeplinkPath("/product/detail")

Remaining renames

6.x7.0Breakage
setReferrerImageURL:setReferrerImageUrl:Compile error
setBaseDeeplink:setBaseDeepLink:Compile error
addParameters:addUserParams:Compile error
// 6.x
[generator setReferrerImageURL:@"https://example.com/avatar.png"];
[generator setBaseDeeplink:@"myapp://home"];
[generator addParameters:@{@"af_sub1": @"val"}];

// 7.0
[generator setReferrerImageUrl:@"https://example.com/avatar.png"];
[generator setBaseDeepLink:@"myapp://home"];
[generator addUserParams:@{@"af_sub1": @"val"}];
// 6.x
generator.setReferrerImageURL("https://example.com/avatar.png")
generator.setBaseDeeplink("myapp://home")
generator.addParameters(["af_sub1": "val"])

// 7.0
generator.setReferrerImageUrl("https://example.com/avatar.png")
generator.setBaseDeepLink("myapp://home")
generator.addUserParams(["af_sub1": "val"])

11. Apply remaining method renames

Rename the SDK version method

What changed: getSDKVersiongetSdkVersion

Compile error: Existing code breaks on upgrade

// 6.x
NSString *version = [[AppsFlyerLib shared] getSDKVersion];

// 7.0
NSString *version = [[AppsFlyerLib shared] getSdkVersion];
// 6.x
let version = AppsFlyerLib.shared().getSDKVersion()

// 7.0
let version = AppsFlyerLib.shared().getSdkVersion()

Fix the Swift deep link URL method name

What changed: appendParametersToDeeplinkURLappendParametersToDeepLinkingURL

Compile error: Existing Swift code breaks on upgrade

// 6.x
AppsFlyerLib.shared().appendParametersToDeeplinkURL(contains: "example.com", parameters: [:])

// 7.0
AppsFlyerLib.shared().appendParametersToDeepLinkingURL(contains: "example.com", parameters: [:])

Update the partner data parameter label

What changed: partnerInfo:data:

Compile error: Existing code breaks on upgrade

// 6.x
[[AppsFlyerLib shared] setPartnerDataWithPartnerId:@"partner_int" partnerInfo:@{@"key": @"val"}];

// 7.0
[[AppsFlyerLib shared] setPartnerDataWithPartnerId:@"partner_int" data:@{@"key": @"val"}];
// 6.x
AppsFlyerLib.shared().setPartnerData(partnerId: "partner_int", partnerInfo: ["key": "val"])

// 7.0
AppsFlyerLib.shared().setPartnerData(partnerId: "partner_int", data: ["key": "val"])

Part 2: New capabilities

1. File-based SDK configuration

SDK 7 introduces an optional property list file for configuring SDK behavior without code. Add AppsFlyerLibConfig.plist to your app's main bundle. The SDK loads it automatically at initialization, before initialize(devKey:appId:) is called. If the file is missing, the SDK uses defaults. If a key is absent from the plist, its default applies. Programmatic API calls always override plist values.

Supported keys

Plist keyTypeDefaultProgrammatic equivalent
debug_modeBooleanfalseAppsFlyerLib.shared().isDebug = true
currency_codeString"USD"AppsFlyerLib.shared().currencyCode = "ILS"
disable_idfa_collectionBooleanfalseAppsFlyerLib.shared().disableAdvertisingIdentifier = true
disable_idfv_collectionBooleanfalseAppsFlyerLib.shared().disableIDFVCollection = true
disable_skadnetworkBooleanfalseAppsFlyerLib.shared().disableSKAdNetwork = true
min_time_between_sessionsInteger (seconds)30AppsFlyerLib.shared().minTimeBetweenSessions = 1
hostString""AppsFlyerLib.shared().setHost("prefix", hostName: "host.com")
prefixString""(set together with host)

Example plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
  "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>debug_mode</key>
    <true/>
    <key>currency_code</key>
    <string>USD</string>
    <key>disable_idfa_collection</key>
    <false/>
    <key>disable_idfv_collection</key>
    <false/>
    <key>disable_skadnetwork</key>
    <false/>
    <key>min_time_between_sessions</key>
    <integer>30</integer>
    <key>host</key>
    <string></string>
    <key>prefix</key>
    <string></string>
</dict>
</plist>

Adding the file to Xcode

  1. Choose File → New → File and select Property List.
  2. Name it exactly AppsFlyerLibConfig (Xcode adds .plist).
  3. Add it to your app target, not the test target.
  4. Verify it appears under Build Phases → Copy Bundle Resources.

Precedence

AppsFlyerLibConfig.plist  →  loaded at SDK init (lowest priority)
         ↓
Programmatic API calls    →  override plist values at any time (highest priority)

Any value set via the public API overwrites the corresponding plist value for the remainder of the process. On the next cold start, the plist value is loaded again.

Comparison with Android af_init_config.json file

iOSAndroid
FileAppsFlyerLibConfig.plist (main bundle)assets/af_init_config.json
FormatProperty list (XML)JSON
Loaded atAppsFlyerLib.init()AppsFlyerLib.init()
Contains credentialsNo — use initialize(devKey:appId:)No — use init(key, listener, context)
Unknown keysIgnoredIgnored (logged)

Troubleshooting

Session readiness listener never fires

Symptom: The listener block is never called, and the SDK does not start.

Causes:

  1. registerSessionReadyListener called after start instead of before.
  2. Credentials not set via initialize(devKey:appId:) before registering the listener.
  3. Universal Link configured, but handleLaunchOptions not called before listener registration.

Solution: Ensure this order is in didFinishLaunchingWithOptions::

[[AppsFlyerLib shared] initWithDevKey:@"KEY" appleAppId:@"ID"];
[[AppsFlyerLib shared] handleLaunchOptions:launchOptions]; // if using Universal Links
[[AppsFlyerLib shared] registerSessionReadyListener:^{ /* call start here */ }];

Silent deep link failure in foreground

Symptom: didResolveDeepLink is called but result.status is .failure even though the link is valid.

Causes:

  1. handleLaunchOptions not called in didFinishLaunchingWithOptions: for cold-launch links.
  2. AppsFlyerDeepLinkDelegate set after start fires.

Solution: Set the delegate before calling start:

[AppsFlyerLib shared].deepLinkDelegate = self;
[[AppsFlyerLib shared] start];

Compile error: method not found

Symptom: Xcode reports No visible @interface for 'AppsFlyerLib' declares selector 'oldMethodName:'.

Solution: Refer to the breaking changes sections above to find the 7.0 replacement. Every removed method has a direct replacement or a clear rationale for removal.


Quick reference

All API changes at a glance. Use this when you hit a compile error and want to find the 7.0 replacement without reading the full section.

AppsFlyerLib

6.x7.0Breakage
appsFlyerDevKey (read-write property)appsFlyerDevKey (read-only) + initialize(devKey:appId:)Compile
appleAppID (read-write property)appleAppID (read-only) + initialize(devKey:appId:)Compile
setHost(_:withHostPrefix:) — host, prefixsetHost(_:hostName:) — prefix, host (order swapped)Compile + Silent regression
getSDKVersiongetSdkVersionCompile
validateAndLogInAppPurchase(_:price:currency:transactionId:additionalParameters:success:failure:)validateAndLogInAppPurchase(purchaseDetails:purchaseAdditionalDetails:)Compile
setSharingFilterForAllPartnersRemoved — use setSharingFilterForPartnersCompile
waitForATTUserAuthorization(timeoutInterval:)Deprecated → registerSessionReadyListenerCompile warning → Silent regression

Swift-specific changes

6.x Swift7.0 SwiftBreakage
appendParametersToDeeplinkURL(contains:parameters:)appendParametersToDeepLinkingURL(contains:parameters:)Compile
setPartnerData(partnerId:partnerInfo:)setPartnerData(partnerId:data:)Compile

AppsFlyerLibDelegate

6.x7.0Breakage
onAppOpenAttribution (@optional)Removed — migrate to AppsFlyerDeepLinkDelegate.didResolveDeepLinkCompile
onAppOpenAttributionFailure (@optional)Removed — handle errors via result.status in didResolveDeepLinkCompile

AppsFlyerDeepLinkDelegate

6.x Swift name7.0 Swift nameBreakage
DeepLinkDelegateAppsFlyerDeepLinkDelegateCompile (Swift)

AppsFlyerShareInviteHelper

6.x7.0Breakage
generateInviteUrl(linkGenerator:completionHandler:) — no error paramgenerateInviteLink(linkGenerator:completionHandler:) — adds ErrorCompile
logInvite(_:parameters:)logInvite(_:eventParameters:)Compile

AppsFlyerCrossPromotionHelper

6.x7.0Breakage
logCrossPromoteImpression(_:appID:campaign:parameters:)logCrossPromoteImpression(_:appId:campaign:userParams:)Compile
logAndOpenStore(_:appID:campaign:parameters:openStore:)logAndOpenStore(_:promotedAppId:campaign:userParams:openStore:)Compile

AppsFlyerLinkGenerator

6.x7.0Breakage
setReferrerImageURLsetReferrerImageUrlCompile
setAppleAppIDRemoved — no replacementCompile
setDeeplinkPathRemoved — no replacementCompile
setBaseDeeplinksetBaseDeepLinkCompile
addParametersaddUserParamsCompile