【 Flutter 】Flutter を 基礎 から 学習 ( ライブラリ ) part210 プラットフォームアクセスとPluginパッケージ

基礎 から 学ぶ Flutter 」という書籍で  学習 したことを ブログでアウトプットしていこうと思います。今回は ライブラリ ( part210 )です。

前回

【 Flutter 】Flutter を 基礎 から 学習 ( ライブラリ ) part209 プラットフォームアクセスとPluginパッケージ

引き続き、ライブラリについて学びます。

プラットフォームアクセスとPluginパッケージ

プラットフォームへのアクセス方法

続きです。こんどはKotlin側で結果を返す処理を記述します。

package com.example.flutter_app

import android.content.Intent
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugins.GeneratedPluginRegistrant
import io.flutter.embedding.android.FlutterActivity

class MainActivity: FlutterActivity() {
    lateinit var channel: MethodChannel

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        GeneratedPluginRegistrant.registerWith(flutterEngine)
        // ①-① Dart側の①で指定した文字列
        this.channnel =
            MethodChanel(flutterEngine.dartExecutor.binaryMessenger, "sample/toPlatformScreen")
        this.channel.setMethodCallHandler { call, result ->
            when (call.method) {
                // ②-① Dart側の②で指定した文字列
                "toPlatformScreen" -> {
                    // ③-① Dart側の③で指定した引数
                    val label = call.argument("label_from_dart")
                    startActivityForResut(
                        NextActivity.intent(this@MainActivity)
                            .apply {
                                putExtra("label", label)
                            }, REQUEST_CODE)
                    // ④-① 成功した場合に渡す値
                    result.success("Platform Screen was displayed!!")
                }
                else -> result.notImplemented()
            }
        }
    }

    override fun onActivityResult(requestCode: Int,
                                  resultCode: Int,
                                  data: Intent?) {
        super.onActivityResult(requestCode, resultCode, resultCode, data)
        when (requestCode) {
            REQUEST_CODE -> {
                // ⑤-① Dartを呼び出す
                channel,invodeMethod(
                    // ⑥-① Dart側が処理を判断するためのキーを指定
                    "onClosed",
                    // ⑦-① Dart側に渡す値
                    mapOf("from_platform" to "Called onClosed() in Android")
                )
            }
        }
    }
}

続いてSwift側です。

import UIKit
import Flutter

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  var channel: FlutterMethodChannel!

  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    GeneratedPluginRegistrant.register(with: self)

    let controller: FlutterViewController = window?.rootViewController as! FlutterViewController
    // ①-② Dart側の①で指定した文字列
    channel = FlutterMethodChanel(name: "sample/toPlatformScreen", binaryMessenger: controllere as FlutterBinaryMessenger)

    channel.setMethodCallHandler({
      (call: FlutterMethodCall, result: FlutterResult) -> Void in
      switch call.method {
      // ②-② Dart側の②で指定した文字列
      case "toPlatformScreen":
        // ③-② Dart側の③で指定した引数
        let argument = call.arguments as! Dictionary<String, String>
        let label = arguments["label_from_dart"]!
        self.toPlatformScreen(label)
        // ④-② 成功した場合委に値を渡す値
        result("Platform Screen was displayed!!")
        break
      default:
        result(FlutterMethodNotImplemented)
      }
    })
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }

  private func toPlatformScreen(_ label: String) {
    let controller: FlutterViewController =
      window?.rootViewController as! FlutterViewController
    let storyboard: UIStoryboard
      = UIStoryboard(nae: "Next", bundle: nil)
    let nextController =
      storyboard.instantiateInitialViewController() as! NextController
    controller.present(nextController,
                       animated: true,
                       completion: {() in nextController.label.text = label
     })
     nextController.onClose = { () in
        // ⑤-② Dartを呼び出す
        self.channel.invokeMethod(
            // ⑥-② Dart側が処理を判断するためのキーを指定
            "onClose",
            // ⑦-② Dart側に渡す値
            arguments: ["from_platform": "called onClosed() is ios"]
        )
     }
  }

}

なるほど。こうやってDartとAndroid(Swift)がつながってパッケージになっていくんですね。

最後に

って、本書では動作確認なしで次のセクションに進んでしまうんですね。
ひどい!
しかしSwiftのコードはビルド出来ないのでこれでよかったのかもしれません。

今日はここまで!

参考