> ## Documentation Index
> Fetch the complete documentation index at: https://help.airbridge.io/llms.txt
> Use this file to discover all available pages before exploring further.

# 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.

<Accordion title="List of all changes">
  #### Option

  | AirBridge                                                  | AirbridgeOptionBuilder                                       | What's Changed                                                                                                                         |
  | ---------------------------------------------------------- | ------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------- |
  | -                                                          | AirbridgeOptionBuilder(name: String, token: String)          | The option has been changed to be set through the Builder.                                                                             |
  | -                                                          | build()                                                      | The option has been changed to be non-modifiable after the SDK initialization.                                                         |
  | setLogLevel(ABLogLevel)                                    | setLogLevel(AirbridgeLogLevel)                               | The type name has been changed.                                                                                                        |
  | setPaginateLogEnabled(Bool)                                | setPaginateLogEnabled(Bool)                                  | -                                                                                                                                      |
  | state().setSDKDevelopmentPlatform(String)                  | setSDKDevelopmentPlatform(String)                            | The name has been changed.                                                                                                             |
  | -                                                          | setAppGroup(String)                                          | New features have been added.                                                                                                          |
  | setSDKEnabled(Bool)                                        | setSDKEnabled(Bool)                                          | -                                                                                                                                      |
  | -                                                          | setTrackingLinkCustomDomains(\[String])                      | The setting available through Info.plist has been changed to an option.                                                                |
  | setIsFacebookDeferredAppLinkEnabled(Bool)                  | setTrackMetaDeferredAppLinkEnabled(Bool)                     | The name has been changed.                                                                                                             |
  | deeplink().setDeeplinkCallback((String) -> Void)           | -                                                            | The role has been transferred to the handleDeeplink function.                                                                          |
  | deeplink().setDeferredDeeplinkCallback((String) -> Void)   | -                                                            | The role has been transferred to the handleDeferredDeeplink function.                                                                  |
  | deeplink().setHandleTrackingLinkTimeout: UInt              | -                                                            | The feature has been removed. (It is fixed to the default value of 3 seconds.)                                                         |
  | setAutoStartTrackingEnabled(Bool)                          | setAutoStartTrackingEnabled(Bool)                            | -                                                                                                                                      |
  | -                                                          | setAutoDetermineTrackingAuthorizationEnabled(Bool)           | New features have been added.                                                                                                          |
  | setting().trackingAuthorizeTimeout: UInt                   | setAutoDetermineTrackingAuthorizationTimeout(second: Double) | The name has been changed. And the unit has been changed from milliseconds to seconds. Also, a maximum limit of 1 hour has been added. |
  | setting().isRestartTrackingAuthorizeTimeout: Bool          | -                                                            | The function has been removed. (Fixed to the default, true.)                                                                           |
  | setIsUserInfoHashed(Bool)                                  | setHashUserInformationEnabled(Bool)                          | The name has been changed.                                                                                                             |
  | setSessionTimeout(Int)                                     | setSessionTimeout(second: Double)                            | The unit has been changed from milliseconds to seconds. And a maximum limit of 7 days has been added.                                  |
  | setIsTrackAirbridgeDeeplinkOnly(Bool)                      | setTrackAirbridgeDeeplinkOnlyEnabled(Bool)                   | The name has been changed.                                                                                                             |
  | setSDKSignature(id: String, secret: String)                | setSDKSignature(id: String, secret: String)                  | -                                                                                                                                      |
  | resetEventBufferEnabled(Bool)                              | setClearEventBufferOnInitializeEnabled(Bool)                 | The name has been changed.                                                                                                             |
  | setting().isResetEventBufferEnabled: Bool                  | setClearEventBufferOnInitializeEnabled(Bool)                 | The name has been changed.                                                                                                             |
  | -                                                          | setPauseEventTransmitOnBackgroundEnabled(Bool)               | New features have been added.                                                                                                          |
  | setting().setEventMaximumBufferCount(UInt)                 | setEventBufferCountLimit(Int)                                | The name has been changed.                                                                                                             |
  | setting().setEventMaximumBufferSize(UInt)                  | setEventBufferSizeLimit(gibibyte: Double)                    | The name has been changed. And the unit has been changed from byte to gibibyte.                                                        |
  | setting().setEventTransmitInterval(UInt)                   | setEventTransmitInterval(second: Double)                     | The name has been changed. And the unit has been changed from milliseconds to seconds. Also, a maximum limit of 1 day has been added.  |
  | setting().attributionCallback: (\[String: String]) -> Void | setOnAttributionReceived((\[String: String]) -> Void)        | The name has been changed.                                                                                                             |

  #### Function

  | AirBridge                                                                | Airbridge                                                                                                  | What's Changed                                                                                                        |
  | ------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
  | getInstance(String, appName: String)                                     | initializeSDK(option: AirbridgeOption)                                                                     | The name has been changed.                                                                                            |
  | isSDKEnabled: Bool                                                       | isSDKEnabled: Bool                                                                                         | -                                                                                                                     |
  | enableSDK()                                                              | enableSDK()                                                                                                | -                                                                                                                     |
  | disableSDK()                                                             | disableSDK()                                                                                               | The implementation method that restricted access to SDK components has been changed to remove components from memory. |
  | startTracking()                                                          | startTracking()                                                                                            | -                                                                                                                     |
  | deeplink().handleURLSchemeDeeplink(URL)                                  | trackDeeplink(url: URL)                                                                                    | The name has been changed.                                                                                            |
  | deeplink().handleUserActivity(NSUserActivity)                            | trackDeeplink(userActivity: NSUserActivity)                                                                | The name has been changed.                                                                                            |
  | -                                                                        | handleDeeplink(url: URL, onSuccess: (URL) -> Void, onFailure: (Error) -> Void) -> Bool                     | The setDeeplinkCallback option has been moved.                                                                        |
  | -                                                                        | handleDeeplink(userActivity: NSUserActivity, onSuccess: (URL) -> Void, onFailure: (Error) -> Void) -> Bool | The setDeeplinkCallback option has been moved.                                                                        |
  | -                                                                        | handleDeferredDeeplink(url: URL, onSuccess: (URL) -> Void, onFailure: (Error) -> Void) -> Bool             | The setDeferredDeeplinkCallback option has been moved.                                                                |
  | -                                                                        | trackEvent(category: String, semanticAttributes: \[String: Any], customAttributes: \[String: Any])         | The event transmission method has been changed.                                                                       |
  | placement().click(URL, completion: (Error?) -> Void)                     | click(trackingLink: URL, onSuccess: () -> Void, onFailure: (Error) -> Void) -> Bool                        | The name has been changed.                                                                                            |
  | placement().impression(URL, completion: (Error?) -> Void)                | impression(trackingLink: URL, onSuccess: () -> Void, onFailure: (Error) -> Void) -> Bool                   | The name has been changed.                                                                                            |
  | webInterface().inject(to: WKUserContentController, withWebToken: String) | setWebInterface(controller: WKUserContentController, webToken: String)                                     | The name has been changed. And the DeviceAlias integration function has been added.                                   |
  | deviceUUID: String                                                       | fetchDeviceUUID(onSuccess: (String) -> Void, onFailure: (Error) -> Void) -> Bool                           | The name has been changed. The function has been modified to operate asynchronously.                                  |
  | fetchAirbridgeGeneratedUUID((String) -> Void) -> Bool                    | fetchAirbridgeGeneratedUUID(onSuccess: (String) -> Void, onFailure: (Error) -> Void) -> Bool               | The name has been changed.                                                                                            |
  | -                                                                        | isUninstallTrackingNotification(\[String: Any]) -> Bool                                                    | New features have been added.                                                                                         |
  | state().setUserID(String)                                                | setUserID(String)                                                                                          | The name has been changed.                                                                                            |
  | -                                                                        | clearUserID()                                                                                              | New features have been added.                                                                                         |
  | state().setUserEmail(String)                                             | setUserEmail(String)                                                                                       | The name has been changed.                                                                                            |
  | -                                                                        | clearUserEmail()                                                                                           | New features have been added.                                                                                         |
  | state().setUserPhone(String)                                             | setUserPhone(String)                                                                                       | The name has been changed.                                                                                            |
  | -                                                                        | clearUserPhone()                                                                                           | New features have been added.                                                                                         |
  | addUserAttribute(key: String, value: Any)                                | setUserAttribute(key: String, value: Any)                                                                  | The name has been changed.                                                                                            |
  | removeUserAttribute(String)                                              | removeUserAttribute(key: String)                                                                           | The name has been changed.                                                                                            |
  | clearUserAttributes()                                                    | clearUserAttributes()                                                                                      | -                                                                                                                     |
  | addUserAlias(key: String, value: String)                                 | setUserAlias(key: String, value: String)                                                                   | The name has been changed.                                                                                            |
  | removeUserAlias(String)                                                  | removeUserAlias(key: String)                                                                               | The name has been changed.                                                                                            |
  | clearUserAlias()                                                         | clearUserAlias()                                                                                           | -                                                                                                                     |
  | -                                                                        | clearUser()                                                                                                | New features have been added.                                                                                         |
  | addDeviceAlias(key: String, value: String)                               | setDeviceAlias(key: String, value: String)                                                                 | The name has been changed.                                                                                            |
  | setDeviceAlias(key: String, value: String)                               | setDeviceAlias(key: String, value: String)                                                                 | -                                                                                                                     |
  | removeDeviceAlias(key: String)                                           | removeDeviceAlias(key: String)                                                                             | -                                                                                                                     |
  | clearDeviceAlias()                                                       | clearDeviceAlias()                                                                                         | -                                                                                                                     |
  | registerPushToken(Data)                                                  | registerPushToken(Data)                                                                                    | -                                                                                                                     |

  #### Class

  | ABInAppEvent                 | Airbridge                                                                                          | What's Changed                                                                                                                                                                                                                                                 |
  | ---------------------------- | -------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  | setCategory(String)          | trackEvent(category: String, semanticAttributes: \[String: Any], customAttributes: \[String: Any]) | Enter AirbridgeCategory or String in the category parameter.                                                                                                                                                                                                   |
  | setAction(String)            | trackEvent(category: String, semanticAttributes: \[String: Any], customAttributes: \[String: Any]) | Enter into the semanticAttributes parameter using AirbridgeAttribute.ACTION as the key.                                                                                                                                                                        |
  | setLabel(String)             | trackEvent(category: String, semanticAttributes: \[String: Any], customAttributes: \[String: Any]) | Enter into the semanticAttributes parameter using AirbridgeAttribute.LABEL as the key.                                                                                                                                                                         |
  | setValue(NSNumber)           | trackEvent(category: String, semanticAttributes: \[String: Any], customAttributes: \[String: Any]) | Enter into the semanticAttributes parameter using AirbridgeAttribute.VALUE as the key.                                                                                                                                                                         |
  | setSemantics(\[String: Any]) | trackEvent(category: String, semanticAttributes: \[String: Any], customAttributes: \[String: Any]) | Use AirbridgeAttribute for keys using ABSemanticsKey, and input keys using String directly into the semanticAttributes parameter.<br />For the value of products, use AirbridgeAttribute for keys using ABProductKey, and enter keys using string as they are. |
  | setCustoms(\[String: Any])   | trackEvent(category: String, semanticAttributes: \[String: Any], customAttributes: \[String: Any]) | Enter the key and value directly into customAttributes.                                                                                                                                                                                                        |

  #### Constant

  | ABCategory        | AirbridgeCategory       | What's Changed                |
  | ----------------- | ----------------------- | ----------------------------- |
  | signUp            | SIGN\_UP                | The name has been changed.    |
  | signIn            | SIGN\_IN                | The name has been changed.    |
  | signOut           | SIGN\_OUT               | The name has been changed.    |
  | viewHome          | HOME\_VIEWED            | The name has been changed.    |
  | viewProductList   | PRODUCT\_LIST\_VIEWED   | The name has been changed.    |
  | viewSearchResult  | SEARCH\_RESULTS\_VIEWED | The name has been changed.    |
  | viewProductDetail | PRODUCT\_VIEWED         | The name has been changed.    |
  | -                 | ADD\_PAYMENT\_INFO      | New features have been added. |
  | -                 | ADD\_TO\_WISHLIST       | New features have been added. |
  | addToCart         | ADDED\_TO\_CART         | The name has been changed.    |
  | -                 | INITIATE\_CHECKOUT      | New features have been added. |
  | purchase          | ORDER\_COMPLETED        | The name has been changed.    |
  | -                 | ORDER\_CANCELED         | New features have been added. |
  | -                 | START\_TRIAL            | New features have been added. |
  | -                 | SUBSCRIBE               | New features have been added. |
  | -                 | UNSUBSCRIBE             | New features have been added. |
  | -                 | AD\_IMPRESSION          | New features have been added. |
  | -                 | AD\_CLICK               | New features have been added. |
  | -                 | COMPLETE\_TUTORIAL      | New features have been added. |
  | -                 | ACHIEVE\_LEVEL          | New features have been added. |
  | -                 | UNLOCK\_ACHIEVEMENT     | New features have been added. |
  | -                 | RATE                    | New features have been added. |
  | -                 | SHARE                   | New features have been added. |
  | -                 | SCHEDULE                | New features have been added. |
  | -                 | SPEND\_CREDITS          | New features have been added. |

  | ABSemanticsKey | AirbridgeAttribute                    | What's Changed                                |
  | -------------- | ------------------------------------- | --------------------------------------------- |
  | -              | ACTION                                | New features have been added.                 |
  | -              | LABEL                                 | New features have been added.                 |
  | -              | VALUE                                 | New features have been added.                 |
  | totalValue     | -                                     | The feature has been removed. Enter in VALUE. |
  | currency       | CURRENCY                              | The name has been changed.                    |
  | -              | ORIGINAL\_CURRENCY                    | New features have been added.                 |
  | products       | PRODUCTS                              | The name has been changed.                    |
  | -              | PERIOD                                | New features have been added.                 |
  | -              | IS\_RENEWAL                           | New features have been added.                 |
  | -              | RENEWAL\_COUNT                        | New features have been added.                 |
  | productListID  | PRODUCT\_LIST\_ID                     | The name has been changed.                    |
  | cartID         | CART\_ID                              | The name has been changed.                    |
  | transactionID  | TRANSACTION\_ID                       | The name has been changed.                    |
  | -              | TRANSACTION\_TYPE                     | New features have been added.                 |
  | -              | TRANSACTION\_PAIRED\_EVENT\_CATEGORY  | New features have been added.                 |
  | -              | TRANSACTION\_PAIRED\_EVENT\_TIMESTAMP | New features have been added.                 |
  | totalQuantity  | TOTAL\_QUANTITY                       | The name has been changed.                    |
  | query          | QUERY                                 | The name has been changed.                    |
  | inAppPurchased | IN\_APP\_PURCHASED                    | The name has been changed.                    |
  | -              | CONTRIBUTION\_MARGIN                  | New features have been added.                 |
  | -              | ORIGINAL\_CONTRIBUTION\_MARGIN        | New features have been added.                 |
  | -              | LIST\_ID                              | New features have been added.                 |
  | -              | RATE\_ID                              | New features have been added.                 |
  | -              | RATE                                  | New features have been added.                 |
  | -              | MAX\_RATE                             | New features have been added.                 |
  | -              | ACHIEVEMENT\_ID                       | New features have been added.                 |
  | -              | SHARED\_CHANNEL                       | New features have been added.                 |
  | -              | DATE\_TIME                            | New features have been added.                 |
  | -              | DESCRIPTION                           | New features have been added.                 |
  | -              | IS\_REVENUE                           | New features have been added.                 |
  | -              | PLACE                                 | New features have been added.                 |
  | -              | SCHEDULE\_ID                          | New features have been added.                 |
  | -              | TYPE                                  | New features have been added.                 |
  | -              | LEVEL                                 | New features have been added.                 |
  | -              | SCORE                                 | New features have been added.                 |
  | -              | AD\_PARTNERS                          | New features have been added.                 |
  | -              | IS\_FIRST\_PER\_USER                  | New features have been added.                 |

  | ABProductKey | AirbridgeAttribute      | What's Changed                |
  | ------------ | ----------------------- | ----------------------------- |
  | productID    | PRODUCT\_ID             | The name has been changed.    |
  | name         | PRODUCT\_NAME           | The name has been changed.    |
  | price        | PRODUCT\_PRICE          | The name has been changed.    |
  | quantity     | PRODUCT\_QUANTITY       | The name has been changed.    |
  | currency     | PRODUCT\_CURRENCY       | The name has been changed.    |
  | position     | PRODUCT\_POSITION       | The name has been changed.    |
  | -            | PRODUCT\_CATEGORY\_ID   | New features have been added. |
  | -            | PRODUCT\_CATEGORY\_NAME | New features have been added. |
  | -            | PRODUCT\_BRAND\_ID      | New features have been added. |
  | -            | PRODUCT\_BRAND\_NAME    | New features have been added. |
