> ## 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 마이그레이션 가이드 - 플러터 SDK

에어브릿지 플러터 SDK의 업데이트에 필요한 사항을 확인할 수 있습니다. 현재 버전 이후부터 업데이트 이후 버전까지의 사항을 모두 확인하는 것을 권장합니다.

## v3.x에서 v4.0으로 업데이트

에어브릿지 플러터 SDK를 v4.0으로 업데이트하면 확인해 주세요.

<Accordion title="전체 변경사항">
  #### 옵션

  | airbridge.json (v3)             | airbridge.json (v4)                               | 변경점              |
  | ------------------------------- | ------------------------------------------------- | ---------------- |
  | -                               | sdkEnabled                                        | 새로운 기능이 추가되었습니다. |
  | logLevel                        | logLevel                                          | -                |
  | autoStartTrackingEnabled        | autoStartTrackingEnabled                          | -                |
  | trackingAuthorizeTimeoutSeconds | autoDetermineTrackingAuthorizationTimeoutInSecond | 이름이 변경되었습니다.     |
  | facebookDeferredAppLinkEnabled  | trackMetaDeferredAppLinkEnabled                   | 이름이 변경되었습니다.     |
  | sessionTimeoutSeconds           | sessionTimeoutInSecond                            | 이름이 변경되었습니다.     |
  | metaInstallReferrer             | metaInstallReferrerAppID                          | 이름이 변경되었습니다.     |
  | trackAirbridgeLinkOnly          | trackAirbridgeDeeplinkOnlyEnabled                 | 이름이 변경되었습니다.     |
  | -                               | trackInSessionLifecycleEventEnabled               | 새로운 기능이 추가되었습니다. |
  | userInfoHashEnabled             | hashUserInformationEnabled                        | 이름이 변경되었습니다.     |
  | sdkSignatureSecretID            | sdkSignatureID                                    | 이름이 변경되었습니다.     |
  | sdkSignatureSecret              | sdkSignatureSecret                                | 이름이 변경되었습니다.     |
  | -                               | clearEventBufferOnInitializeEnabled               | 새로운 기능이 추가되었습니다. |
  | -                               | eventBufferCountLimit                             | 새로운 기능이 추가되었습니다. |
  | -                               | eventBufferSizeLimitInGibibyte                    | 새로운 기능이 추가되었습니다. |
  | -                               | eventTransmitIntervalInSecond                     | 새로운 기능이 추가되었습니다. |

  #### 함수 (Flutter)

  | Airbridge (v3)         | Airbridge (v4)                  | 변경점                                   |
  | ---------------------- | ------------------------------- | ------------------------------------- |
  | setAttributionListener | setOnAttributionReceived        | 이름이 변경되었습니다.                          |
  | setDeeplinkListener    | setOnDeeplinkReceived           | 이름이 변경되었습니다.                          |
  | event.trackEvent       | trackEvent                      | 이름이 변경되었습니다. 어트리뷰트를 입력받는 방식이 변경되었습니다. |
  | state.deviceUUID       | fetchDeviceUUID                 | 이름이 변경되었습니다. 값을 콜백으로 제공하도록 변경되었습니다.   |
  | -                      | fetchAirbridgeGeneratedUUID     | 새로운 기능이 추가되었습니다.                      |
  | -                      | isUninstallTrackingNotification | 새로운 기능이 추가되었습니다.                      |
  | placement.click        | click                           | 이름이 변경되었습니다. 콜백 기능이 추가되었습니다.          |
  | placement.impression   | impression                      | 이름이 변경되었습니다. 콜백 기능이 추가되었습니다.          |
  | state.setUser          | -                               | User 관련 함수들로 대체되었습니다.                 |
  | state.updateUser       | -                               | User 관련 함수들로 대체되었습니다.                 |
  | -                      | setUserID                       | 새로운 기능이 추가되었습니다.                      |
  | -                      | clearUserID                     | 새로운 기능이 추가되었습니다.                      |
  | -                      | setUserEmail                    | 새로운 기능이 추가되었습니다.                      |
  | -                      | clearUserEmail                  | 새로운 기능이 추가되었습니다.                      |
  | -                      | setUserPhone                    | 새로운 기능이 추가되었습니다.                      |
  | -                      | clearUserPhone                  | 새로운 기능이 추가되었습니다.                      |
  | -                      | setUserAttribute                | 새로운 기능이 추가되었습니다.                      |
  | -                      | removeUserAttribute             | 새로운 기능이 추가되었습니다.                      |
  | -                      | clearUserAttributes             | 새로운 기능이 추가되었습니다.                      |
  | -                      | setUserAlias                    | 새로운 기능이 추가되었습니다.                      |
  | -                      | removeUserAlias                 | 새로운 기능이 추가되었습니다.                      |
  | -                      | clearUserAlias                  | 새로운 기능이 추가되었습니다.                      |
  | -                      | clearUser                       | 새로운 기능이 추가되었습니다.                      |
  | setDeviceAlias         | setDeviceAlias                  | -                                     |
  | removeDeviceAlias      | removeDeviceAlias               | -                                     |
  | clearDeviceAlias       | clearDeviceAlias                | -                                     |
  | registerPushToken      | registerPushToken               | -                                     |
  | -                      | enableSDK                       | 새로운 기능이 추가되었습니다.                      |
  | -                      | disableSDK                      | 새로운 기능이 추가되었습니다.                      |
  | -                      | isSDKEnabled                    | 새로운 기능이 추가되었습니다.                      |
  | state.startTracking    | startTracking                   | 이름이 변경되었습니다.                          |
  | -                      | stopTracking                    | 새로운 기능이 추가되었습니다.                      |
  | -                      | isTrackingEnabled               | 새로운 기능이 추가되었습니다.                      |
  | createWebInterface     | -                               | WebInterface 관련 함수들로 대체되었습니다.         |
  | -                      | createWebInterfaceScript        | 새로운 기능이 추가되었습니다.                      |
  | -                      | handleWebInterfaceCommand       | 새로운 기능이 추가되었습니다.                      |

  #### 상수 (Flutter)

  | AirbridgeCategory (v3)  | AirbridgeCategory (v4)  | 변경점 |
  | ----------------------- | ----------------------- | --- |
  | SIGN\_UP                | SIGN\_UP                | -   |
  | SIGN\_IN                | SIGN\_IN                | -   |
  | SIGN\_OUT               | SIGN\_OUT               | -   |
  | HOME\_VIEWED            | HOME\_VIEWED            | -   |
  | PRODUCT\_LIST\_VIEWED   | PRODUCT\_LIST\_VIEWED   | -   |
  | SEARCH\_RESULTS\_VIEWED | SEARCH\_RESULTS\_VIEWED | -   |
  | PRODUCT\_VIEWED         | PRODUCT\_VIEWED         | -   |
  | ADD\_PAYMENT\_INFO      | ADD\_PAYMENT\_INFO      | -   |
  | ADD\_TO\_WISHLIST       | ADD\_TO\_WISHLIST       | -   |
  | ADD\_TO\_CART           | ADDED\_TO\_CART         | -   |
  | INITIATE\_CHECKOUT      | INITIATE\_CHECKOUT      | -   |
  | ORDER\_COMPLETED        | ORDER\_COMPLETED        | -   |
  | ORDER\_CANCELED         | ORDER\_CANCELED         | -   |
  | START\_TRIAL            | START\_TRIAL            | -   |
  | SUBSCRIBE               | SUBSCRIBE               | -   |
  | UNSUBSCRIBE             | UNSUBSCRIBE             | -   |
  | AD\_IMPRESSION          | AD\_IMPRESSION          | -   |
  | AD\_CLICK               | AD\_CLICK               | -   |
  | COMPLETE\_TUTORIAL      | COMPLETE\_TUTORIAL      | -   |
  | ACHIEVE\_LEVEL          | ACHIEVE\_LEVEL          | -   |
  | UNLOCK\_ACHIEVEMENT     | UNLOCK\_ACHIEVEMENT     | -   |
  | RATE                    | RATE                    | -   |
  | SHARE                   | SHARE                   | -   |
  | SCHEDULE                | SCHEDULE                | -   |
  | SPEND\_CREDITS          | SPEND\_CREDITS          | -   |

  | AirbridgeAttributes (v3)              | AirbridgeAttribute (v4)               | 변경점              |
  | ------------------------------------- | ------------------------------------- | ---------------- |
  | -                                     | ACTION                                | 새로운 기능이 추가되었습니다. |
  | -                                     | LABEL                                 | 새로운 기능이 추가되었습니다. |
  | -                                     | VALUE                                 | 새로운 기능이 추가되었습니다. |
  | TOTAL\_VALUE                          | -                                     | VALUE로 대체되었습니다.  |
  | CURRENCY                              | CURRENCY                              | -                |
  | ORIGINAL\_CURRENCY                    | ORIGINAL\_CURRENCY                    | -                |
  | PRODUCTS                              | PRODUCTS                              | -                |
  | PERIOD                                | PERIOD                                | -                |
  | IS\_RENEWAL                           | IS\_RENEWAL                           | -                |
  | RENEWAL\_COUNT                        | RENEWAL\_COUNT                        | -                |
  | PRODUCT\_LIST\_ID                     | PRODUCT\_LIST\_ID                     | -                |
  | CART\_ID                              | CART\_ID                              | -                |
  | TRANSACTION\_ID                       | TRANSACTION\_ID                       | -                |
  | TRANSACTION\_TYPE                     | TRANSACTION\_TYPE                     | -                |
  | TRANSACTION\_PAIRED\_EVENT\_CATEGORY  | TRANSACTION\_PAIRED\_EVENT\_CATEGORY  | -                |
  | TRANSACTION\_PAIRED\_EVENT\_TIMESTAMP | TRANSACTION\_PAIRED\_EVENT\_TIMESTAMP | -                |
  | TOTAL\_QUANTITY                       | TOTAL\_QUANTITY                       | -                |
  | QUERY                                 | QUERY                                 | -                |
  | IN\_APP\_PURCHASED                    | IN\_APP\_PURCHASED                    | -                |
  | CONTRIBUTION\_MARGIN                  | CONTRIBUTION\_MARGIN                  | -                |
  | ORIGINAL\_CONTRIBUTION\_MARGIN        | ORIGINAL\_CONTRIBUTION\_MARGIN        | -                |
  | LIST\_ID                              | LIST\_ID                              | -                |
  | RATE\_ID                              | RATE\_ID                              | -                |
  | RATE                                  | RATE                                  | -                |
  | MAX\_RATE                             | MAX\_RATE                             | -                |
  | ACHIEVEMENT\_ID                       | ACHIEVEMENT\_ID                       | -                |
  | SHARED\_CHANNEL                       | SHARED\_CHANNEL                       | -                |
  | DATE\_TIME                            | DATE\_TIME                            | -                |
  | DESCRIPTION                           | DESCRIPTION                           | -                |
  | IS\_REVENUE                           | IS\_REVENUE                           | -                |
  | PLACE                                 | PLACE                                 | -                |
  | SCHEDULE\_ID                          | SCHEDULE\_ID                          | -                |
  | TYPE                                  | TYPE                                  | -                |
  | LEVEL                                 | LEVEL                                 | -                |
  | SCORE                                 | SCORE                                 | -                |
  | AD\_PARTNERS                          | AD\_PARTNERS                          | -                |
  | IS\_FIRST\_PER\_USER                  | IS\_FIRST\_PER\_USER                  | -                |

  | AirbridgeProduct (v3)   | AirbridgeAttribute (v4) | 변경점 |
  | ----------------------- | ----------------------- | --- |
  | PRODUCT\_ID             | PRODUCT\_ID             | -   |
  | PRODUCT\_NAME           | PRODUCT\_NAME           | -   |
  | PRODUCT\_PRICE          | PRODUCT\_PRICE          | -   |
  | PRODUCT\_QUANTITY       | PRODUCT\_QUANTITY       | -   |
  | PRODUCT\_CURRENCY       | PRODUCT\_CURRENCY       | -   |
  | PRODUCT\_POSITION       | PRODUCT\_POSITION       | -   |
  | PRODUCT\_CATEGORY\_ID   | PRODUCT\_CATEGORY\_ID   | -   |
  | PRODUCT\_CATEGORY\_NAME | PRODUCT\_CATEGORY\_NAME | -   |
  | PRODUCT\_BRAND\_ID      | PRODUCT\_BRAND\_ID      | -   |
  | PRODUCT\_BRAND\_NAME    | PRODUCT\_BRAND\_NAME    | -   |

  #### 함수 (iOS)

  | AirbridgeRN (v3)                 | AirbridgeReactNative (v4) | 변경점          |
  | -------------------------------- | ------------------------- | ------------ |
  | getInstance                      | initializeSDK             | 이름이 변경되었습니다. |
  | deeplink.handleURLSchemeDeeplink | trackDeeplink             | 이름이 변경되었습니다. |
  | deeplink.handleUserActivity      | trackDeeplink             | 이름이 변경되었습니다. |

  #### 함수 (Android)

  | AirbridgeRN (v3)        | AirbridgeReactNative (v4) | 변경점          |
  | ----------------------- | ------------------------- | ------------ |
  | init                    | initializeSDK             | 이름이 변경되었습니다. |
  | processDeeplinkData     | trackDeeplink             | 이름이 변경되었습니다. |
  | setLifecycleIntegration | setLifecycleIntegration   | -            |
