Enode Developers

Link SDKs in Flutter

In this guide we will walk you through the steps to integrate the Link SDKs into your Flutter app.

You can integrate Enode’s Link SDKs for iOS and Android into your Flutter app by making them accessible through platform channels.

Using this guide, you will:

  1. Ensure that you have the prerequisites to get started
  2. Expose the Link SDKs in iOS and/or Android via platform channels
  3. Import the exposed native modules into your Flutter app

Copy linkPrerequisites

  • An existing Flutter application configured to build iOS and Android apps, with native code under /android and /ios directories
  • A server that calls Link UserAPI with API version 2024-01-01. You should be able to generate a linkToken to pass back to your Flutter client

Copy linkImplement the SDK on iOS

Copy linkSet up your Xcode project

Open the iOS project in your Flutter app (found under /ios/*.xcworkspace) in Xcode. Follow the Set up your Xcode project steps from our iOS SDK guide to add LinkKit by extracting the SDK archive, importing the framework, and configuring Bluetooth access.

Copy linkImplement a platform channel

Decide where in your existing iOS code you’d like to call Link UI via a platform-specific implementation. The following simple example is directly implemented within the existing AppDelegate.swift file that is part of every Flutter app, demonstrating the most critical piece of creating a Handler instance and calling its present() method within setMethodCallHandler.

Sample

import UIKit
import Flutter
import LinkKit

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {

    let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
    let linkChannel = FlutterMethodChannel(name: "com.your-app-name/linkkit",
                                                    binaryMessenger: controller.binaryMessenger)

    var handler: Handler?

    linkChannel.setMethodCallHandler({
      (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
      guard call.method == "showLinkUI" else {
          result(FlutterMethodNotImplemented)
          return
      }

        if let args = call.arguments as? Dictionary<String, String>,
          let token = args["linkToken"] as? String {
            handler = Handler(linkToken: token) { (code: LinkResultCode, errMsg: String?) in
                if (errMsg != nil) {
                    result(FlutterError(code: "LINK_ERROR",
                                        message: errMsg,
                                        details: nil))
                } else {
                    result(["result": code.rawValue])
                }
            }

            handler?.present(from: controller)
        }
    })
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

Copy linkImplement the SDK in Android

Copy linkImport the SDK to your project

Open the Android project in your Flutter app (found under /android), ideally in Android Studio. Follow our Android SDK guide to include the SDK in your app’s build.gradle. (In a Flutter project, you should add the dependency in /android/app/build.gradle.)

Copy linkConfigure your project

SDK versions

If necessary, you may have to increase your compile SDK version (34) and your minimum SDK version (23). For example, depending how you define the properties, your /android/app/build.gradle should resemble:

Sample

android {
  compileSdkVersion 34
	...
	defaultConfig {
    minSdkVersion 23
		targetSdkVersion 34
		...
	}
}

Copy linkStyles & permissions

The Link SDK makes use of a few style attributes and permissions. Follow the guide for our Android SDK to ensure that you are defining and applying these appropriately to avoid errors.

Copy linkConfigure ProGuard

Flutter’s code obfuscation can impact release builds. To avoid this, you can prevent any optimization of LinkKit by adding this to your proguard-rules.pro:

Sample

-keep class io.enode.link.** { *; }

Copy linkImplement a platform channel

Decide where in your existing Android code you’d like to call Link UI via a platform-specific implementation. The following simple example is directly implemented within the existing MainActivity.kt file that is part of every Flutter app, demonstrating the most critical piece of starting Link UI via showLinkUI() within setMethodCallHandler.

Sample

package com.your-app-name

import android.app.Activity
import android.content.Intent
import androidx.annotation.NonNull
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import io.enode.link.LinkKit

const val LINK_UI_REQUEST = 99

class MainActivity: FlutterActivity() {
    private val CHANNEL = "com.your-app-name/linkkit"
    private lateinit var _result: MethodChannel.Result;

    private fun showLinkUI(token: String) {
        val intent = Intent(activity, LinkKit::class.java)
        intent.putExtra(LinkKit.INTENT_LINK_TOKEN, token);
        activity.startActivityForResult(intent, LINK_UI_REQUEST, null);
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) {
        if (requestCode == LINK_UI_REQUEST) {
            if (resultCode == Activity.RESULT_OK) {
								_result.success(hashMapOf("result" to "success"))
            } else {
                _result.error(
                    intent?.getStringExtra(LinkKit.ERROR_CODE).toString(),
                    intent?.getStringExtra(LinkKit.ERROR_DETAILS),
                    "Error"
                )
            }
        } else {
            super.onActivityResult(requestCode, resultCode, intent);
        }
    }

    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler {
                call, result ->
            if (call.method == "showLinkUI") {
                val token: String? = call.argument("linkToken");
                if (token != null) {
                    _result = result;
                    showLinkUI(token);
                }
            }
        }
    }
}

Copy linkCall your platform code from Flutter

Now that you have implementations of the SDKs in your native iOS and Android projects, you can leverage them in your Dart code via method channels.

First, generate a linkToken on your server and make sure it is available in your Flutter app.

Next, decide where you want to show Link UI and create a MethodChannel there:

Sample

static const platform = MethodChannel('com.your-app-name/linkkit');

(Ensure the name of your channel is the same one as you used in your native implementations.)

When you are ready to open Link UI, call platform.invokeMethod<T>(), being sure to specify a return type T and passing in the method name that matches your native implementations. In the full example below, we use Map and showLinkUI.

Sample

String linkToken = /* comes from server */ ;
try {
  final result = await platform.invokeMethod<Map>(
      'showLinkUI', {'linkToken': linkToken}
  );
  if (result != null) {
    setState(() {
      _result = result["result"].toString();
    });
  }
} on Exception catch (e) {
  setState(() {
    _error = e.message;
  });
}

Copy linkOther ways to integrate

Link SDK for iOS

Integrating with the Link SDK for iOS

Link SDK for Android

Integrating with the Link SDK for Android

Was this article helpful?