</Accordion>

### 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](/en/developers/ios-sdk-v4#install-sdk).

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.

<CodeGroup>
  ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  import Airbridge
  ...
  let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN")
      .setLogLevel(.warning)
      .setSessionTimeout(second: 300)
      .build()
  Airbridge.initializeSDK(option: option)
  ```

  ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  #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];
  ```
</CodeGroup>

<AccordionGroup>
  <Accordion title="Mapping for AirbridgeOptionBuilder">
    | AirBridge                                                  | Default              | AirbridgeOptionBuilder                                                         | Default                           |
    | ---------------------------------------------------------- | -------------------- | ------------------------------------------------------------------------------ | --------------------------------- |
    | setLogLevel(ABLogLevel)                                    | LOG\_WARNING         | setLogLevel(AirbridgeLogLevel)                                                 | .warning                          |
    | setSDKEnabled(Bool)                                        | true                 | setSDKEnabled(Bool)                                                            | true                              |
    | setIsFacebookDeferredAppLinkEnabled(Bool)                  | false                | setTrackMetaDeferredAppLinkEnabled(Bool)                                       | false                             |
    | setAutoStartTrackingEnabled(Bool)                          | true                 | setAutoStartTrackingEnabled(Bool)                                              | true                              |
    | setting().trackingAuthorizeTimeout // UInt                 | 30000 (millisecond)  | setAutoDetermineTrackingAuthorizationTimeout(second: Double)                   | 300.0 (second) (0 \~ 1 hour)      |
    | setting().isRestartTrackingAuthorizeTimeout // Bool        | true                 | The feature has been removed.                                                  | -                                 |
    | deeplink().setDeeplinkCallback((String) -> Void)           | -                    | It has been replaced with another feature. Please refer to the deep link item. | -                                 |
    | deeplink().setDeferredDeeplinkCallback((String) -> Void)   | -                    | It has been replaced with another feature. Please refer to the deep link item. | -                                 |
    | deeplink().setHandleTrackingLinkTimeout(UInt)              | 3000 (millisecond)   | The feature has been removed. (Fixed at 3 seconds)                             | -                                 |
    | setIsUserInfoHashed(Bool)                                  | true                 | setHashUserInformationEnabled(Bool)                                            | true                              |
    | setSessionTimeout(Int)                                     | 300000 (millisecond) | setSessionTimeout(second: Double)                                              | 300.0 (second) (0 \~ 7 day)       |
    | setIsTrackAirbridgeDeeplinkOnly(Bool)                      | false                | setTrackAirbridgeDeeplinkOnlyEnabled(Bool)                                     | false                             |
    | setSDKSignatureSecret(id: String, secret: String)          | -                    | setSDKSignature(id: String, secret: String)                                    | -                                 |
    | setResetEventBufferEnabled(Bool)                           | false                | setClearEventBufferOnInitializeEnabled(Bool)                                   | false                             |
    | setting().isResetEventBufferEnabled // Bool                | false                | setClearEventBufferOnInitializeEnabled(Bool)                                   | false                             |
    | setting().setEventMaximumBufferCount(UInt)                 | INT\_MAX             | setEventBufferCountLimit(Int)                                                  | INT\_MAX                          |
    | setting().setEventMaximumBufferCount(UInt)                 | INT\_MAX (byte)      | setEventBufferSizeLimit(gibibyte: Double)                                      | 1024 (gibibyte) (0 \~ 1 tebibyte) |
    | setting().setEventTransmitInterval(UInt)                   | 0 (millisecond)      | setEventTransmitInterval(second: Double)                                       | 0 (second) (0 \~ 1 day)           |
    | setting().attributionCallback((\[String: String]) -> Void) | -                    | setOnAttributionReceived((\[String: String]) -> Void)                          | -                                 |
  </Accordion>

  <Accordion title="Example) AirbridgeOptionBuilder">
    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import Airbridge
      ...
      let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN")
          .setLogLevel(.warning)
          .setSessionTimeout(second: 300)
          .build()
      Airbridge.initializeSDK(option: option)
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #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];
      ```
    </CodeGroup>
  </Accordion>
</AccordionGroup>

### Deep Linking

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

<Accordion title="Required: Deep links">
  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.

  <CodeGroup>
    ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    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
        }
    }
    ```

    ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    #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
    ```
  </CodeGroup>
</Accordion>

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

<AccordionGroup>
  <Accordion title="Required task - Deeplink processing">
    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.

    <CodeGroup>
      ```swift SceneDelegate (Swift) lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      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)
              }
          }
      }
      ```

      ```swift AppDelegate (Swift) lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      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
          }
      }
      ```

      ```swift SwiftUI (Swift) lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      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)
                      }
              }
          }
      }
      ```

      ```objective-c SceneDelegate (Objective-C) lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #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
      ```

      ```objective-c AppDelegate (Objective-C) lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #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
      ```
    </CodeGroup>

    <Note>
      `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.
    </Note>
  </Accordion>

  <Accordion title="Required: Deferred deep links">
    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.

    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      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)
          }
      }
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #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];
          }
      }];
      ```
    </CodeGroup>

    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.
  </Accordion>
</AccordionGroup>

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.

<Accordion title="Required: Custom domains">
  Please call the setTrackingLinkCustomDomains function in the SDK initialization code.

  <CodeGroup>
    ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    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)
    ```

    ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    #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];
    ```
  </CodeGroup>
</Accordion>

### In-app event and user data

<Danger>
  **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.
</Danger>

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.

<AccordionGroup>
  <Accordion title="Mapping for AirbridgeCategory">
    | ABCategory        | AirbridgeCategory       |
    | ----------------- | ----------------------- |
    | signIn            | SIGN\_IN                |
    | signUp            | SIGN\_UP                |
    | signOut           | SIGN\_OUT               |
    | viewHome          | HOME\_VIEWED            |
    | viewProductList   | PRODUCT\_LIST\_VIEWED   |
    | viewSearchResult  | SEARCH\_RESULTS\_VIEWED |
    | viewProductDetail | PRODUCT\_VIEWED         |
    | addToCart         | ADDED\_TO\_CART         |
    | purchase          | ORDER\_COMPLETED        |
  </Accordion>

  <Accordion title="Mapping for AirbridgeAttribute">
    | ABSemanticsKey | AirbridgeAttribute          |
    | -------------- | --------------------------- |
    | products       | PRODUCTS                    |
    | transactionID  | TRANSACTION\_ID             |
    | inAppPurchased | IN\_APP\_PURCHASED          |
    | cartID         | CART\_ID                    |
    | query          | QUERY                       |
    | productListID  | PRODUCT\_LIST\_ID           |
    | currency       | CURRENCY                    |
    | totalValue     | Removed. Use VALUE instead. |
    | totalQuantity  | TOTAL\_QUANTITY             |

    | ABProductKey | AirbridgeAttribute |
    | ------------ | ------------------ |
    | productID    | PRODUCT\_ID        |
    | name         | PRODUCT\_NAME      |
    | price        | PRODUCT\_PRICE     |
    | currency     | PRODUCT\_CURRENCY  |
    | position     | PRODUCT\_POSITION  |
    | quantity     | PRODUCT\_QUANTITY  |
  </Accordion>

  <Accordion title="Example) Airbridge.trackEvent function">
    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      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",
          ]
      )
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #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",
      }];
      ```
    </CodeGroup>
  </Accordion>