</Accordion>

### SDK 설치 및 초기화

`airbridge.json` 의 위치가 변경되었습니다. `assets/airbridge.json` 파일을 플러터 프로젝트 폴더 최상단의 `airbridge.json` 파일로 위치를 이동해주세요.

`airbridge.json` 의 키값이 변경되었습니다. 아래와 같이 키값을 변경해 주세요.

| airbridge.json (v3)             | airbridge.json (v4)                               |
| ------------------------------- | ------------------------------------------------- |
| trackingAuthorizeTimeoutSeconds | autoDetermineTrackingAuthorizationTimeoutInSecond |
| facebookDeferredAppLinkEnabled  | trackMetaDeferredAppLinkEnabled                   |
| sessionTimeoutSeconds           | sessionTimeoutInSecond                            |
| metaInstallReferrer             | metaInstallReferrerAppID                          |
| trackAirbridgeLinkOnly          | trackAirbridgeDeeplinkOnlyEnabled                 |
| userInfoHashEnabled             | hashUserInformationEnabled                        |
| sdkSignatureSecretID            | sdkSignatureID                                    |
| sdkSignatureSecret              | sdkSignatureSecret                                |

iOS의 `AirbridgeFlutter.init` 함수가 `AirbridgeFlutter.initializeSDK` 함수로 대체되었습니다. `ios/YOUR_PROJECT_NAME/AppDelegate.swift` 파일을 수정해 주세요.

