How to Integrate the Device Data Collector into Flutter Applications

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:

  1. iOS Integration
  2. Android Integration
  3. Platform Selection Integration

Integrating Kount iOS SDK to Flutter Hybrid Applications

Provide native support for your Kount solution by integrating the Kount iOS SDK into your Flutter application. This allows you to use Kount's service without having to create API calls.

Integration Steps for iOS (include SDK in project)

There are three ways to integrate Kount iOS SDK with React Native App:

  1. Universal Static Library (libKountDataCollector.a)
    Refer to How to Integrate the Device Data Collector into Mobile SDKs using iOS Universal Static Library.
  2. XCFramework (KountDataCollector.xcframework)
    Refer to How to Integrate the Kount Device Data Collector XCFramework Package into an iOS 14.5 Application.
    1. Refer to How to Integrate the Kount Device Data Collector CocoaPods Package into an iOS 13.5 Application.
    2. Go to Flutter Project and then iOS. Open .xcworkspace(if pod is there)/.xcodeproj.

      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 while building the app after integrating with Kount CocoaPod, then proceed with the following methods to resolve it.

      Method 1
        1. Choose the target, go to Build Phases, click Link Binary With Libraries, and then remove all libPods.a files.
        2. Open Terminal and then direct to your project.
        3. Run: pod install
        4. Clean and build project.

      Method 2
        1. Open the Terminal.
        2. Direct to your project and then run: pod deintegrate –verbose and pod install –verbose

      Method 3
        1. Add two User-Defined Settings: [to the left = to the right]
        2. Run PODS_ROOT = ${SRCROOT}/Pods and PODS_PODFILE_DIR_PATH = ${SRCROOT}/

Integration Steps for iOS (create wrapper)

Swift

  1. A Runner-Bridging-header.h file is created automatically. Open this and write following import statements:
          #import "GeneratedPluginRegistrant.h"
          #import "KDataCollector.h"
          #import "KountAnalyticsViewController.h"
        
  2. In Appdelegate.swift file, write the following code snippet. Update the merchantID field with the merchant ID that was assigned to you from Kount. In addition, use the KEnvironment.test environment when running tests, and KEnvironment.prod when releasing running in production.
        KDataCollector.shared().locationCollectorConfig = KLocationCollectorConfig.requestPermissionKDataCollector.shared().debug = true
        KDataCollector.shared().merchantID = 900900
        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
                         }
        })
        
  3. Create a private function, callCollect() which takes result as argument and is being called in the above code snippet. In this function, invoke the collector using either the Kount Supplied sessionID KountAnalyticsViewController.getAppSessionID(), your own sessionID, or @"".
    Do not forget to send the sessionID used here back to your servers. You need to use it when making Kount API calls to evaluate this transaction/event. Analytics are not available for Hybrid apps, so ensure the analyticsSwitch is set to False. The example below shows the callback function which will be returned upon completion. Updated them as warranted 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 asAny)
                }else {
                  print("Collection failed without error")
                }
                result(FlutterError(code: "UNAVAILABLE" ,message:error?.localizedDescription, details: nil))
            }
          }
        }
                         
        
        private func callGetSessionID(result: @escaping FlutterResult) {
          result(KountAnalyticsViewController.getAppSessionID())
        }
        

Objective-C

  1. Open AppDelegate.m and write following import statements.
        #import "KDataCollector.h"
        #import "KountAnalyticsViewController.h"
        
  2. In Appdelegate.m file, write the following code snippet. Ensure you update the merchantID field with the merchant ID that was assigned to you from Kount. In addition, use the KEnvironmentTest environment when running tests, and KEnvironmentProduction when releasing running in production.
        [[KDataCollector sharedCollector] setDebug:YES];
        // TODO Set your Merchant ID
        [[KDataCollector sharedCollector] setMerchantID:999999];
        // 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);
            }
        }];
        
  3. 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 sessionID KountAnalyticsViewController.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 Kount API calls to evaluate this transaction/event. Analytics are not available for Hybrid apps, so ensure the analyticsSwitch is set to False. The example below shows the callback function which will be returned upon completion. Updated them as warranted 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.

  1. Click on your project in the project navigator to open your project settings.
  2. Select your target, and then open the General tab.
  3. Scroll to Frameworks, Libraries, and then Embedded Content Settings.
  4. On the newly-added KountDataCollector.xcframework, select Do Not Embed.
  5. If you do not see KountDataCollector.xcframework, you must add it manually:
    1. Click the Plus (+) button.
    2. Select KountDataCollector.xcframework.
    3. Click Add.

Integrating Kount Android SDK to Flutter Hybrid Apps

Integrate the Kount Analytics SDK into your Flutter application to collect additional end-user information. This assists in detecting suspicious devices and preventing fraud.

Integration Steps for Android (include in project)

You have two project integration options. Choose the one that best fits your project. We recommend using the Gradle option if you do not have a preference.

  1. Refer to How to Integrate the Device Data Collector into Mobile Apps using Android Gradle.
  2. Refer to 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, add tools:replace="android:allowBackup" to your application tag.

Integrations Steps for Android (create wrapper)

  1. In the main activity of your application, you will need to initialize the collector and assign the merchant ID you received from Kount. 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 Kount API (see the Kount API section below). 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()
            }
          }
        }
        
  2. Create a private function, collectData() which is being called in the previous code snippet.
        private fun collectData() {
          AnalyticsCollector.collectDeviceDataForSession(this)
          AnalyticsCollector.collectDeviceFingerprintDataForSession(this)
        }
        
  3. 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)
           }
        }
        
    Note: While preferred, not all apps are approved in the app store to use the ACCESS_FINE_LOCATION. If your app has been rejected for having this permission, replace ACCESS_FINE_LOCATION (uses GPS) with ACCESS_COARSE_LOCATION (uses cellular triangulation).

Platform Selection Integration in Flutter App

  1. In Flutter application, go to main.dart and write following code snippet. This sample code snippets shows how to call native SDK methods based on application platform.
        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),          
                        ],        
                    ),      
                  )    
                );  
            }}
        
  2. Run flutter app and it should capture the data points for device data collector and device fingerprinting data collector in both iOS and Android Platform.

Was this article helpful?
0 out of 1 found this helpful