Flutter


To continue with the implementation of the SDK, you must have the Flutter environment installed on your computer. You can follow the official Flutter documentation to install the Flutter environment.

Set up


1. Dart Configuration

To use the SDK you must configure a MethodChannel in your file where you will invoke the SDK. You can use the following code as a guide:

main.dart

import 'dart:async';

// MethodChannel to invoke the Autentikar SDK
// The channel name must be the same as the one in the Android and iOS projects
static const methodChannel = MethodChannel('invokeAK');

// Response from the Autentikar SDK
String response = 'No response yet';


// Method to invoke the Autentikar SDK
Future<void> _invokeAK() async {
    // Invoke the Autentikar SDK and get the response
    // The response will be a dynamic JSON object or instance ID
    // Send the arguments to the SDK via MethodChannel
    // initAK is the method name in the Android and iOS projects
    try {
        final Object result = await methodChannel.invokeMethod(
            'initAK',
            { // arguments to send to the SDK
            "flowId": "your_flow_id",
            "country": "xx",
            "docType": "xx",
            "idNum": "xxx"
            },
        );
        setState(() {
          // Set the response
          response = result.toString();
        });
    } on PlatformException catch (e) {
        setState(() {
          response = "Failed to Invoke AK: '${e.message}'.";
        });
    }
 }

  // your ui code
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: SingleChildScrollView(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
                const SizedBox(height: 40),
                ElevatedButton(
                onPressed: _invokeAK, // invoke the SDK
                child: const Text('Invoke AK'),
              ),
              const Text(
                'Response:',
                style: TextStyle(fontWeight: FontWeight.bold),
              ),
              Text(
                response, // response from the SDK
              ),
            ],
          ),
        ));
    }

2. Android Configuration

To android configuration you mush the following previous guide Android. Once you have completed the previous guide, you must add the following code to your MainActivity.java file:

2.1. Add the following code to your MainActivity.java class:

This code will invoke the SDK and return the response to the MethodChannel in your main.dart file.

MainActivity.java

public class MainActivity extends FlutterActivity implements MethodChannel.MethodCallHandler {

    // Response from the SDK
    static String ak_response;
    private MethodChannel.Result _result;

    // Parameters to send to the SDK
    public static final String FLOW_ID = "flowID";
    public static final String COUNTRY = "country";
    public static final String DOC_TYPE = "docType";
    public static final String ID_NUM = "id_num";

    @Override
    public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
        super.configureFlutterEngine(flutterEngine);
        // Set the MethodChannel to invoke the SDK as ``invokeAK``
        new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), "invokeAK").setMethodCallHandler(this);
    }

    // Add onMethodCall method to invoke the SDK 
    @Override
    public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
        // Check if the method is ``initAK``
        if (call.method.equals("initAK")) {

            // Get the arguments
            String flowId = call.argument("flowId");
            String country = call.argument("country");
            String docType = call.argument("docType");
            String idNum = call.argument("idNum");

            // check if the arguments are not null
            if (flowId == null || country == null || docType == null || idNum == null) {
                result.error("ERROR", "Missing arguments", null);
                return;
            }

            // Set the result to return the response to the MethodChannel
            _result = result;

            // Invoke ``AKFragmentActivity`` to start the SDK
            Intent akActivity = new Intent(this, AKFragmentActivity.class);

            // Set the arguments to send to the SDK
            akActivity.putExtra(FLOW_ID, flowId);
            akActivity.putExtra(COUNTRY, country);
            akActivity.putExtra(DOC_TYPE, docType);
            akActivity.putExtra(ID_NUM, idNum);

            // Start the SDK
            this.startActivityForResult(akActivity, 1000);
        }
    }

    // Add onActivityResult method to get the response from the ``AKFragmentActivity``
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // Check if the result code is OK
        if (resultCode == Activity.RESULT_OK) {
            // Get the response from the SDK
            _result.success(ak_response);
            return;
        }

        // if the result code is CANCELED or other then return the response to the MethodChannel
        _result.success("User cancel");
    }
}

2.2. Create AKFragmentActivity.java class:

This class will start the SDK and return the response to the MainActivity.java class.

AKFragmentActivity.java

