version v3.3.0
Please add the following dependency under the dependencies
block in your pubspec.yaml
file
dependencies:
# Get the latest version from https://pub.dev/packages/airbridge_flutter_sdk/versions
airbridge_flutter_sdk: HERE_LATEST_VERSION
Open Terminal
at the topmost level of the project and execute the following command.
flutter pub get
The Airbridge Flutter SDK supports >= Flutter 1.20.0
and >= Dart 2.12.0
Please add the following under the flutter/assets
block in your pubspec.yaml
file.
flutter:
assets:
- assets/airbridge.json
Create an assets/airbridge.json
file at the topmost level of the project.
Configure settings in JSON format.
{
"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"
}
Add the following code to the ios/[Project Name]/AppDelegate.m
file.
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];
}
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
.
Add the following code to the onCreate
function within the android/app/src/main/java/.../MainApplication.java
file.
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")
}
}
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.
<application
android:name=".MainApplication"
...>
...
</application>
Add an airbridge.json
file to the project folder.
Configure settings in JSON format.
{
"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 (30). 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 |
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) |
trackingAuthorizeTimeoutSeconds | Number | 0 | When timeout is set, Install event is delayed until |
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. |
Check if install events are sent when the application is installed and opened.
Events from the Airbridge SDK are shown at the "Airbridge Dashboard → Raw Data → App Real-time Logs".
Go to Airbridge Dashboard → Raw Data → App Real-time Logs
.
Search for the device's ADID (IDFA, IDFV, GAID).
Attention
Logs may be delayed for up to 5 minutes.
Please refer to the guides below to setup your deep links in the Airbridge dashboard.
URL Scheme Setup
Go to "Xcode → Project file → Info → URL Types".
From the Airbridge dashboard, copy "iOS URI Scheme" to Xcode's "URL Schemes". (Do not include://
)
Universal Link Setup
Go to "Xcode → Project file → Signing & Capabilities".
Click "+ Capability" and add "Associated Domains".
Add applinks:YOUR_APP_NAME.airbridge.io
to "Associated Domains".
Add applinks:YOUR_APP_NAME.deeplink.page
to "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
Open ios/[Project name]/AppDelegate
.
Add the following methods. (handleUserActivity
, handleURLSchemeDeeplink
)
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
}
- (BOOL)application:(UIApplication*)application
continueUserActivity:(NSUserActivity*)userActivity
restorationHandler:(void (^)(NSArray* _Nullable))restorationHandler
{
[AirbridgeFlutter.deeplink handleUserActivity:userActivity];
return YES;
}
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey, id>*)options
{
[AirbridgeFlutter.deeplink handleURLSchemeDeeplink:url];
return YES;
}
AndroidManifest.xml Setup
Open AndroidManifest.xml
Add the following intent-filter to the activity that will process the deep link.
<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
.
MainActivity Setup
Insert the following code to the android/app/src/main/java/.../MainActivity.java
file.
@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)
}
Register a function that will be called whenever a "deep link" or a "deferred deep link" opens the application.
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.
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.
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.
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 | - |
User email | Hashed by default | |
phone | User phone number | Hashed by default |
alias | User alias | - Maximum 10 aliases |
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.
Airbridge.state.updateUser(
User(
id: 'sam1234',
)
);
Additional user attributes can be used for more accurate Multi-Touch Attribution (MTA) analyses, additional internal data analyses, and linking third-party solutions.
Airbridge.state.setUser(
User(
attributes: {
'attr_key': 'attr_value',
},
)
);
Name | Description | Limitations |
---|---|---|
attributes | User attribute | - Maximum 100 attributes |
Attention
The user attribute information can be reset or overwritten through user events.
Make sure that your user information settings are being properly sent through the SDK.
Configure user identifier information.
Send an event using the SDK.
Click the event at "Airbridge dashboard → Raw Data → App Real-time Logs"
Check if the user information is correctly sent under the user
block.
Setup a device alias through the Airbridge SDK. The alias will be sustained even after the app closes, unless otherwise deleted.
Airbridge.setDeviceAlias("ADD_YOUR_KEY", "AND_YOUR_VALUE");
Airbridge.removeDeviceAlias("DELETE_THIS_KEY");
Airbridge.clearDeviceAlias();
| Add the key value pair to the device identifier. |
| Delete the corresponding device alias. |
| Delete all device aliases. |
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.
action
, label
, value
, customAttributes
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 |
static void trackEvent(String category, [ AirbridgeEventOption? option ]) {
event.trackEvent(category, option);
}
Send user events with the SDK.
action
, label
, value
, customAttributes
and semanticAttributes
can be used for user events.
User identifiers are set with setUser
and then sent with AirbridgeCategory.SIGN_UP
for user sign ups.
Airbridge.state.setUser(User(
id: 'tester',
email: 'tester@ab180.co',
phone: '+82 10 0000-0000',
));
Airbridge.trackEvent(AirbridgeCategory.SIGN_UP);
Airbridge.state.setUser(User(
ID: 'test',
email: 'test@ab180.co',
phone: '000-0000-0000',
));
Airbridge.trackEvent(AirbridgeCategory.SIGN_IN);
Airbridge.trackEvent(AirbridgeCategory.SIGN_OUT);
Airbridge.state.setUser(User());
Attention
All user identifier properties will disappear after
sign out
is called.
action
, label
, value
, customAttributes
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.
Airbridge.trackEvent(AirbridgeCategory.HOME_VIEW);
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,
},
]
}
));
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,
}
]
}
));
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,
}
]
}
));
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,
}
]
}
));
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,
}
]
}
));
Make sure that the events are being properly sent through the SDK.
Send an event with the SDK.
Check if the event shows up at "Airbridge dashboard → Raw Data → App Real-time Logs".
Please refer to the below guide for advanced settings.
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.
{
"sdkSignatureSecretID": "YOUR_SDK_SIGNATURE_SECRET_ID",
"sdkSignatureSecret": "YOUR_SDK_SIGNATURE_SECRET"
}
The SDK Signature Credentials are required for the SDK Signature setup. Refer to this article to learn how to create them.
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.
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
.
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.
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.
The event API has been replaced to the below.
static void trackEvent(String category, [ AirbridgeEventOption? option ]) {
event.trackEvent(category, option);
}
Refer to the Flutter 3.X.X migration guide for details.
An error like below may occur when creating iOS builds with Flutter SDK v3.0.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.
If a Plugin project ... not found. Please update settings.gradle
error occurs, please edit the android/settings.gradle
file as below.
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
}
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".
iOS
Change the AirbridgeFL
classes to AirbridgeFlutter
in the AppDelegat
file.
Android
Change the AirbridgeFL
classes to AirbridgeFlutter
in MainApplication
and MainActivity
.
Change the processDeeplinkData
method to processDeeplink
in MainActivity
.
このページは役に立ちましたか?
flutter:
assets:
- assets/airbridge.json
{
"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"
}
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];
}
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")
}
}
<application
android:name=".MainApplication"
...>
...
</application>
{
"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"
}
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
}
- (BOOL)application:(UIApplication*)application
continueUserActivity:(NSUserActivity*)userActivity
restorationHandler:(void (^)(NSArray* _Nullable))restorationHandler
{
[AirbridgeFlutter.deeplink handleUserActivity:userActivity];
return YES;
}
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey, id>*)options
{
[AirbridgeFlutter.deeplink handleURLSchemeDeeplink:url];
return YES;
}
<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>
@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)
}
Airbridge.deeplink.setDeeplinkListener((deeplink) {
// airbridge deeplink = SCHEME://...
print('$deeplink');
});
Airbridge.state.setUser(
User(
id: 'tester',
email: 'tester@ab180.co',
phone: '+82 10 0000-0000',
alias: {
'alias_key': 'alias_value',
},
)
);
Airbridge.state.updateUser(
User(
id: 'sam1234',
)
);
Airbridge.state.setUser(
User(
attributes: {
'attr_key': 'attr_value',
},
)
);
Airbridge.setDeviceAlias("ADD_YOUR_KEY", "AND_YOUR_VALUE");
Airbridge.removeDeviceAlias("DELETE_THIS_KEY");
Airbridge.clearDeviceAlias();
static void trackEvent(String category, [ AirbridgeEventOption? option ]) {
event.trackEvent(category, option);
}
Airbridge.state.setUser(User(
id: 'tester',
email: 'tester@ab180.co',
phone: '+82 10 0000-0000',
));
Airbridge.trackEvent(AirbridgeCategory.SIGN_UP);
Airbridge.state.setUser(User(
ID: 'test',
email: 'test@ab180.co',
phone: '000-0000-0000',
));
Airbridge.trackEvent(AirbridgeCategory.SIGN_IN);
Airbridge.trackEvent(AirbridgeCategory.SIGN_OUT);
Airbridge.state.setUser(User());
Airbridge.trackEvent(AirbridgeCategory.HOME_VIEW);
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,
},
]
}
));
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,
}
]
}
));
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,
}
]
}
));
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,
}
]
}
));
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,
}
]
}
));
{
"sdkSignatureSecretID": "YOUR_SDK_SIGNATURE_SECRET_ID",
"sdkSignatureSecret": "YOUR_SDK_SIGNATURE_SECRET"
}
Airbridge.registerPushToken(token);
static void trackEvent(String category, [ AirbridgeEventOption? option ]) {
event.trackEvent(category, option);
}
Airbridge.createWebInterface(
webToken: 'YOUR_WEB_TOKEN',
postCommandFunction: (arg) {
return """...""";
});
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)
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
}