Flutter SDK

SDK Installation


Pub VersionPub Version

Package Installation

pubspec Setup

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

dependencies:
  airbridge_flutter_sdk: 2.0.1

Open Termnimal at the location of the top-level file of the project and execute the following command

Airbridge Flutter SDK is only work for >= Flutter 1.20.0, >= Dart 2.12.0

flutter pub get

Project Setup

Add airbridge.json File

Please add the following line under flutter/assets block in your pubspec.yaml file

flutter:
  assets:
    - assets/airbridge.json

Add the following contents to assets/airbridge.json at the top level of the project.

{
    "sessionTimeoutSeconds": 300,
    "autoStartTrackingEnabled": true,
    "userInfoHashEnabled": true,
    "trackAirbridgeLinkOnly": false,
    "facebookDeferredAppLinkEnabled": false,
    "locationCollectionEnabled": false,
    "trackingAuthorizeTimeoutSeconds": 0
}

iOS Setup

Add the following code to the AppDelegate class file of the project ios module

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)
}
#import <airbridge_flutter_sdk/AirbridgeFlutter.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [AirbridgeFlutter initSDKWithAppName:@"YOUR_APP_NAME" appToken:@"YOUR_APP_TOKEN" withLaunchOptions:launchOptions];
}

You can find YOUR_APP_NAME and YOUR_APP_SDK_TOKEN in the Airbridge Dashboard → SettingsTokens tab

Android Setup

Add the following code to the Application class file of the project android module

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");
    }
}
import co.ab180.airbridge.flutter.AirbridgeFlutter
import io.flutter.app.FlutterApplication

class MainApplication: FlutterApplication() {
    override fun onCreate() {
        super.onCreate()
        AirbridgeFlutter.init(this, "YOUR_APP_NAME", "YOUR_APP_TOKEN")
    }
}

You can find YOUR_APP_NAME and YOUR_APP_SDK_TOKEN in the Airbridge Dashboard → SettingsTokens tab

Register the Application class created earlier in AndroidManifest.xml of the project android module as follows

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

Testing

You can check your events into Raw DataApp Real-time Log page on the dashboard after run your application

🚧

Real-time logs may have a delay of up to 5 minutes

Deep Link Setup


Dashboard Setup

The deep link dashboard settings for each iOS and Android platform are variable as follows

  • iOS Deep Link Dashboard Setup Guide
  • Android Deep Link Dashboard Setup Guide

Project Setup

iOS Deep Link Setup

  • URL Scheme Setup
  1. Open *.xcodeproj or *.xcworkspace of the project ios module in Xcode
  2. Go to Project SettingsInfo tab
  3. Add the iOS URI Scheme information entered in the Airbridge dashboard to URL Schemes in the URL Types tab of the page
  • Universal Link Setup
  1. Open *.xcodeproj or *.xcworkspace of the project ios module in Xcode
  2. Go to Project SettingsSigning & Capabilities tab
  3. Add the following information to the Domains of the Associated Domains tab of the page.
  • applinks:YOUR_APP_NAME.airbridge.io
  • applinks:YOUR_APP_NAME.deeplink.page
  • AppDelegate Setup
  1. Open AppDelegate of the project ios module in Xcode
  2. Add the following methods.
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
}
-  (BOOL)application:(UIApplication*)application
continueUserActivity:(NSUserActivity*)userActivity
  restorationHandler:(void (^)(NSArray* _Nullable))restorationHandler
{
    [AirbridgeFlutter.deeplink handleUniversalLink:userActivity.webpageURL];

    return YES;
}

- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
            options:(NSDictionary<UIApplicationOpenURLOptionsKey, id>*)options
{
    [AirbridgeFlutter.deeplink handleURLSchemeDeeplink:url];

    return YES;
}

Android Deep Link Setup

  • AndroidManifest.xml Setup

Follow these steps to setup the Intent Filter

  1. Open AndroidManifest.xml
  2. Add Intent Filter to MainActivity.
<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>
  • MainActivity Setup
  1. Open MainActivity.
  2. Add onResume, onNewIntent to MainActivity.
@Override
protected void onResume() {
    super.onResume();
    AirbridgeFlutter.processDeeplink(intent);
}

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

override fun onNewIntent(intent: Intent) {
    super.onNewIntent(intent)
    setIntent(intent)
}

Callback Setup

Following method is requiring the class name for receiving deep link data that user clicks on

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

Testing

After the deep link configuration of the Airbridge Flutter SDK is completed, you can check whether it has been correctly setup through the following links

  • YOUR_APP_URI_SCHEME://

