Android

Follow this guide to integrate Portal into your Flutter App.

In order to integrate Portal into your Flutter App currently you will need to write custom platform-specific code using platform channels.

Platform channels overview

On the client side, MethodChannel enables sending messages that correspond to method calls. On the platform side, MethodChannel on Android (MethodChannelAndroid) enable receiving method calls and sending back a result. These classes allow you to develop a platform plugin with very little 'boilerplate' code. You can check the Flutter official documentation for platform channels. You can check our Portal Flutter example.

Add Portal implementation for Android:

  1. Open the Android host portion of your Flutter app in Xcode.

  2. Add Portal Android SDK to the Android project, you can follow this Android setup guide.

  3. Open MainActivity.kt located under android > app > src > main > kotlin in the project navigation.

The client and host sides of a channel are connected through a channel name passed in the channel constructor. All channel names used in a single app must be unique; prefix the channel name with a unique 'identifier', for example: your.bundle.identifier/portal. Below the channel name and some method names are defined.

object Constants {
    const val FLUTTER_CHANNEL_NAME = "your.bundle.identifier/portal"
    const val METHOD_INITIALIZE_PORTAL = "initializePortal"
    const val METHOD_CREATE_WALLET = "createWallet"
}

Now inside the MainActivity.kt, configure channel and methods handling like this.

class MainActivity : FlutterActivity() {
    private lateinit var portal: Portal
    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)

        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, Constants.FLUTTER_CHANNEL_NAME)
            .setMethodCallHandler { call, result ->
                handleFlutterMethodCall(call, result)
            }
    }

    private fun handleFlutterMethodCall(call: MethodCall, result: MethodChannel.Result) {
        when (call.method) {
            Constants.METHOD_INITIALIZE_PORTAL -> initializePortal(call.arguments, result)
        }
    }

    private fun initializePortal(arguments: Any?, result: MethodChannel.Result) {
        if (arguments == null || arguments !is String || arguments.isBlank()) {
            result.error("FAILED", "Missing argument apiKey", null)
            return
        }

        try {
            portal = Portal(
                apiKey = arguments,
                featureFlags = FeatureFlags(isMultiBackupEnabled = true)
            )
            result.success("Portal initialized")
        } catch (e: Exception) {
            result.error("FAILED", e.message, null)
        }
    }
}

Then define a callback to handle any method invocation that comes from the Flutter side and they Switch on those Methods then execute the proper Kotlin implementation for each one and reply back to Flutter using a regular callback of type FlutterResult which is expected to be passed from Flutter side as a completion handler.

You will also need to define this implementation in your native iOS code as well for the code to work on both iOS and Android. Refer to this guide for iOS specific instructions.

Calling platform-specific code using platform channels

Now Portal Android implementation is ready for Flutter, Let's create the Flutter platform client: We will use the same channel name we defined above to initialize MethodChannel

static const platform = MethodChannel('your.bundle.identifier/portal');

Next, invoke a method on the method channel, specifying the concrete method to call using the String identifier initializePortal. The call might fail, so wrap the invokeMethod call in a try-catch statement.

Future<void> initializePortal(String apiKey) async {
  String message;
  try {
    final result = await platform.invokeMethod('initializePortal', apiKey);
    message = 'Success with message ${result?['message']}';
  } on PlatformException catch (e) {
    message = "Failed to initialize portal with error: '${e.message}'.";
  }
}

Finally, your Flutter function initializePortal to initialize portal is ready to be called. You can call it from Flutter side passing the apiKey to initialize Portal.

Last updated

Was this helpful?