```diff lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
- override func application(
-     _ application: UIApplication,
-     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
- ) -> Bool {
-     AirbridgeFlutter.init(
-         appName: "YOUR_APP_NAME",
-         appToken: "YOUR_APP_SDK_TOKEN",
-         withLaunchOptions: launchOptions
-     )
- }
+ override func application(
+     _ application: UIApplication,
+     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
+ ) -> Bool {
+     AirbridgeFlutter.initializeSDK(
+         name: "YOUR_APP_NAME",
+         token: "YOUR_APP_SDK_TOKEN",
+     )
+ }
```

안드로이드의 `AirbridgeFlutter.init` 함수가 `AirbridgeFlutter.initializeSDK` 함수로 대체되었습니다. `android/app/src/main/java/.../MainApplication.kt` 파일을 수정해 주세요.

```diff lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
- import co.ab180.airbridge.flutter.AirbridgeFlutter
- ...
- override fun onCreate() {
-     super.onCreate()
-     AirbridgeFlutter.init(this, "YOUR_APP_NAME", "YOUR_APP_SDK_TOKEN")
-     ...
- }
+ import co.ab180.airbridge.flutter.AirbridgeFlutter
+ ...
+ override fun onCreate() {
+     super.onCreate()
+     AirbridgeFlutter.initializeSDK(this, "YOUR_APP_NAME", "YOUR_APP_SDK_TOKEN")
+     ...
+ }
```