After deep link configuration and verification is completed, you can check on the Airbridge dashboard → Row DataApp Real-time Log tab

User Setup


User Identifier Setup

To measure the contribution of fragmented 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 Web and App must match 1:1 with the user's specific ID values)
  • User Alias : Identifiers that can represent users(e.g. loyalty program ID, affiliate integrated ID, etc)

📘

The user's email and phone numbers are automatically HASH(SHA256)

In the Airbridge Flutter SDK, you can set the user identifier in the following ways

Airbridge.state.setUser(
    User(
    id: 'tester',
    email: '[email protected]',
    phone: '+82 10 0000-0000',
    alias: {
        'alias_key': 'alias_value',
    },
    )
);
  • User Alias maximum number is up to 10
  • User Alias key must be String type and length is up to 128
  • User Alias key should satisfy ^[a-z_][a-z0-9_]*$ regular expression
  • User Alias value must be String type and length is up to 1024

Once you setup user identifier, all events will be forward with that identity information

🚧

The user identifier set can be reset or overwritten through user events

User Attribute Setup

Additional user attribute data can be improve accuracy of Multi-Touch Attribute(MTA) analysis, internal data analysis and linking thrd-party solutions

AirbridgeUnity.SetUserAttribute(key, value);
AirbridgeUnity.ClearUserAttributes();
  • User Attribute maximum number is up to 100
  • User Attribute key must be String type and up to 128
  • User Attribute key should satisfy ^[a-z_][a-z0-9_]*$ regular expression
  • User Attribute value must be Primitive type or String type and up to 1024 for String

🚧

The user attribute set can be reset or overwritten through user events

Testing

User information set in Airbridge Flutter SDK can be checked on the Airbridge Dashboard → Row DataApp Real-time Log tab

Event Setup


All the events that calls by Airbridge Flutter SDK has following fields can be contains

  • Event Category : Name of event Required (String)
  • Event Action : Event attribute 1 (String)
  • Event Label : Event attribute 2 (String)
  • Event Value : Event attribute 3 (Float)
  • Event Custom Attributes : Additional fields that can represent the event (Map<String, Object>)
  • Event Semantic Attributes : Additional semantic fields that can represent the event (Semantic Attributes Class)

User Events

For convenience, the Airbridge Flutter SDK provides the following user events

  • Sign Up
Airbridge.event.send(SignUpEvent(
    user: User(
        id: 'tester',
        email: '[email protected]',
        phone: '+82 10 0000-0000',
    )
));

🚧

User identifier and property values passed at sign up will be automatically recorded

  • Sign In
Airbridge.event.send(SignInEvent(
    user: User(
        id: 'tester',
        email: '[email protected]',
        phone: '+82 10 0000-0000',
    )
));

🚧

User identifier and property values passed at sign in will be automatically recorded

  • Sign Out
Airbridge.event.send(SignOutEvent());

🚧

All user identifier and property values will disappear after sign out called

E-Commerce Events

For convenience, Airbridge Flutter SDK provides e-commerce events with the following product classes

Product(
  id: 'beverage_1'
  name: 'Coca cola',
  price: 1.25,
  currency: 'USD',
  quantity: 1,
  position: 0
)
  • Home Screen View
Airbridge.event.send(ViewHomeEvent());
  • Search Results View
Airbridge.event.send(ViewSearchResultEvent(
  query: 'SELECT * FROM beverages',
  products: [
    Product(
      id: 'beverage_1'
      name: 'Coca cola',
      price: 1.25,
      currency: 'USD',
      quantity: 1,
      position: 0
    ),
    Product(
      id: 'beverage_2'
      name: 'Fanta',
      price: 1500,
      currency: 'KRW',
      quantity: 1,
      position: 1
    ),
  ],
));
  • Product List View
Airbridge.event.send(ViewProductListEvent(
  listID: 'beverage_list_0',
  products: [
    Product(
      id: 'beverage_1'
      name: 'Coca cola',
      price: 1.25,
      currency: 'USD',
      quantity: 1,
      position: 0
    ),
    Product(
      id: 'beverage_2'
      name: 'Fanta',
      price: 1500,
      currency: 'KRW',
      quantity: 1,
      position: 1
    ),
  ],
));
  • Product Details View