</AccordionGroup>

`The AirBridge.setDeviceAlias` related functions have been replaced with [AirBridge.setDeviceAlias](/en/developers/ios-sdk-v4#configure-device-ids) related functions.

<CodeGroup>
  ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  import Airbridge
  ...
  Airbridge.setDeviceAlias(key: "string", value: "string")
  Airbridge.removeDeviceAlias(key: "string")
  Airbridge.clearDeviceAlias()
  ```

  ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  #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
  }
  ```
</CodeGroup>

`The AirBridge.state().setUser` related functions have been replaced with [Airbridge.setUser](/en/developers/ios-sdk-v4#set-additional-user-properties) related functions. The `setUser` function that sets user information at once is not supported.

<CodeGroup>
  ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  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()
  ```

  ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  #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];
  ```
</CodeGroup>

### Additional settings

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

<CodeGroup>
  ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  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
  }
  ```

  ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  #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
  }
  ```
</CodeGroup>

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

<CodeGroup>
  ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  import Airbridge
  ...
  Airbridge.setWebInterface(
      controller: controller,
      webToken: "YOUR_WEB_TOKEN"
  )
  ```

  ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  #import <Airbridge/Airbridge.h>
  ...
  [Airbridge setWebInterfaceWithController:controller webToken:@"YOUR_WEB_TOKEN"];
  ```
</CodeGroup>

## Update within v1.x

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

### v1.36.0 - Deep Link

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.

### v1.34.0 - Deep Link

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](https://app.airbridge.io/supports).

### 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.

<link rel="alternate" hrefLang="en" href="https://help.airbridge.io/en/developers/migration-guide-for-ios-sdk-v4" />

<link rel="alternate" hrefLang="ko" href="https://help.airbridge.io/ko/developers/migration-guide-for-ios-sdk-v4" />