### 딥링크

`Airbridge.setDeeplinkListener` 함수가 `Airbridge.setOnDeeplinkReceived` 함수로 대체되었습니다.

```diff lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
- import 'package:airbridge_flutter_sdk/airbridge_flutter_sdk.dart';
- ...
- Airbridge.setDeeplinkListener((url) => {
-     // show proper content
- })
+ import 'package:airbridge_flutter_sdk/airbridge_flutter_sdk.dart';
+ ...
+ Airbridge.setOnDeeplinkReceived((url) => {
+     // show proper content
+ })
```

iOS의 `AirbridgeFlutter.deeplink.handleURLSchemeDeeplink` , `AirbridgeFlutter.deeplink.handleUserActivity` 함수가 `AirbridgeFlutter.trackDeeplink` 함수로 대체되었습니다.

```diff lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
- override func application(
-     _ application: UIApplication,
-     continue userActivity: NSUserActivity,
-     restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
- ) -> Bool {
-     AirbridgeFlutter.deeplink.handle(userActivity)
-     
-     return true
- }
- 
- override func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
-     AirbridgeFlutter.deeplink.handleURLSchemeDeeplink(url)
-     
-     return true
- }
+ override func application(
+     _ application: UIApplication,
+     continue userActivity: NSUserActivity,
+     restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
+ ) -> Bool {
+     AirbridgeFlutter.trackDeeplink(userActivity: userActivity)
+     
+     return true
+ }
+ 
+ override func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
+     AirbridgeFlutter.trackDeeplink(url: url)
+     
+     return true
+ }
```