Airbridge.event.send(ViewProductDetailEvent(
  products: [
    Product(
      id: 'beverage_1'
      name: 'Coca cola',
      price: 1.25,
      currency: 'USD',
      quantity: 1,
      position: 0
    ),
  ],
);
  • Add To Cart
Airbridge.event.send(AddToCartEvent(
  cartID: 'cart_0',
  currency: 'KRW',
  total: 2500,
  products: [
    Product(
      id: 'beverage_1'
      name: 'Coca cola',
      price: 1000,
      currency: 'KRW',
      quantity: 1,
      position: 0
    ),
    Product(
      id: 'beverage_2'
      name: 'Fanta',
      price: 1500,
      currency: 'KRW',
      quantity: 1,
      position: 1
    ),
  ],
);
  • Order Complete
Airbridge.event.send(PurchaseEvent(
  transactionID: 'transaction_0',
  products: [
    Product(
      id: 'beverage_1'
      name: 'Coca cola',
      price: 1000,
      currency: 'KRW',
      quantity: 1,
      position: 0
    ),
    Product(
      id: 'beverage_2'
      name: 'Fanta',
      price: 1500,
      currency: 'KRW',
      quantity: 1,
      position: 1
    ),
  ],
  isInAppPurchase: true,
  currency: 'KRW',
  total: 2500,
);

Customized Events

You can send an customized event in the following way from the Airbridge Flutter SDK

Airbridge.event.send(Event(
  'category',
  option: EventOption(
    action: 'action',
    label: 'label',
    value: 9999,
    attributes: {
      'custom_key': 'value',
    },
    semantics: {
      'query': 'query_123',
    },
  ),
));

📘

To configure and deliver Semantic Attributes directly, please check this guide.

Testing

Event information sent from the Airbridge Flutter SDK can be checked on the Airbridge dashboard → Row DataApp Real-time Log tab

Advanced Setup


User Identifier Hash Setup

If you want to send identity information without HASH(SHA256) for internal data analysis, you can stop automatic HASH(SHA256) through userInfoHashEnabled field of airbridge.json file

❗️

The option required separate security measures must be taken internally because provides sensitive personal information such as User Email and User Phone

Session Timeout Setup

Airbridge Flutter SDK does not send app open event again if the user relaunch the app within the sessionTimeoutSeconds field of airbridge.json file otherwise will transfer app open event when the user relaunch the app after that time

Personal Information Protection

This function is useful when collecting and transferring data with consent form customers for personal information protection, such as GDPR or CCPA

Data collection and transmission can be started explicitly using the autoStartTrackingEnabled field of airbridge.json file

📘

When this feature is disabled, the following functions must be explicitly called for proper data collection

Airbridge.state.startTracking();

Track Airbridge Link Only

If it is difficult to see the performance of re-engagement through Airbridge at a glance due to too many deep link actions within the advertiser's app, trackAirbridgeLinkOnly field of airbridge.json file can be used to filter only the results received through Airbridge deep link

If the setting is activated, the result of the deep link is measured only when the app is opened through a deep link that matches the conditions below

  • The app is opened through a airbridge.io link
  • The app is opened through a deeplink.page link
  • The app is opened through a Custom Domain Setup that registered on a dashboard
  • The app is opened through airbridge_referrer query contains link

Location Collection (Android only)

Airbridge Unity SDK can collect user location information through locationCollectionEnabled field of airbridge.json file

❗️

Location information must be collected through legitimate purposes and ways

🚧

The option only available on Android device and to collects location information, the following permission must be included into AndroidManifest.xml file

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

Facebook Deferred App Links

You can receive Facebook Deferred App Link from the Airbridge Unity SDK through the setting of the facebookDeferredAppLinkEnabled field of airbridge.json file

Tracking Authorize Timeout 설정 (iOS only)

When show Request tracking authorization alert using AppTrackingTransparency.framework, even though Tracking authorize is clicked, IDFA is not collected on install event because install event is sent before click.

When set trackingAuthorizeTimeoutSeconds on airbridge.json file, install event is delayed until Request tracking authorization alert is clicked.

Troubleshooting


settings.gradle

When build on Android, Plugin project ... not found. Please update settings.gradle error is occurred, error can be solved with edit android/settings.gradle file.

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 swift plugin,
But Flutter has issue that when 100% Objective C Project use Swift Plugin, above error is occurred.
With click File > New > File... > Swift File to create File.swift file and Bridge Header file, issue can be solved.

Issue is not existed on Objective C & Swift Project and 100% Swift Project.

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

  • iOS
  1. Change AppDelegate 의 AirbridgeFL class to AirbridgeFlutter class.
  • Android
  1. Change AirbridgeFL class of MainApplication and MainActivity to AirbridgeFlutter class.
  2. Change processDeeplinkData method of MainActivity to processDeeplink method.