Flutter SDK

    SDK Installation


    version v3.3.0

    Package Installation

    pubspec Setup

    Please add the following dependency under the dependencies block in your pubspec.yaml file

    12
    dependencies:
      airbridge_flutter_sdk: 3.4.3

    Open Terminal at the topmost level of the project and execute the following command.

    Shell
    1
    flutter pub get

    The Airbridge Flutter SDK supports >= Flutter 1.20.0 and >= Dart 2.12.0

    Project Setup

    airbridge.json

    1. Please add the following under the flutter/assetsblock in your pubspec.yamlfile.

    123
    flutter:
      assets:
        - assets/airbridge.json
    1. Create an assets/airbridge.jsonfile at the topmost level of the project.

    2. Configure settings in JSON format.

    1234567891011
    {
        "sessionTimeoutSeconds": 300,
        "autoStartTrackingEnabled": true,
        "userInfoHashEnabled": true,
        "trackAirbridgeLinkOnly": false,
        "facebookDeferredAppLinkEnabled": false,
        "locationCollectionEnabled": false,
        "trackingAuthorizeTimeoutSeconds": 0,
        "sdkSignatureSecretID": "YOUR_SDK_SIGNATURE_SECRET_ID",
        "sdkSignatureSecret": "YOUR_SDK_SIGNATURE_SECRET"
    }

    iOS Setup

    Add the following code to the ios/[Project Name]/AppDelegate.m file.

    12345678
    import airbridge_flutter_sdk
    
    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
      ) -> Bool {
        AirbridgeFlutter.initSDK(appName: "YOUR_APP_NAME", appToken: "YOUR_APP_TOKEN", withLaunchOptions: launchOptions)
    }

    APP_NAME can be found on the dashboard at Settings → Tokens → App Name. APP_TOKEN can be found on the dashboard at Settings → Tokens → App SDK Token.

    Android Setup

    Add the following code to the onCreate function within the android/app/src/main/java/.../MainApplication.java file.

    12345678910
    import co.ab180.airbridge.flutter.AirbridgeFlutter;
    import io.flutter.app.FlutterApplication;
    
    public class MainApplication extends FlutterApplication {
        @Override
        public void onCreate() {
            super.onCreate();
            AirbridgeFlutter.init(this, "YOUR_APP_NAME", "YOUR_APP_TOKEN");
        }
    }

    APP_NAME can be found on the dashboard at Settings → Tokens → App Name. APP_TOKEN can be found on the dashboard at Settings → Tokens → App SDK Token.

    Register the MainApplication class created above in the AndroidManifest.xml file.

    12345
    <application
        android:name=".MainApplication"
        ...>
        ...
    </application>

    Common Settings

    airbridge.json

    1. Add an airbridge.jsonfile to the project folder.

    2. Configure settings in JSON format.

    123456789101112
    {
        "sessionTimeoutSeconds": 300,
        "autoStartTrackingEnabled": true,
        "userInfoHashEnabled": true,
        "trackAirbridgeLinkOnly": false,
        "facebookDeferredAppLinkEnabled": false,
        "locationCollectionEnabled": false,
        "trackingAuthorizeTimeoutSeconds": 30,
        "sdkSignatureSecretID": "YOUR_SDK_SIGNATURE_SECRET_ID",
        "sdkSignatureSecret": "YOUR_SDK_SIGNATURE_SECRET",
        "logLevel": "warning"
    }

    Attention

    trackingAuthorizeTimeoutSeconds in the above code is the default value (0). Please adjust accordingly depending on your user experience and ATT prompt settings. Refer to ]Tracking Authorize Timeout Settings for more details.

    Name

    Type

    Default

    Description

    sessionTimeoutSeconds

    Number

    300

    An app open event will not be sent when the app is reopened within the designated period.

    autoStartTrackingEnabled

    Boolean

    true

    When set to false, no events will be sent until Airbridge.state.startTracking() is called.

    userInfoHashEnabled

    Boolean

    true

    When set to false, user email and user phone information are sent without being hashed.

    trackAirbridgeLinkOnly

    Boolean

    false

    When set to true, deep link events are sent only when app is opened with an Airbridge deep link.

    facebookDeferredAppLinkEnabled

    Boolean

    false

    When set to true and the Facebook SDK is installed, Facebook Deferred App Link data is collected.

    locationCollectionEnabled

    Boolean

    false

    When set to true, location information is collected. (Android Only)
    Two permissions must be allowed in AndroidManifest.xml
    android.permission.ACCESS_FINE_LOCATION
    android.permission.ACCESS_COARSE_LOCATION

    trackingAuthorizeTimeoutSeconds

    Number

    0

    When timeout is set, Install event is delayed until  Request tracking authorization alert is clicked. (iOS only)

    sdkSignatureSecretID

    String

    null

    Protects against SDK spoofing. Both sdkSignatureSecretID and sdkSignatureSecret values must be applied.

    sdkSignatureSecret

    String

    null

    Protects against SDK spoofing. Both sdkSignatureSecretID and sdkSignatureSecret values must be applied.

    logLevel

    String

    warning

    Adjusts the log record level for Airbridge.
    logLevel: "debug" | "info" | "warning" | "error" | "fault"

    Testing the SDK

    Check if install events are sent when the application is installed and opened.

    Check in the Airbridge Dashboard

    Events from the Airbridge SDK are shown at the "Airbridge Dashboard → Raw Data → App Real-time Logs".

    1. Go to Airbridge Dashboard → Raw Data → App Real-time Logs.

    2. Search for the device's ADID (IDFA, IDFV, GAID).

    Attention

    Logs may be delayed for up to 5 minutes.


    Dashboard Setup

    Please refer to the guides below to setup your deep links in the Airbridge dashboard.

    • iOS Deep Link Dashboard Setup Guide

    • Android Deep Link Dashboard Setup Guide

    Project Setup

    • URL Scheme Setup

    1. Go to "Xcode → Project file → Info → URL Types".

    2. From the Airbridge dashboard, copy "iOS URI Scheme" to Xcode's "URL Schemes". (Do not include://)

    • Universal Link Setup

    1. Go to "Xcode → Project file → Signing & Capabilities".

    2. Click "+ Capability" and add "Associated Domains".

    3. Add applinks:YOUR_APP_NAME.airbridge.ioto "Associated Domains".

    4. Add applinks:YOUR_APP_NAME.deeplink.pageto "Associated Domains".

    YOUR_APP_NAME can be found at the "Airbridge dashboard → Settings → Tokens → App Name".
    Please refer to Troubleshooting → Webcredentials if you want to use the autofill feature.

    • AppDelegate Setup

    1. Open ios/[Project name]/AppDelegate.

    2. Add the following methods. (handleUniversalLink, handleURLSchemeDeeplink)

    1234567891011121314151617
    override func application(
        _ application: UIApplication,
        continue userActivity: NSUserActivity,
        restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
    ) -> Bool {
        if let universalLink = userActivity.webpageURL {
            AirbridgeFlutter.deeplink.handleUniversalLink(universalLink)
        }
        
        return true
    }
    
    override func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
        AirbridgeFlutter.deeplink.handleURLSchemeDeeplink(url)
        
        return true
    }

    • AndroidManifest.xml Setup

    1. Open AndroidManifest.xml

    2. Add the following intent-filter to the activity that will process the deep link.

    123456789101112131415161718192021222324252627282930
    <activity ...>
        ...
        <intent-filter android:autoVerify="true">
            <action android:name="android.intent.action.VIEW" />
    
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
    
            <data android:scheme="http" android:host="YOUR_APP_NAME.deeplink.page" />
            <data android:scheme="https" android:host="YOUR_APP_NAME.deeplink.page" />
        </intent-filter>
        <intent-filter android:autoVerify="true">
            <action android:name="android.intent.action.VIEW" />
    
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
    
            <data android:scheme="http" android:host="YOUR_APP_NAME.airbridge.io" />
            <data android:scheme="https" android:host="YOUR_APP_NAME.airbridge.io" />
        </intent-filter>
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
    
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
    
            <data android:scheme="YOUR_APP_URI_SCHEME" />
        </intent-filter>
        ...
    </activity>

    Enter your app name at YOUR_APP_NAME.
    Enter your scheme value set in the Airbridge dashboard at YOUR_APP_URI_SCHEME. (e.g. abc://)

    • MainActivity Setup

    Insert the following code to the android/app/src/main/java/.../MainActivity.java file.

    1234567891011
    @Override
    protected void onResume() {
        super.onResume()
        AirbridgeFlutter.processDeeplink(intent)
    }
    
    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent)
        setIntent(intent)
    }

    Callback Setup

    Register a function that will be called whenever a "deep link" or a "deferred deep link" opens the application.

    1234
    Airbridge.deeplink.setDeeplinkListener((deeplink) {
        // airbridge deeplink = SCHEME://...
        print('$deeplink');
    });

    If setDeeplinkListener is called from the main function, make sure that WidgetsFlutterBinding.ensureInitialized(); is called first.

    Custom Domain (Optional)

    Please refer to the below guides to setup your custom domain with Airbridge.

    Click on your URI scheme to test if your deep link has been properly set up in the Airbridge SDK.

    • YOUR_APP_URI_SCHEME://

    The results will show on the "Airbridge dashboard → Row Data → App Real-time Log" tab if everything is working.

    User Setup


    User Identifier Setup

    To measure the fragmented contributions of users between web and app, Airbridge collects the following user identifier information.

    • User Email: Email address

    • User Phone: Phone number

    • User ID: Unique User ID (The ID value that specifies the user must be the same in both web and mobile)

    • User Alias: Identifiers that can represent users (e.g. loyalty program ID, affiliate integrated ID, etc)

    The user's email and phone numbers are hashed (SHA256) by default and then sent to servers.

    You can set the user identifier as below for the Airbridge Flutter SDK.

    12345678910
    Airbridge.state.setUser(
        User(
        id: 'tester',
        email: 'tester@ab180.co',
        phone: '+82 10 0000-0000',
        alias: {
            'alias_key': 'alias_value',
        },
        )
    );

    Name

    Description

    Limitations

    id

    User ID

    -

    email

    User email

    Hashed by default
    (SHA256, can be disabled)

    phone

    User phone number

    Hashed by default
    (SHA256, can be disabled)

    alias

    User alias

    - Maximum 10 aliases
    - "key"type is String, maximum 128 characters
    -"key"must satisfy ^[a-z_][a-z0-9_]*$regex
    - `"value" type is String, maximum 1024 characters

    Once the user identifier has been configured, all events will be forwarded with the corresponding identity information.

    Attention

    The user identifier properties can be reset or overwritten through user events.

    Below is an example of how a particular field can be updated.

    12345
    Airbridge.state.updateUser(
        User(
            id: 'sam1234',
        )
    );

    User Attribute Setup

    Additional user attributes can be used for more accurate Multi-Touch Attribution (MTA) analyses, additional internal data analyses, and linking third-party solutions.

    1234567
    Airbridge.state.setUser(
        User(
        attributes: {
            'attr_key': 'attr_value',
        },
        )
    );

    Name

    Description

    Limitations

    attributes

    User attribute

    - Maximum 100 attributes
    - "key" type is string, maximum 128 characters
    - "key" must satisfy ^[a-z_][a-z0-9_]*$regex
    - "value" type is primitive or string
    - Maximum 1024 characters when "value" is string

    Attention

    The user attribute information can be reset or overwritten through user events.

    Testing

    Make sure that your user information settings are being properly sent through the SDK.

    1. Configure user identifier information.

    2. Send an event using the SDK.

    3. Click the event at "Airbridge dashboard → Raw Data → App Real-time Logs"

    4. Check if the user information is correctly sent under the userblock.

    Device Setup


    Setup Device Alias

    Setup a device alias through the Airbridge SDK. The alias will be sustained even after the app closes, unless otherwise deleted.

    123
    Airbridge.setDeviceAlias("ADD_YOUR_KEY", "AND_YOUR_VALUE");
    Airbridge.removeDeviceAlias("DELETE_THIS_KEY");
    Airbridge.clearDeviceAlias();

    setDeviceAlias(key: string, value: string)

    Add the key value pair to the device identifier.

    removeDeviceAlias(key: string)

    Delete the corresponding device alias.

    clearDeviceAlias()

    Delete all device aliases.

    Event Setup


    When important user actions occur, in-app events can be sent to measure performance by channel.

    All event parameters are optional. However, more information about the event will help provide a more accurate analysis.

    actionlabelvaluecustomAttributes and semanticAttributes can be used for event options.

    Name

    Type

    Description

    Event Category

    String

    Name of the event

    Required

    Event Action

    String

    Event attribute 1

    Event Label

    String

    Event attribute 2

    Event Value

    Float

    Event attribute value

    Custom Attributes

    Map<String, Object>

    Custom attributes

    Semantic Attributes

    Semantic Attributes Class

    Semantic attributes

    123
    static void trackEvent(String category, [ AirbridgeEventOption? option ]) {
        event.trackEvent(category, option);
    }

    User Events

    Send user events with the SDK.

    actionlabelvaluecustomAttributes and semanticAttributes can be used for user events.

    Sign Up

    User identifiers are set with setUser and then sent with AirbridgeCategory.SIGN_UP for user sign ups.

    123456
    Airbridge.state.setUser(User(
        id: 'tester',
        email: 'tester@ab180.co',
        phone: '+82 10 0000-0000',
    ));
    Airbridge.trackEvent(AirbridgeCategory.SIGN_UP);

    123456
    Airbridge.state.setUser(User(
        ID: 'test',
        email: 'test@ab180.co',
        phone: '000-0000-0000',
    ));
    Airbridge.trackEvent(AirbridgeCategory.SIGN_IN);

    12
    Airbridge.trackEvent(AirbridgeCategory.SIGN_OUT);
    Airbridge.state.setUser(User());

    Attention

    All user identifier properties will disappear after sign out is called.

    E-commerce Events

    Send e-commerce events with the SDK.

    actionlabelvaluecustomAttributes and semanticAttributes can be used for e-commerce events.
    It is possible to include product information using semanticAttributes. Custom key values can be used as well as the pre-defined values.

    View Home Screen

    1
    Airbridge.trackEvent(AirbridgeCategory.HOME_VIEW);

    View Product Detail

    123456789101112131415
    Airbridge.event.trackEvent(
      AirbridgeCategory.PRODUCT_DETAILS_VIEW,
      AirbridgeEventOption(
        semanticAttributes: {
          AirbridgeAttributes.PRODUCTS: [{
              AirbridgeProduct.PRODUCT_ID: 'coke_zero',
              AirbridgeProduct.NAME: 'Coke Zero',
              AirbridgeProduct.PRICE: 1.99,
              AirbridgeProduct.CURRENCY: 'USD',
              AirbridgeProduct.POSITION: 1,
              AirbridgeProduct.QUANTITY: 1,
            },
          ]
        }
    ));

    View Product List

    1234567891011121314151617181920212223
    Airbridge.event.trackEvent(
      AirbridgeCategory.PRODUCT_DETAILS_VIEW,
      AirbridgeEventOption(
        semanticAttributes: {
          AirbridgeAttributes.PRODUCT_LIST_ID: 'ID-1234567890',
          AirbridgeAttributes.PRODUCTS: [{
              AirbridgeProduct.PRODUCT_ID: 'coke_zero',
              AirbridgeProduct.NAME: 'Coke Zero',
              AirbridgeProduct.PRICE: 1.99,
              AirbridgeProduct.CURRENCY: 'USD',
              AirbridgeProduct.POSITION: 1,
              AirbridgeProduct.QUANTITY: 1,
            }, {
              AirbridgeProduct.PRODUCT_ID: 'burger_cheese_double',
              AirbridgeProduct.NAME: 'Double Cheeseburger',
              AirbridgeProduct.PRICE: 3.99,
              AirbridgeProduct.CURRENCY: 'USD',
              AirbridgeProduct.POSITION: 2,
              AirbridgeProduct.QUANTITY: 1,
            }
          ]
        }
    ));

    View Search Result

    1234567891011121314151617181920212223
    Airbridge.event.trackEvent(
      AirbridgeCategory.SEARCH_RESULT_VIEW,
      AirbridgeEventOption(
        semanticAttributes: {
          AirbridgeAttributes.QUERY: 'product',
          AirbridgeAttributes.PRODUCTS: [{
              AirbridgeProduct.PRODUCT_ID: 'coke_zero',
              AirbridgeProduct.NAME: 'product A',
              AirbridgeProduct.PRICE: 1.99,
              AirbridgeProduct.CURRENCY: 'USD',
              AirbridgeProduct.POSITION: 1,
              AirbridgeProduct.QUANTITY: 1,
            }, {
              AirbridgeProduct.PRODUCT_ID: 'burger_cheese_double',
              AirbridgeProduct.NAME: 'product B',
              AirbridgeProduct.PRICE: 3.99,
              AirbridgeProduct.CURRENCY: 'USD',
              AirbridgeProduct.POSITION: 2,
              AirbridgeProduct.QUANTITY: 1,
            }
          ]
        }
    ));

    Add To Cart

    12345678910111213141516171819202122232425
    Airbridge.event.trackEvent(
      AirbridgeCategory.ADD_TO_CART,
      AirbridgeEventOption(
        value: 5.98,
        semanticAttributes: {
          AirbridgeAttributes.CART_ID: 'ID-1234567890',
          AirbridgeAttributes.CURRENCY: 'USD',
          AirbridgeAttributes.PRODUCTS: [{
              AirbridgeProduct.PRODUCT_ID: 'coke_zero',
              AirbridgeProduct.NAME: 'Coke Zero',
              AirbridgeProduct.PRICE: 1.99,
              AirbridgeProduct.CURRENCY: 'USD',
              AirbridgeProduct.POSITION: 1,
              AirbridgeProduct.QUANTITY: 1,
            }, {
              AirbridgeProduct.PRODUCT_ID: 'burger_cheese_double',
              AirbridgeProduct.NAME: 'Double Cheeseburger',
              AirbridgeProduct.PRICE: 3.99,
              AirbridgeProduct.CURRENCY: 'USD',
              AirbridgeProduct.POSITION: 2,
              AirbridgeProduct.QUANTITY: 1,
            }
          ]
        }
    ));

    Purchase

    1234567891011121314151617181920212223242526
    Airbridge.event.trackEvent(
      AirbridgeCategory.ORDER_COMPLETED,
      AirbridgeEventOption(
        value: 5.98,
        semanticAttributes: {
          AirbridgeAttributes.TRANSACTION_ID: 'transactionID-purchase',
          AirbridgeAttributes.CURRENCY: 'USD',
          AirbridgeAttributes.IN_APP_PURCHASED: true,
          AirbridgeAttributes.PRODUCTS: [{
              AirbridgeProduct.PRODUCT_ID: 'coke_zero',
              AirbridgeProduct.NAME: 'Coke Zero',
              AirbridgeProduct.PRICE: 1.99,
              AirbridgeProduct.CURRENCY: 'USD',
              AirbridgeProduct.POSITION: 1,
              AirbridgeProduct.QUANTITY: 1,
            }, {
              AirbridgeProduct.PRODUCT_ID: 'burger_cheese_double',
              AirbridgeProduct.NAME: 'Double Cheeseburger',
              AirbridgeProduct.PRICE: 3.99,
              AirbridgeProduct.CURRENCY: 'USD',
              AirbridgeProduct.POSITION: 2,
              AirbridgeProduct.QUANTITY: 1,
            }
          ]
        }
    ));

    To configure and deliver Semantic Attributes directly, please refer to this .

    Verify Event Transmission

    Make sure that the events are being properly sent through the SDK.

    1. Send an event with the SDK.

    2. Check if the event shows up at "Airbridge dashboard → Raw Data → App Real-time Logs".

    Advanced Setup


    Please refer to the below guide for advanced settings.

    SDK Signature Setup

    Protection against SDK spoofing is possible once you set your SDK Signature.
    This feature is available for the Airbridge Flutter SDK v3.2.0 and above.

    • Add the following lines in the airbridge.json file.

    1234
    {
        "sdkSignatureSecretID": "YOUR_SDK_SIGNATURE_SECRET_ID",
        "sdkSignatureSecret": "YOUR_SDK_SIGNATURE_SECRET"
    }

    Please ask your CSM for the "SDK Signature Secret ID" and "SDK Signature Secret" values.

    Uninstall Tracking

    Attention

    This feature is available only for Flutter SDK v3.0.2+.

    • Airbridge Android SDK v2.6.0+

    • Airbridge iOS SDK v1.28.2+

    Please refer to this guide for details.

    Send Push Token

    1
    Airbridge.registerPushToken(token);

    Forward the push token to Airbridge using the registerPushToken method.
    Make sure the notification is not shown on the device if the remote message value is airbridge-uninstall-tracking.

    Hybrid App Setup


    While basic events (e.g. "install", "open", "deep link open") can be automatically tracked by only installing the Flutter SDK in your hybrid app, in-app events (e.g. sign-up, purchase, etc.) cannot be tracked as they are actually in-browser events that occur within a website of the WebView environment. Airbridge provides a simpler way to track in-app events by enabling the Flutter SDK to automatically pull all events from the web SDK that is installed on the website of the WebView environment. This replaces the hassle of having to create bridge functions between native and WebView environments.

    12345
    Airbridge.createWebInterface(
          webToken: 'YOUR_WEB_TOKEN',
          postCommandFunction: (arg) {
            return """..."""; 
        });

    You can control the web interface using Airbridge.createWebInterface. Refer to the Flutter Hybrid App Integration Guide for details.

    Troubleshooting


    Update 2.X.X → 3.X.X

    The event API has been replaced to the below.

    123
    static void trackEvent(String category, [ AirbridgeEventOption? option ]) {
      event.trackEvent(category, option);
    }

    Refer to the Flutter 3.X.X migration guide for details.

    Bitcode Compile Error

    An error like below may occur when creating iOS builds with Flutter SDK v3.0.1+.

    Text
    1
    ld: XCFrameworkIntermediates/AirBridge/AirBridge.framework/AirBridge(AirBridge-arm64-master.o)' does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE)

    Flutter SDK v3.0.1+ uses Airbridge iOS SDK v1.28.0+, and Bitcode is no longer supported. Please refer to the Bitcode compile error guide for more details.

    settings.gradle (Android only)

    If a Plugin project ... not found. Please update settings.gradle error occurs, please edit the android/settings.gradle file as below.

    123456789101112131415
    include ':app'
    
    def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
    
    def plugins = new Properties()
    def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
    if (pluginsFile.exists()) {
        pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
    }
    
    plugins.each { name, path ->
        def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
        include ":$name"
        project(":$name").projectDir = pluginDirectory
    }

    Could not find or use auto-linked library...

    Flutter issue: https://github.com/flutter/flutter/issues/16049

    Airbridge Flutter SDK is a Swift plugin, and Flutter has an issue when a 100% Objective C project uses the Swift Plugin.
    Click File → New > File... → Swift File to create an empty Swift file and a bridge header.

    Issue does not exist with an "Objective C & Swift Project" or a "100% Swift Project".

    Update 1.X.X to 2.X.X

    • iOS

    1. Change the AirbridgeFLclasses to AirbridgeFlutterin the AppDelegatfile.

    • Android

    1. Change the AirbridgeFLclasses to AirbridgeFlutterin MainApplicationand MainActivity.

    2. Change the processDeeplinkDatamethod to processDeeplinkin MainActivity.

    Was this page helpful?

    Have any questions or suggestions?