안드로이드의 `AirbridgeFlutter.processDeeplinkData` 함수가 `AirbridgeFlutter.trackDeeplink` 함수로 대체되었습니다.

```diff lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
- import co.ab180.airbridge.flutter.AirbridgeFlutter
- ...
- override fun onResume() {
-   super.onResume()
-   AirbridgeFlutter.processDeeplinkData(intent)
- }
+ import co.ab180.airbridge.flutter.AirbridgeFlutter
+ ...
+ override fun onResume() {
+   super.onResume()
+   AirbridgeFlutter.trackDeeplink(intent)
+ }
```

<Danger>
  **알립니다**

  Flutter SDK v.3.7부터 외부 플러그인 없이 앱 내에서 딥링크를 직접 처리할 수 있도록 딥링크 기능이 개선되었습니다. 그러나 오작동 방지를 위해서 플랫폼별로 다음 조치가 반드시 필요합니다.

  * Android: AndroidManifest.xml 파일에서 `<meta-data android:name="flutter_deeplinking_enabled" android:value="false" />`로 설정하세요.
  * iOS: Info.plist 파일에서 `FlutterDeepLinkingEnabled` 키 값을 `NO` 로 설정하세요.
</Danger>

### 커스텀 도메인 설정하기

v2.x 에서 사용 되던 커스텀 도메인 주소 플랫폼 별로 설정하던 방식이 변경되었습니다.

에어브릿지 SDK 초기화시 airbridge.json 의 `trackingLinkCustomDomains`에 커스텀 도메인 링크를 추가 할 수 있습니다

```json lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
{
    "trackingLinkCustomDomains": ["YOUR_APP_CUSTOM_DOMAIN"]
}
```

### 인앱 이벤트 및 유저 정보