public class AKFragmentActivity extends FlutterFragmentActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Get the arguments from the ``MainActivity.java`` class
        Bundle extras = getIntent().getExtras();
        String flowId = extras.getString(MainActivity.FLOW_ID);
        String country = extras.getString(MainActivity.COUNTRY);
        String docType = extras.getString(MainActivity.DOC_TYPE);
        String idNum = extras.getString(MainActivity.ID_NUM);

        // set the options for the SDK
        InitFlow options = Options.getStart().inFlowID(
                flowId, // set the flow id of the SDK
                new User(country,docType,idNum), // set the user of the SDK
                CoreStage.QA, // set the stage of the SDK
                null, // set custom fields of the SDK (optional)
                null, // set files of the SDK (optional)
                ResponseType.INSTANCE_RESPONSE
        );

        // Start the SDK
        AKCore.init(flowResultLauncher, options);

    }

    // Add the following code to get the response from the SDK
    private final ActivityResultLauncher<Unit> flowResultLauncher = registerForActivityResult(new AKFlowResultContract(), result -> {

        // Check if the result is OK
        if (result.component1() == AKResultType.RESULT) {

            // Get the response from the SDK
            AKReturn akResult = result.component2();

            // JsonParser to parse the response to Json String
            JsonElement jsonElement = JsonParser.parseString(new Gson().toJson(akResult.getInstanceResponse()));
            Gson gson = new GsonBuilder().setPrettyPrinting().create();

            // Set Json String to the ``MainActivity.ak_response``
            MainActivity.ak_response = gson.toJson(jsonElement);

            // Set the result code to OK
            setResult(Activity.RESULT_OK);
        }

        // finish the activity
        finish();
    });
}

3. iOS Configuration

To iOS configuration you mush the following previous guide iOS. Once you have completed the previous guide, you must add the following code to your AppDelegate.swift file or custom ViewController.swift file.

In this guide we will use the AKViewController.swift file to configure FlutterMethodChannel and invoke the SDK.

3.1. Add the following code to your AKViewController.swift class:

This code will invoke the SDK and return the response to the FlutterMethodChannel in your main.dart file.

AKViewController.swift
import UIKit
import AKCoreSwift


class AKViewController: FlutterViewController {
    
    lazy var result: FlutterResult? = nil
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // Set the MethodChannel to invoke the SDK as ``invokeAK``
        let invokeAK = FlutterMethodChannel(name: "invokeAK", binaryMessenger: binaryMessenger)

        // Add onMethodCall method to invoke the SDK
        invokeAK.setMethodCallHandler { call, flutterResult in
            // Check if the method is ``initAK``
            if call.method == "initAK" {

                // Get the arguments
                let flowId = (call.arguments as? [String: String] ?? [:])["flowId"] ?? ""
                let country = (call.arguments as? [String: String] ?? [:])["country"] ?? ""
                let docType = (call.arguments as? [String: String] ?? [:])["docType"] ?? ""
                let idNum = (call.arguments as? [String: String] ?? [:])["idNum"] ?? ""

                // Check if the arguments are not null
                if !flowId.isEmpty && !country.isEmpty && !docType.isEmpty && !idNum.isEmpty {

                    DispatchQueue.main.asyncAfter(deadline: .now(), execute: {

                        // Set the options for the SDK
                        let options = AKCoreOptions.start.inFlowID(flowId: flowId, user: User(country: country, docType: docType, idNum: idNum), stage: .qa, responseType: .instance_response)

                        // Set the result to return the response to the MethodChannel
                        self.result = flutterResult

                        // Start the SDK
                        AKCore.start(self, options: options)
                    })
                }
            }
        }
    }      
}

// Add AKDynamicFlowDelegate to get the response from the SDK
extension AKViewController: AKDynamicFlowDelegate {

    // Add onSuccess method to get the response from the SDK
    func onSuccess(_ result: Any?) {

        // Check if the response is not null
        if let result = result as? AKReturn, let map = result.instanceResponse as? [String: AnyCodable] {
            do {

                // Encode the response to Json String
                let jsonData = try JSONEncoder().encode(map)
                let jsonString = String(data: jsonData, encoding: .utf8)!

                // Return the response to the MethodChannel
                self.result?(jsonString)
            } catch {

                // Return the error to the MethodChannel
                self.result?(FlutterError(code: "Error", message: "Error: \(error.localizedDescription)", details: nil))
            }
        }
    }
    
    // Add onFailure method to get the response from the SDK
    func onFailure() {

        // Return the error to the MethodChannel
        result?(FlutterError(code: "CANCEL", message: "USER OR SDK CANCEL", details: nil))
    }
}

Response


The response from the SDK is a Dynamic Json String. The response will be returned to the MethodChannel in your main.dart file.