Flutter is a named channel for communicating with platform plugins using asynchronous method calls. Method calls are encoded into binary before being sent, and binary results received are decoded into Dart values. The MethodCodec used must be compatible with the one used by the platform plugin.
To integrate the Mobile SDKs into a hybrid Flutter application, there are three main steps:
-
iOS Integration
-
Android Integration
-
Platform Selection Integration
Provide native support for your solution by integrating the iOS SDK into your Flutter application. This allows you to use our services without having to create API calls.
There are three ways to integrate iOS SDK with Flutter:
-
Go to
Flutter Project
and theniOS
. Open.xcworkspace(if pod is there)/.xcodeproj
. -
For CocoaPods integration, if you receive an error similar to the sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation proceed with the following methods to resolve it.
-
Method 1: Choose the target, go to Build Phases, select Link Binary With Libraries, and then remove all
libPods.a
files. Open Terminal and then direct to your project. Runpod install
. Clean and build the project. -
Method 2: Open the Terminal. Direct to your project and then run:
pod deintegrate –verbose
andpod install –verbose
. -
Method 3: Add two User-Defined Settings:
[to the left = to the right]
RunPODS_ROOT = ${SRCROOT}/Pods
andPODS_PODFILE_DIR_PATH = ${SRCROOT}/
.
-
-
A
Runner-Bridging-header.h
file is created automatically. You can use this file or you can import the SDK directly into the file.-
Bridging-header file
Open the
Runner-Bridging-header.h
and write the following import statements:#import "GeneratedPluginRegistrant.h" #import "KDataCollector.h" #import "KountAnalyticsViewController.h"
-
Import the SDK
Import the SDK into the AppDelegate Swift file by using one of the following methods:
Either import the SDK directly:
import KountDataCollector
Or add the following code to your Runner-Bridging-header file:
#import "GeneratedPluginRegistrant.h" @import KountDataCollector;
-
-
In the
Appdelegate.swift
file, update the merchantID field with the merchant ID that was assigned to you. In addition, use theKEnvironment.test
environment when running tests, andKEnvironment.prod
when releasing running in production.KDataCollector.shared().locationCollectorConfig = KLocationCollectorConfig.requestPermissionKDataCollector.shared().debug = true KDataCollector.shared().merchantID = "900900" // Insert your valid merchant ID KDataCollector.shared().environment = KEnvironment.test KountAnalyticsViewController().setEnvironmentForAnalytics(KDataCollector.shared().environment) let controller : FlutterViewController = window?.rootViewController as! FlutterViewControllerlet collectChannel = FlutterMethodChannel(name: "DataCollector", binaryMessenger: controller.binaryMessenger) collectChannel.setMethodCallHandler({[weak self] (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in // Note: this method is invoked on the UI thread. if call.method == "collect" { self?.callCollect(result: result) } else if call.method == "getSessionID" { self?.callGetSessionID(result: result) } else { result(FlutterMethodNotImplemented) return } })
-
Create a private function,
callCollect()
which takes the result as an argument. In this function, invoke the collector using either the the supplied sessionIDKountAnalyticsViewController.getAppSessionID()
, your own sessionID, or@""
.Do not forget to send the
sessionID
used here back to your servers. You must use thesessionID
when making API calls to evaluate this transaction/event. Analytics are not available for hybrid apps. This example shows the callback function which will be returned upon completion. Update them as needed for your application.private func callCollect(result: @escaping FlutterResult) { KountAnalyticsViewController().collect(KountAnalyticsViewController.getAppSessionID(), analyticsSwitch:false) { (sessionID, success, error) in if (success) { result("Collection Successful") print("Collection Successful") } else { if((error) != nil) { print("Collection failed with error",error?.localizedDescription as Any) }else { print("Collection failed without error") } result(FlutterError(code: "UNAVAILABLE" ,message:error?.localizedDescription, details: nil)) } } } private func callGetSessionID(result: @escaping FlutterResult) { result(KountAnalyticsViewController.getAppSessionID()) }
-
You can import the header files or import the SDK directly into the Objective-C file.
-
Import header files
Open
AppDelegate.m
and add the following code.#import "KDataCollector.h" #import "KountAnalyticsViewController.h"
-
Import the SDK (Swift Package Manager, XCFramework, and Universal Library)
Import the SDK directly into the AppDelegate Objective-C file.
@import KountDataCollector;
-
Import the SDK (CocoaPods)
Import the SDK directly into the AppDelegate Objective-C file.
#import "KountUmbrela.h"
-
-
In the
Appdelegate.m
file, write the following code snippet. Update the merchantID field with the merchant ID that was assigned to you. In addition, use theKEnvironmentTest
environment when running tests, andKEnvironmentProduction
when releasing running in production.[[KDataCollector sharedCollector] setDebug:YES]; // TODO Set your Merchant ID [[KDataCollector sharedCollector] setMerchantID:@"900900"]; // TODO Set the location collection configuration [[KDataCollector sharedCollector] setLocationCollectorConfig:KLocationCollectorConfigRequestPermission]; // For a released app, you'll want to set this to KEnvironmentProduction [[KDataCollector sharedCollector] setEnvironment:KEnvironmentTest]; [[KountAnalyticsViewController sharedInstance] setEnvironmentForAnalytics: [KDataCollector.sharedCollector environment]]; FlutterViewController *controller = [[FlutterViewController alloc] init]; controller = (FlutterViewController*)self.window.rootViewController; FlutterMethodChannel *collectChannel = [FlutterMethodChannel methodChannelWithName:@"DataCollector" binaryMessenger:controller.binaryMessenger]; [collectChannel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult _Nonnull result) { if ([call.method isEqual:@"collect"]) { [self callCollect:result]; } else if ([call.method isEqual:@"getSessionID"]) { [self callGetSessionID:result]; } else { result(FlutterMethodNotImplemented); } }];
-
Create a private function,
callCollect()
which takes result as argument and is being called in above code snippet. In this function, you must invoke the collector using either the Kount Supplied sessionIDKountAnalyticsViewController.getAppSessionID
, your own sessionID, or@""
.Do not forget to send the
sessionID
used here back to your servers. You will need to use it when making API calls to evaluate this transaction/event. Analytics are not available for hybrid apps. This example shows the callback function which will be returned upon completion. Update them as needed for your application.- (void)callCollect:(_Nonnull FlutterResult)result { [[KountAnalyticsViewController sharedInstance] collect:@"" analyticsSwitch:NO completion:^(NSString * _Nonnull sessionID, BOOL success, NSError * _Nullable error) { if(success) { result(@"Collection Successful"); NSLog(@"Collection Successful"); } else { if (error != nil) { NSLog(@"Collection failed with error:%@",error.description); } else { NSLog(@"Collection failed without error"); } result([FlutterError errorWithCode:@"UNAVAILABLE" message:error.localizedDescription details:nil]); } }]; } - (void)callGetSessionID:(_Nonnull FlutterResult)result { result([KountAnalyticsViewController getAppSessionID]); }
If you get a build fail error like this ld: library not found for -lKountDataCollector” “clang: error: linker command failed with exit code 1 (use -v to see invocation)
, then follow the steps below.
-
Click the Plus (+) button.
-
Select
KountDataCollector.xcframework
. -
Click Add.
-
Click on your project in the project navigator to open your project settings.
-
Select your target, and then open the General tab.
-
Scroll to Frameworks, Libraries, and then Embedded Content Settings.
-
On the newly-added
KountDataCollector.xcframework
, select Do Not Embed. -
If you do not see
KountDataCollector.xcframework
, you must add it manually:
Integrate the Device Data Collector Android SDK into your Flutter application to collect additional end-user information. This assists in detecting suspicious devices and preventing fraud.
There are two project integration options. We recommend using the Gradle option if you do not have a preference.
-
How to Integrate the Device Data Collector into Mobile Apps using Android Gradle.
-
How to Integrate the Device Data Collector into Android Applications using the Library JAR.
Note
If
android:allowbackup attribute
is false in your<application>
tag, addtools:replace="android:allowBackup"
to your application tag.
-
In the main activity of your application, initialize the collector and assign the merchant ID you received. Optionally, you can provide a session ID if you need to generate your own (if not, the SDK generates one for you). You must send this session ID back to your servers in order to make calls to the API. Add the following initialization in your MainActivity:
import com.kount.api.analytics.AnalyticsCollector import com.kount.api.analytics.AnalyticsConstants import com.kount.api.analytics.Analytics .... override fun onCreate(savedInstanceState: Bundle?) { ... private val CHANNEL = "DataCollector" // Name for method channel // REQUIRED SECTION AnalyticsCollector.setMerchantId("999999") // END REQUIRED SECTION //Set below flags to true to enable devicedata and device fingerprint data collection. AnalyticsConstants.collectDeviceDataForSession=true AnalyticsConstants.collectDeviceFingerprintDataForSession=true //For production need to add AnalyticsCollector.ENVIRONMENT_PRODUCTION . AnalyticsCollector.setEnvironment(AnalyticsCollector.ENVIRONMENT_TEST) // OPTIONAL SESSION_ID SECTION val deviceSessionID = UUID.randomUUID().toString() AnalyticsCollector.setSessionId(deviceSessionID) //END OPTIONAL SESSION_ID SECTION //Method Channel name must be same as the one used in .dart file for invoking this method. MethodChannel(flutterEngine!!.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result -> // Note: this method is invoked on the UI thread. if (call.method == "collectData") { collectData() } } }
-
Create a private function,
collectData()
.private fun collectData() { AnalyticsCollector.collectDeviceDataForSession(this@MainActivity, {sessionId -> Log.d("TAG", "success completed with sessionId $sessionId") Log.d("TAG", "DDC STATUS is :" + AnalyticsCollector.getCollectionStatus()?.name) },{ sessionId, error -> Log.d("TAG", " failed with sessionId $error, $sessionId") Log.d("TAG", "DDC STATUS is :" + AnalyticsCollector.getCollectionStatus()?.name) }) }
-
To support Location Collection in Android API 23 and above, add the following permissions to your main activity with the onCreate method.
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) { ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), AnalyticsCollector.REQUEST_PERMISSION_LOCATION) } else { ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), AnalyticsCollector.REQUEST_PERMISSION_LOCATION) } }
-
In the Flutter application, go to
main.dart
and add the following code snippet.import 'dart:io' show Platform; class _MyHomePageState extends State<MyHomePage> { static const method_channel='DataCollector' static const platform = const MethodChannel(method_channel); String _collectionStatus = 'Collect Data'; Future<void> _startCollection() async { String collectionStatus="NOT_STARTED"; try { if(Platform.isAndroid){ await platform.invokeMethod('collectData'); } else if(Platform.isIOS){ final String result = await platform.invokeMethod('collect'); collectionStatus = '$result.'; } } on PlatformException catch (e) { collectionStatus = "Did not find method '${e.message}'."; } setState(() { _collectionStatus = collectionStatus; }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ ElevatedButton( child: Text('Collect'), onPressed: _startCollection, ), Text(_collectionStatus), ], ), ) ); }}
-
Run the Flutter app.
The app should capture the data points for the Device Data Collector in both iOS and Android platforms.