<Danger>
  **주의하세요**

  기존 `AirbridgeAttributes.TOTAL_VALUE` 대신 `AirbridgeAttribute.VALUE` 에 값을 입력해 주세요.

  `AirbridgeAttributes.TOTAL_VALUE` 를 사용하고 `value` 를 정의하면 `AirbridgeAttributes.TOTAL_VALUE` 가 `value` 를 덮어 쓰는 로직은 Flutter SDK v4부터 삭제되었습니다.
</Danger>

`Airbridge.event.trackEvent` 함수가 `Airbridge.trackEvent` 함수로 대체되었습니다.

아래 예시코드를 따라 `Airbridge.event.trackEvent` 함수를 `Airbridge.trackEvent`함수로 변경해 주세요.

```diff lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
- import 'package:airbridge_flutter_sdk/airbridge_flutter_sdk.dart';
- ...
- Airbridge.event.trackEvent(
-     'event',
-     AirbridgeEventOption(
-         action: '...',
-         label: '...',
-         value: 100,
-         semanticAttributes: {
-             AirbridgeAttributes.QUERY: '...',
-         },
-         customAttributes: {
-             'key1': '...',
-             'key2': '...',
-             'key3': '...',
-         },
-     ));
+ import 'package:airbridge_flutter_sdk/airbridge_flutter_sdk.dart';
+ ...
+ Airbridge.trackEvent(
+     category: 'event',
+     semanticAttributes: {
+         AirbridgeAttribute.ACTION: '...',
+         AirbridgeAttribute.LABEL: '...',
+         AirbridgeAttribute.VALUE: 100,
+         AirbridgeAttribute.QUERY: '...',
+     },
+     customAttributes: {
+             'key1': '...',
+             'key2': '...',
+             'key3': '...',
+     });
```

<Danger>
  **주의하세요**

  `Airbridge.event.trackEvent` 함수의 두 번째 파라미터에 해당하는 `action` , `label` , `value` , `semanticAttributes` 값은 `Airbridge.trackEvent` 함수의 두 번째 파라미터에 포함되어야 합니다.

  `Airbridge.event.trackEvent` 함수의 두 번째 파라미터에 해당하는 `customAttributes` 값은 `Airbridge.trackEvent` 함수의 세 번째 파라미터에 포함되어야 합니다.
</Danger>

