SDK Migration - iOS SDK

    This article contains the information required to update the Airbridge iOS SDK. We recommend checking the information regarding all versions.

    Update from v1.x to v4.0

    Check the information below when updating the iOS SDK to v4.0. The iOS SDK name has changed from "AirBridge" to "Airbridge," and the "AirBridge class" has changed to "Airbridge class." Functions and options have been renamed.

    Option

    Function

    Class

    Constant

    SDK installation and initialization

    The CocoaPods package name, SwiftPackageManager Git address, and direct install download URL have changed. Delete the existing iOS SDK and reinstall it by following the Airbridge guide.

    The AirBridge.getInstance function used to initialize the SDK has been changed to the Airbridge.initializeSDK function. Also, the option setting functions have been changed to the AirbridgeOption and AirbridgeOptionBuilder classes.

    SDK's options are no longer changed at runtime. Refer to the mapping below to write your new SDK initialization code.

    1234567
    import Airbridge
    ...
    let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN")
        .setLogLevel(.warning)
        .setSessionTimeout(second: 300)
        .build()
    Airbridge.initializeSDK(option: option)
    12345678
    #import <Airbridge/Airbridge.h>
    ...
    AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
                                                                                   token:@"YOUR_APP_SDK_TOKEN"];
    [optionBuilder setLogLevel:AirbridgeLogLevelWarning];
    [optionBuilder setSessionTimeoutWithSecond:300];
    AirbridgeOption* option = [optionBuilder build];
    [Airbridge initializeSDKWithOption:option];

    1234567
    import Airbridge
    ...
    let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN")
        .setLogLevel(.warning)
        .setSessionTimeout(second: 300)
        .build()
    Airbridge.initializeSDK(option: option)
    12345678
    #import <Airbridge/Airbridge.h>
    ...
    AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
                                                                                   token:@"YOUR_APP_SDK_TOKEN"];
    [optionBuilder setLogLevel:AirbridgeLogLevelWarning];
    [optionBuilder setSessionTimeoutWithSecond:300];
    AirbridgeOption* option = [optionBuilder build];
    [Airbridge initializeSDKWithOption:option];

    Deep Linking

    The AirBridge.setDeeplinkCallback function has been replaced by the Airbridge.handleDeeplink function and handleDeferredDeeplink function.

    You need to implement the existing AirBridge.setDeeplinkCallback function by separating it into a function that handles scheme deep links registered in the Airbridge dashboard and another function that handles other deep links. Please refer to the following DeeplinkHandler class.

    123456789101112131415161718192021
    import Foundation
    
    final class DeeplinkHandler {
        private init() {}
    
        static func handleSchemeDeeplink(url: URL) -> Bool {
            if url.scheme != "YOUR_SCHEME" {
                return false
            }
    
            // REQUIRE: show content
    
            return true
        }
    
        static func handleOtherDeeplink(url: URL) -> Bool {
            // OPTION: show content
    
            return true
        }
    }
    1234567891011121314151617181920212223242526272829303132
    #import <Foundation/Foundation.h>
    
    @implementation ABDeeplinkHandler
    
    - (instancetype) init __unavailable;
    
    + (BOOL)handleSchemeDeeplink:(NSURL *)url;
    + (BOOL)handleOtherDeeplink:(NSURL *)url;
    
    @end
    ...
    #import "ABDeeplinkHandler.h"
    
    @interface ABDeeplinkHandler : NSObject
    
    + (BOOL)handleSchemeDeeplink:(NSURL *)url {
        if (![url.scheme isEqualToString:@"YOUR_SCHEME"]) {
            return NO;
        }
    
        // REQUIRE: show content
    
        return YES;
    }
    
    + (BOOL)handleOtherDeeplink:(NSURL *)url {
        // OPTION: show content
    
        return YES;
    }
    
    @end

    AirBridge.deeplink().handle (or handleUniversalLink) and AirBridge.deeplink().handleURLSchemeDeeplink have been replaced by Airbridge.trackDeeplink.

    1. Remove the part that calls the AirBridge.deeplink().handle (or handleUniversalLink) and AirBridge.deeplink().handleURLSchemeDeeplink functions depending on the system method.

    2. You call the Airbridge.trackDeeplink function and the Airbridge.handleDeeplink function.

    The Airbridge.handleDeeplink function provides a scheme deep link with true when an Airbridge deeplink is entered. If it is not an Airbridge deeplink, it does not provide a callback with false.

    3. Call a function that processes the scheme deeplink executed to Airbridge in the onSuccess callback.

    1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
    import UIKit
    import Airbridge
    
    class SceneDelegate: UIResponder, UIWindowSceneDelegate {
        var window: UIWindow?
    
        // when terminated app is opened with scheme deeplink or universal links
        func scene(
            _ scene: UIScene,
            willConnectTo session: UISceneSession,
            options connectionOptions: UIScene.ConnectionOptions
        ) {
            // when app is opened with scheme deeplink
            if let url = connectionOptions.urlContexts.first?.url {
                // track deeplink
                Airbridge.trackDeeplink(url: url)
    
                // handle airbridge deeplink
                var isHandled = Airbridge.handleDeeplink(url: url) { url in
                    DeeplinkHandler.handleSchemeDeeplink(url: url)
                }
                if isHandled { return }
    
                // handle scheme deeplink
                isHandled = DeeplinkHandler.handleSchemeDeeplink(url: url)
                if isHandled { return }
    
                // handle other deeplink
                isHandled = DeeplinkHandler.handleOtherDeeplink(url: url)
            }
            // when app is opened with universal links
            else if let userActivity = connectionOptions.userActivities.first {
                // track deeplink
                Airbridge.trackDeeplink(userActivity: userActivity)
    
                // handle airbridge deeplink
                var isHandled = Airbridge.handleDeeplink(userActivity: userActivity) { url in
                    DeeplinkHandler.handleSchemeDeeplink(url: url)
                }
                if isHandled { return }
    
                // handle other deeplink
                if let url = userActivity.webpageURL {
                    isHandled = DeeplinkHandler.handleOtherDeeplink(url: url)
                }
            }
        }
    
        // when backgrounded app is opened with scheme deeplink
        func scene(
            _ scene: UIScene,
            openURLContexts URLContexts: Set<UIOpenURLContext>
        ) {
            guard let url = URLContexts.first?.url else { return }
    
            // track deeplink
            Airbridge.trackDeeplink(url: url)
    
            // handle airbridge deeplink
            var isHandled = Airbridge.handleDeeplink(url: url) { url in
                DeeplinkHandler.handleSchemeDeeplink(url: url)
            }
            if isHandled { return }
    
            // handle scheme deeplink
            isHandled = DeeplinkHandler.handleSchemeDeeplink(url: url)
            if isHandled { return }
    
            // handle other deeplink
            isHandled = DeeplinkHandler.handleOtherDeeplink(url: url)
        }
    
        // when backgrounded app is opened with universal links
        func scene(
            _ scene: UIScene,
            continue userActivity: NSUserActivity
        ) {
            // track deeplink
            Airbridge.trackDeeplink(userActivity: userActivity)
    
            // handle airbridge deeplink
            var isHandled = Airbridge.handleDeeplink(userActivity: userActivity) { url in
                DeeplinkHandler.handleSchemeDeeplink(url: url)
            }
            if isHandled { return }
    
            // handle other deeplink
            if let url = userActivity.webpageURL {
                isHandled = DeeplinkHandler.handleOtherDeeplink(url: url)
            }
        }
    }
    12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
    #import "SceneDelegate.h"
    #import "ABDeeplinkHandler.h"
    #import <Airbridge/Airbridge.h>
    
    @interface SceneDelegate ()
    
    @end
    
    @implementation SceneDelegate
    
    // when terminated app is opened with scheme deeplink or universal links
    - (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
        // when app is opened with scheme deeplink
        NSURL* url = connectionOptions.URLContexts.allObjects.firstObject.URL;
        NSUserActivity* userActivity = connectionOptions.userActivities.allObjects.firstObject;
        if (url != nil) {
            // track deeplink
            [Airbridge trackDeeplinkWithUrl:url];
    
            // handle airbridge deeplink
            BOOL isHandled = [Airbridge handleDeeplinkWithUrl:url onSuccess:^(NSURL* url) {
                [ABDeeplinkHandler handleSchemeDeeplink:url];
            }];
            if (isHandled) { return; }
    
            // handle scheme deeplink
            isHandled = [ABDeeplinkHandler handleSchemeDeeplink:url];
            if (isHandled) { return; }
    
            // handle other deeplink
            isHandled = [ABDeeplinkHandler handleSchemeDeeplink:url];
        }
        else if (userActivity != nil) {
            // track deeplink
            [Airbridge trackDeeplinkWithUserActivity:userActivity];
    
            // handle airbridge deeplink
            BOOL isHandled = [Airbridge handleDeeplinkWithUserActivity:userActivity onSuccess:^(NSURL* url) {
                [ABDeeplinkHandler handleSchemeDeeplink:url];
            }];
            if (isHandled) { return; }
    
            // handle other deeplink
            NSURL* url = userActivity.webpageURL;
            if (url != nil) {
                isHandled = [ABDeeplinkHandler handleOtherDeeplink:url];
            }
        }
    }
    
    // when backgrounded app is opened with scheme deeplink
    - (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts {
        NSURL* url = URLContexts.allObjects.firstObject.URL;
        if (url == nil) { return; }
    
        // track deeplink
        [Airbridge trackDeeplinkWithUrl:url];
    
        // handle airbridge deeplink
        BOOL isHandled = [Airbridge handleDeeplinkWithUrl:url onSuccess:^(NSURL* url) {
            [ABDeeplinkHandler handleSchemeDeeplink:url];
        }];
        if (isHandled) { return; }
    
        // handle scheme deeplink
        isHandled = [ABDeeplinkHandler handleSchemeDeeplink:url];
        if (isHandled) { return; }
    
        // handle other deeplink
        isHandled = [ABDeeplinkHandler handleSchemeDeeplink:url];
    }
    
    // when backgrounded app is opened with universal links
    - (void)scene:(UIScene *)scene continueUserActivity:(NSUserActivity *)userActivity {
        // track deeplink
        [Airbridge trackDeeplinkWithUserActivity:userActivity];
    
        // handle airbridge deeplink
        BOOL isHandled = [Airbridge handleDeeplinkWithUserActivity:userActivity onSuccess:^(NSURL* url) {
            [ABDeeplinkHandler handleSchemeDeeplink:url];
        }];
        if (isHandled) { return; }
    
        // handle other deeplink
        NSURL* url = userActivity.webpageURL;
        if (url != nil) {
            isHandled = [ABDeeplinkHandler handleOtherDeeplink:url];
        }
    }
    
    @end
    1234567891011121314151617181920212223242526272829
    import SwiftUI
    import Airbridge
    
    @main
    struct ActualApp: App {
        var body: some Scene {
            WindowGroup {
                ContentView()
                    // when app is opened with scheme deeplink or universal links
                    .onOpenURL { url in
                        // track deeplink
                        Airbridge.trackDeeplink(url: url)
    
                        // handle airbridge deeplink
                        var isHandled = Airbridge.handleDeeplink(url: url) { url in
                            DeeplinkHandler.handleSchemeDeeplink(url: url)
                        }
                        if isHandled { return }
    
                        // handle scheme deeplink
                        isHandled = DeeplinkHandler.handleSchemeDeeplink(url: url)
                        if isHandled { return }
    
                        // handle other deeplink
                        isHandled = DeeplinkHandler.handleOtherDeeplink(url: url)
                    }
            }
        }
    }
    12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
    import UIKit
    import Airbridge
    
    @main
    class AppDelegate: UIResponder, UIApplicationDelegate {   
        var window: UIWindow?
    
        // when app is opened with scheme deeplink
        func application(
            _ app: UIApplication,
            open url: URL,
            options: [UIApplication.OpenURLOptionsKey : Any] = [:]
        ) -> Bool {
            // track deeplink
            Airbridge.trackDeeplink(url: url)
    
            // handle airbridge deeplink
            var isHandled = Airbridge.handleDeeplink(url: url) { url in
                DeeplinkHandler.handleSchemeDeeplink(url: url)
            }
            if isHandled { return isHandled }
    
            // handle scheme deeplink
            isHandled = DeeplinkHandler.handleSchemeDeeplink(url: url)
            if isHandled { return isHandled }
    
            // handle other deeplink
            isHandled = DeeplinkHandler.handleOtherDeeplink(url: url)
    
            return isHandled
        }
    
        // when app is opened with universal links
        func application(
            _ application: UIApplication,
            continue userActivity: NSUserActivity,
            restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
        ) -> Bool {
            // track deeplink
            Airbridge.trackDeeplink(userActivity: userActivity)
    
            // handle airbridge deeplink
            var isHandled = Airbridge.handleDeeplink(userActivity: userActivity) { url in
                DeeplinkHandler.handleSchemeDeeplink(url: url)
            }
            if isHandled { return isHandled }
    
            // handle other deeplink
            if let url = userActivity.webpageURL {
                isHandled = DeeplinkHandler.handleOtherDeeplink(url: url)
            }
    
            return isHandled
        }
    }
    12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
    #import "AppDelegate.h"
    #import "ABDeeplinkHandler.h"
    #import <Airbridge/Airbridge.h>
    
    @interface AppDelegate ()
    
    @end
    
    @implementation AppDelegate
    
    // when app is opened with scheme deeplink
    - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
        // track deeplink
        [Airbridge trackDeeplinkWithUrl:url];
    
        // handle airbridge deeplink
        BOOL isHandled = [Airbridge handleDeeplinkWithUrl:url onSuccess:^(NSURL* url) {
            [ABDeeplinkHandler handleSchemeDeeplink:url];
        }];
        if (isHandled) { return isHandled; }
        
        // handle scheme deeplink
        isHandled = [ABDeeplinkHandler handleSchemeDeeplink:url];
        if (isHandled) { return isHandled; }
        
        // handle other deeplink
        isHandled = [ABDeeplinkHandler handleOtherDeeplink:url];
        
        return isHandled;
    }
    
    // when app is opened with universal links
    - (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
        // track deeplink
        [Airbridge trackDeeplinkWithUserActivity:userActivity];
    
        // handle airbridge deeplink
        BOOL isHandled = [Airbridge handleDeeplinkWithUserActivity:userActivity onSuccess:^(NSURL* url) {
            [ABDeeplinkHandler handleSchemeDeeplink:url];
        }];
        if (isHandled) { return isHandled; }
        
        // handle other deeplink
        NSURL* url = userActivity.webpageURL;
        if (url != nil) {
            isHandled = [ABDeeplinkHandler handleOtherDeeplink:url];
        }
        
        return isHandled;
    }
    
    @end

    Airbridge.handleDeeplink function returns true when an Airbridge deeplink is inputted, and converts it to a Scheme deeplink and passes it on to onSuccess. And if a URL that is not an Airbridge deeplink is inputted or SDK is not initialized, it simply returns false.

    In the part where SDK is initialized, it calls the Airbridge.handleDeferredDeeplink function. It calls a function that processes scheme deep links run by Airbridge in the onSuccess callback.

    1234567891011
    import Airbridge
    ...
    let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN")
        .build()
    Airbridge.initializeSDK(option: option)
    ...
    let isHandled = Airbridge.handleDeferredDeeplink() { url in
        if let url {
            DeeplinkHandler.handleSchemeDeeplink(url)
        }
    }
    123456789101112
    #import <Airbridge/Airbridge.h>
    ...
    AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
                                                                                   token:@"YOUR_APP_SDK_TOKEN"];
    AirbridgeOption* option = [optionBuilder build];
    [Airbridge initializeSDKWithOption:option];
    ...
    [Airbridge handleDeferredDeeplinkOnSuccess:^(NSURL* url) {
        if (url != nil) {
            [ABDeeplinkHandler handleSchemeDeeplink:url];
        }
    }];

    The Airbridge.handleDeferredDeeplink function waits for the acquisition of Airbridge deeplinks with true if Airbridge deeplinks are entered, or converts them into scheme deeplinks and passes them to onSuccess. You can use the corresponding scheme deeplink to send users to the set destination.

    If there is no stored Airbridge deeplink, it delivers nil. If the SDK has not been initialized or if you did not call the Airbridge.handleDeferredDeeplink function for the first time, it delivers false.

    The method for registering custom domains has changed. Previously, custom domains were added as values to the co.ab180.airbridge.trackingLink.customDomains key in Info.plist.

    The changed method is to add them by calling the setTrackingLinkCustomDomains function during the SDK initialization phase.

    Please call the setTrackingLinkCustomDomains function in the SDK initialization code.

    12345678910
    import Airbridge
    ...
    // YOUR_APP_NAME: input your app name
    // YOUR_APP_SDK_TOKEN: input your app token
    // YOUR_APP_CUSTOM_DOMAIN: input your app custom domain. ex) example.domain.com
    let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME",
                                        token: "YOUR_APP_SDK_TOKEN")
        .setTrackingLinkCustomDomains(["YOUR_APP_CUSTOM_DOMAIN"])
        .build()
    Airbridge.initializeSDK(option: option)
    12345678910
    #import <Airbridge/Airbridge.h>
    ...
    // YOUR_APP_NAME: input your app name
    // YOUR_APP_SDK_TOKEN: input your app token
    // YOUR_APP_CUSTOM_DOMAIN: input your app custom domain. ex) example.domain.com
    AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
                                                                                   token:@"YOUR_APP_SDK_TOKEN"];
    [optionBuilder setTrackingLinkCustomDomains:@[@"YOUR_APP_CUSTOM_DOMAIN"]];
    AirbridgeOption* option = [optionBuilder build];
    [Airbridge initializeSDKWithOption:option];

    In-app event and user data

    Attention

    Enter the value to the AirbridgeAttribute.VALUE instead of to the totalValue.

    The logic where totalValue overwrites the value when using totalValue of setSemantics and defining the value with setValue has been removed from SDK v4.

    The ABInAppEvent class has been replaced by the Airbridge.trackEvent function.

    Follow the instructions below to change the ABInAppEvent class and setAction, setLabel, setValue, setSemantics, and setCustoms to the Airbridge.trackEvent function.

    • setCategory: If you are using ABCategory, you should use AirbridgeCategory. If you are using a String, enter it in the category parameter as is.

    • setAction: Enter the AirbridgeAttribute.ACTION key in the semanticAttributes parameter.

    • setLabel: Enter in the AirbridgeAttribute.LABEL key of the semanticAttributes parameter.

    • setValue: Enter in the AirbridgeAttribute.VALUE key of the semanticAttributes parameter.

    • setSemantics: If you are using ABSemanticsKey as the key in the semanticAttributes parameter, useAirbridgeAttribute. If you are using String, enter it as is. The value is entered regardless of the key.

    • setCustoms: In the customAttributes parameter, enter the key and value as they are.

    See AirbridgeCategory, AirbridgeAttribute mapping, and the Airbridge.trackEvent function below.

    123456789101112131415161718192021222324252627282930
    import Airbridge
    ...
    // setCategory
    Airbridge.trackEvent(
        category: AirbridgeCategory.ORDER_COMPLETED,
        semanticAttributes: [
            // setAction
            AirbridgeAttribute.ACTION: "Tool",
            // setLabel
            AirbridgeAttribute.LABEL: "Hammer",
            // setValue
            AirbridgeAttribute.VALUE: 10,
            // setSemantics (using ABSemanticsKey)
            AirbridgeAttribute.CURRENCY: "USD",
            AirbridgeAttribute.PRODUCTS: [
                [
                    // setSemantics value (using ABProductKey)
                    AirbridgeAttribute.PRODUCT_ID: "12345",
                    // setSemantics value (using String)
                    "name": "PlasticHammer",
                ],
            ],
            // setSemantics (using String)
            "totalQuantity": 1,
        ],
        customAttributes: [
            // setCustoms
            "promotion": "FirstPurchasePromotion",
        ]
    )
    12345678910111213141516171819202122232425
    #import <Airbridge/Airbridge.h>
    ...
    [Airbridge trackEventWithCategory:@"event" semanticAttributes:@{
        // action
        AirbridgeAttribute.ACTION: @"Tool",
        // label
        AirbridgeAttribute.LABEL: @"Hammer",
        // value
        AirbridgeAttribute.VALUE: @(10),
        // semantic attribute (provided by sdk)
        AirbridgeAttribute.CURRENCY: @"USD",
        AirbridgeAttribute.PRODUCTS: @[
            @{
                // semantic attribute value (provided by sdk)
                AirbridgeAttribute.PRODUCT_ID: @"12345",
                // semantic attribute value (not provided by sdk)
                @"name": @"PlasticHammer",
            },
        ],
        // semantic attribute (not provided by sdk)
        @"totalQuantity": @(1),
    }, customAttributes:@{
        // custom attribute
        @"promotion": @"FirstPurchasePromotion",
    }];

    The AirBridge.setDeviceAlias related functions have been replaced with AirBridge.setDeviceAlias related functions.

    12345
    import Airbridge
    ...
    Airbridge.setDeviceAlias(key: "string", value: "string")
    Airbridge.removeDeviceAlias(key: "string")
    Airbridge.clearDeviceAlias()
    12345678910
    #import <Airbridge/Airbridge.h>
    ...
    BOOL isHandled = [Airbridge impressionWithTrackingLink:url onSuccess:^{
        // when url is tracking link and succeed
    } onFailure:^(NSError * _Nonnull) {
        // when url is tracking link and failed
    }];
    if (!isHandled) {
        // when url is not tracking link
    }

    The AirBridge.state().setUser related functions have been replaced with Airbridge.setUser related functions. The setUser function that sets user information at once is not supported.

    1234567891011121314151617181920
    import Airbridge
    ...
    // identifier
    Airbridge.setUserID("string")
    Airbridge.clearUserID()
    // addtional identifier
    Airbridge.setUserAlias(key: "string", value: "string")
    Airbridge.removeUserAlias(key: "string")
    Airbridge.clearUserAlias()
    ...
    // email, phone
    Airbridge.setUserEmail("string")
    Airbridge.clearUserEmail()
    Airbridge.setUserPhone("string")
    Airbridge.clearUserPhone()
    // addtional attribute
    Airbridge.setUserAttribute(key: "string", value: "string")
    Airbridge.setUserAttribute(key: "number", value: 1000)
    Airbridge.removeUserAttribute(key: "string")
    Airbridge.clearUserAttributes()
    1234567891011121314151617181920
    #import <Airbridge/Airbridge.h>
    ...
    // identifier
    [Airbridge setUserID:@"string"];
    [Airbridge clearUserID];
    // additional identifier
    [Airbridge setUserAliasWithKey:@"string" value:@"string"];
    [Airbridge removeUserAliasWithKey:@"string"];
    [Airbridge clearUserAlias];
    ...
    // email, phone
    [Airbridge setUserEmail:@"string"];
    [Airbridge clearUserEmail];
    [Airbridge setUserPhone:@"string"];
    [Airbridge clearUserPhone];
    // addtional attribute
    [Airbridge setUserAttributeWithKey:@"string" value:@"string"];
    [Airbridge setUserAttributeWithKey:@"number" value:@(1000)];
    [Airbridge removeUserAttributeWithKey:@"string"];
    [Airbridge clearUserAttributes];

    Additional settings

    The AirBridge.placement().click function and the AirBridge.placement().impression function have been replaced with the Airbridge.clickfunction and the Airbridge.impression function.

    1234567891011121314151617181920
    import Airbridge
    ...
    let isHandled = Airbridge.click(trackingLink: url) {
        // when url is tracking link and succeed
    } onFailure: { error in
        // when url is tracking link and failed
        // example: url is another app's tracking link, internet is not connected
    }
    if !isHandled {
        // when url is not tracking link
    }
    ...
    let isHandled = Airbridge.impression(trackingLink: url) {
        // when url is tracking link and succeed
    } onFailure: { error in
        // when url is tracking link and failed
    }
    if !isHandled {
        // when url is not tracking link
    }
    1234567891011121314151617181920
    #import <Airbridge/Airbridge.h>
    ...
    BOOL isHandled = [Airbridge clickWithTrackingLink:url onSuccess:^{
        // when url is tracking link and succeed
    } onFailure:^(NSError * _Nonnull) {
        // when url is tracking link and failed
        // example: url is another app's tracking link, internet is not connected
    }];
    if (!isHandled) {
        // when url is not tracking link
    }
    ...
    BOOL isHandled = [Airbridge impressionWithTrackingLink:url onSuccess:^{
        // when url is tracking link and succeed
    } onFailure:^(NSError * _Nonnull) {
        // when url is tracking link and failed
    }];
    if (!isHandled) {
        // when url is not tracking link
    }

    The AirBridge.webInterface().inject function has been replaced by Airbridge.setWebInterface function.

    123456
    import Airbridge
    ...
    Airbridge.setWebInterface(
        controller: controller,
        webToken: "YOUR_WEB_TOKEN"
    )
    123
    #import <Airbridge/Airbridge.h>
    ...
    [Airbridge setWebInterfaceWithController:controller webToken:@"YOUR_WEB_TOKEN"];

    Update within v1.x

    See the major changes in each version of the iOS SDK.

    For apps registered with Airbridge after September 4, 2023, an issue where the deep link URL provided in the deep link callback was decoded twice from the content entered in the Airbridge dashboard has been resolved. This issue was found in versions v1.34.0 to v1.35.1.

    For apps registered with Airbridge after September 4, 2023, the "airbridge_referrer" will no longer be added to the deep link URL provided in the deep link callback and will instead pass it to the information entered in the Airbridge Dashboard.

    Contact your Airbridge CSM if your Airbridge App was created before September 4, 2023, and want to apply this change. If you don't have a dedicated CSM, contact the Airbridge Help Center.

    v1.33.0 - SKAdNetwork

    When a user updates an app with iOS SDK v1.33.0 or earlier to v1.33.0 or later, the last calculated conversion value will be finalized.

    v1.32.1 - User privacy

    The default setting for trackingAuthorizeTimeout was changed from 0 seconds to 30 seconds.