CARD91 NSDL AADHAAR SDK Flutter Implementation for IOS

Card91 NSDL AADHAAR KYC IOS Framework Integration with Flutter iOS Apps

Description

Purpose of this document is to illustrate the method to add Card91 ‘Card91KYC’ library to any iOS native application written in swift invoked either from a App Delegate.
Card91 Card91KYC library allows developers to launch the Card91KYC View from their application to process and complete the aadhaar XML full KYC for NSDL cards.
Developers need to launch Card91KYC from their View with some required parameters mentioned below and a library completing the aadhaar KYC for the NSDL cards

Installation(CocoaPods and Info.plist configuration)iOS

iOS Minimum Requirements:

iOS Version : 14.0
Swift Version : 5.0 or later
Xcode Version: 14 or later

iOS Minimum Requirements:

NSCameraUsageDescription
We need access to your camera for KYC verification.
NSPhotoLibraryUsageDescription
We need access to your photos for KYC verification.

Calling of AppDelegate from the dart implementation.

Use MethodChannel for calling native ios class AppDelegate.
Use the below key to communicate to ios native class with required parameters mentioned below

 final int result = await platform.invokeMethod("InvokeNSDLSDK", {
        'mobile': '919920564559',
        'auth_token': "C91CHuAEHGRGTumedT+22MyZSfAwqN8i8LRH8Fq1u8RTXGvw=",
        'env': 'PROD_SANDBOX', // "PROD_SANDBOX" for production sandbox and "PROD" for production
        'pan': 'DHMPM9255F'
      });
import 'dart:io';

import 'package:card91/app/utils/constants.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class InvokeAadhaarSDK extends StatefulWidget {
  const InvokeAadhaarSDK({Key? key}) : super(key: key);

  @override
  State<InvokeAadhaarSDK> createState() => _InvokeAadhaarSDKState();
}

class _InvokeAadhaarSDKState extends State<InvokeAadhaarSDK> {
  static const platform = MethodChannel('flutter.native/intent');

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: Center(
          child: ElevatedButton(
              onPressed: () async {
                if (Platform.isAndroid) {
                  _android();
                } else if (Platform.isIOS) {
                  _iosNative();
                }
              },
              child: Text("Invoke Aadhaar SDK")),
        ),
      ),
    );
  }

/// calling Android Native//////

  Future<void> _android() async {
    print("into android");
    var dataRespForGetToken = await platform.invokeMethod('invoke_card91', {
      'MOBILE_NUMBER': '918871141300',
      'AUTH_TOKEN': "C91CHjGNUWvtdq6rKWuGteUTsnVwTsxzf88nBtrkdHqVh2aM=",
      'ENV': env(),
      'PAN': ''// Always send this empty string
    });
    print("dataRespForGetToken--->${dataRespForGetToken.toString()}");
  }

  ////************ FOR IOS SDK CALLING to AppDelegate*****************////

  Future<void> _iosNative() async {
    print("into ios");
    String callBackMessageFromNatveIOS;
    try {
      final int result = await platform.invokeMethod("InvokeNSDLSDK", {
        'mobile': '919920564559',
        'auth_token': "C91CHuAEHGRGTumedT+22MyZSfAwqN8i8LRH8Fq1u8RTXGvw=",
        'env': 'PROD_SANDBOX', // "PROD_SANDBOX" for production sandbox and "PROD" for production
        'pan': '' // Always send this empty string
      });
      callBackMessageFromNatveIOS = 'Battery level at $result % .';
      print("success.....");
    } on PlatformException catch (e) {
      print("failure.....");

      callBackMessageFromNatveIOS = "Failed to get battery level: '${e.message}'.";
    }
  }
}

Adding a Card91KYC framework

Open your project iOS project "Runner.xcodeproj" file in Xcode under ios folder of your project.

Add Card91KYC and OfflineAadhaar Framework into the project

open the workspace of the project

open the workspace of the project

Drag and drop the framework on General Setting of the project

Drag and drop the framework on General Setting of the project

Clean and Build the project

Changes on AppDelegate to listen the passed values from the dart implementation

import UIKit
import Flutter
import Card91KYC

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate, InvokeNSDLSDKCallBackListener {
    func returnDataToCallingApplication(_ status: String, _ message: String, _ code: String) {
        print("---------------");
                print(status);
                print(message);
                print(code);
                 // Optionally return a result to Dart
    }
    
    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        GeneratedPluginRegistrant.register(with: self)
        let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
        let videoChatChannel = FlutterMethodChannel(name: "flutter.native/intent", binaryMessenger: controller as! FlutterBinaryMessenger)
        videoChatChannel.setMethodCallHandler({
            [weak self] (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
           
            
            if(call.method == "InvokeNSDLSDK"){
                if let args = call.arguments as? [String: Any]{
                    let mobileNumber = args["mobile"] as? String // mobile number of the card holder
                    let enviroment = args["env"] as? String // Env passed from the dart function
                    let cardToken = args["auth_token"] as? String // Card holder token
                    let org_id = args["org_id"] as? String // Card organization id
                    self?.callingNSDLSDK(env:enviroment, mobile:mobileNumber, token:cardToken, orgid:org_id)
                }

            }})
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }
    
    func callingNSDLSDK(env: String?, mobile: String?, token: String?, orgid:String?) {
         DispatchQueue.global(qos: .background).async {
           DispatchQueue.main.async {
             let bundle = Bundle(for: InvokeNSDLSDK.self)
             let newVC = InvokeNSDLSDK(nibName: "InvokeNSDLSDK", bundle: bundle)
             newVC.InvokeNSDLSDKwithParams(
          env: env!, auth_token: token!,
          mobile: mobile!, pan: "", org_id: orgid!)
             newVC.delegate = self // Call back methods
             newVC.modalPresentationStyle = .fullScreen
             if let window = self.window, let rootViewController = window.rootViewController {
                    var currentController = rootViewController
                    while let presentedController = currentController.presentedViewController {
                     currentController = presentedController
                    }
                    currentController.present(newVC, animated: true, completion: nil)
                   }
        }
       }
      }

    }

INPUT PARAMETER DETAILS WHICH LAUNCHING THE SDK FRAMEWORK

NameTypeRequiredDescription
MOBILEstringtrueRegistered card holder mobile number (12 digit) with 91
AUTH_TOKENstringtrueCard Holder auth token (Card91 API)
ENVstringtrue"PROD_SANDBOX" for sandbox and "PROD" production environment
PANstringfalseRegistered card holder valid pan number (For NSDL pass empty value)
ORG_IDstringtrueCard organisation id

DIFFERENT CALLBACLK EVENTS

The events are as follows:

Event NameDescription
SUCCESSOn successful aadhaar KYC completion, developer needs to parse "bundle.getString("COMPLETE_KYC_SUCCESS")" for the same. In this scenario "KYC_RESPONSE_CODE" will comes as 00 and "COMPLETE_KYC_SUCCESS" key value will be "SUCCESS"
FAILEDOn un successful aadhaar KYC completion, developer needs to parse the key "COMPLETE_KYC_SUCCESS" from the bundle, value be "FAILED". In this scenario "KYC_RESPONSE_CODE" will not comes as 00 and detail reason will on the key "KYC_RESPONSE_DATA"