`Airbridge.state.setUser` , `Airbridge.state.updateUser` 함수가 [Airbridge.setUser](/ko/developers/flutter-sdk-v4#유저-속성-설정하기) 관련 함수로 대체되었습니다. 유저 정보를 한번에 설정하는 `setUser` , `updateUser` 함수는 지원하지 않습니다.

```diff lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
- import 'package:airbridge_flutter_sdk/airbridge_flutter_sdk.dart';
- ...
- Airbridge.state.setUser(
-     User(
-         id: '...',
-         email: '...'
-     ));
- Airbridge.state.updateUser(
-     User(
-         phone: '...'
-     ));
+ import 'package:airbridge_flutter_sdk/airbridge_flutter_sdk.dart';
+ ...
+ Airbridge.setUserID('...')
+ Airbridge.setUserEmail('...')
+ Airbridge.setUserPhone('...')
```

### 추가 설정하기

`Airbridge.setAttributionListener` 함수가 `Airbridge.setOnAttributionReceived` 함수로 대체되었습니다.

```diff lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
- import 'package:airbridge_flutter_sdk/airbridge_flutter_sdk.dart';
- ...
- Airbridge.setAttributionListener((attribution) {
-     // using attribution
- });
+ import 'package:airbridge_flutter_sdk/airbridge_flutter_sdk.dart';
+ ...
+ Airbridge.setOnAttributionReceived((attribution) {
+     // using attribution
+ });
```

`Airbridge.placement.click` , `Airbridge.placement.impression` 함수가 `Airbridge.click` , `Airbridge.impression` 함수로 대체되었습니다.

```diff lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
- import 'package:airbridge_flutter_sdk/airbridge_flutter_sdk.dart';
- ...
- Airbridge.placement.click(url);
- Airbridge.placement.impression(url);
+ import 'package:airbridge_flutter_sdk/airbridge_flutter_sdk.dart';
+ ...
+ Airbridge.click(url);
+ Airbridge.impression(url);
```

`Airbridge.createWebInterface` 함수가 `Airbridge.createWebInterfaceScript` , `Airbridge.handleWebInterfaceCommand` 함수로 대체되었습니다.

```diff lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
- var webInterface = Airbridge.createWebInterface(
-     webToken: 'YOUR_WEB_TOKEN',
-     postCommandFunction: (arg) {
-       return """window.flutter_inappwebview.callHandler('postMessage', $arg);"""; 
-   });
- ...
- InAppWebView(
-   initialUrlRequest: URLRequest(url: WebUri('https://...')),
-   onWebViewCreated: (controller) async {
-     controller.addJavaScriptHandler(handlerName: 'postMessage', callback: (args) {
-       webInterface.handle(args[0]);
-       return args;
-     });
-   },
-   initialUserScripts: UnmodifiableListView<UserScript>([
-     UserScript(
-       source: webInterface.script, 
-       injectionTime: UserScriptInjectionTime.AT_DOCUMENT_START)
-   ]),
-   ...
- )
- ...
+ Future<String?> getJavascriptInterface() async {
+     return await Airbridge.createWebInterfaceScript(
+       webToken: 'YOUR_WEB_TOKEN',
+       postMessageScript: 'window.flutter_inappwebview.callHandler(payload);',
+     );
+   }
+ ...
+ FutureBuilder(
+   future: getJavascriptInterface(),
+   builder: (BuildContext context, AsyncSnapshot snapshot) {
+     return 
+       ...
+       InAppWebView(
+         initialUrlRequest: URLRequest(url: WebUri('https://...')),
+         onWebViewCreated: (controller) async {
+           controller.addJavaScriptHandler(handlerName: 'postMessage', callback: (args) {
+             Airbridge.handleWebInterfaceCommand(args[0]);
+             return args;
+           });
+         },
+         initialUserScripts: UnmodifiableListView<UserScript>([
+           UserScript(
+             source: snapshot.data ?? "", 
+             injectionTime: UserScriptInjectionTime.AT_DOCUMENT_START)
+         ]),
+       )
+       ...
+   });
+ ...
```

## v3.x 업데이트

플러터 SDK 각 버전의 주요 변경사항을 참고해 주세요.

### v3.5.0 - 딥링크

딥링크 콜백에서 제공하는 딥링크 URL이 에어브릿지 대시보드에 입력된 내용을 2번 디코딩하는 문제가 해결됐습니다. 3.4.2에서 3.4.7 버전과 2023년 9월 4일 이후에 생성된 에어브릿지 앱이 대상입니다.

### v3.4.2 - 딥링크

2023년 9월 4일 이후에 생성된 에어브릿지 앱에는 딥링크 콜백에서 제공하는 딥링크 URL에 airbridge\_referrer가 추가되지 않습니다.

ios app을 업데이트하면 마지막으로 계산된 SKAdNetwork Conversion Value 로 확정됩니다. 추가적인 계산은 진행하지 않습니다.

* 3.4.2 미만 버전에서는 SKAdNetwork Conversion Value 를 최대 24시간 동안만 계산합니다.
* 새롭게 앱을 설치하는 유저는 해당하지 않습니다.

`deeplink.page` 가 deprecated 되었습니다. 3.4.2 부터는 `abr.ge` 로 딥링크 도메인을 사용해 코드를 작성하는 것을 권장합니다.

* `deeplink.page` 는 하위 호환을 위해 계속 지원 및 동작할 예정입니다.

### v3.4.1 - kotlin

kotlin plugin version 을 1.5.21 로 업데이트 하였습니다.

### v3.4.0 - 개인정보보호 설정

trackingAuthorizeTimeout 의 기본값이 30초로 변경됩니다.

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

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