Flutter だけではどうしても実現できない機能がある場合に、ネイティブの機能を呼び出したい時があります。又は逆にネイティブ側から Flutter 側を呼びたい時もあると思います。
ここでは Flutter とプラットフォーム間で相互にメソッドを呼び出す方法について解説します。
Flutter 側の実装
こちらのライブラリを使うのでインポートします。
import 'package:flutter/services.dart'; // use MethodChannel
プラットフォーム側のメソッドを呼び出す
Flutter からプラットフォーム側のメソッドを呼び出す場合は、
// メソッドチャンネルを作成
final _channel = MethodChannel("net.cbtdev.sample/method");
// メソッドの呼び出し
var result = await _channel.invokeMethod('hello');
“net.cbtdev.sample/method” は、Flutter とプラットフォーム 側で共通で使うチャンネル名です。共通であればなんでも良いですが、「アプリID/カテゴリ」などの固有の名前が良いでしょう。
作成したチャンネルを経由して .invokeMethod でメソッドを呼び出します。
この関数は、第1引数が「メソッド名」、第2引数がデータになっています。(今回第2引数は省略しています)
プラットフォーム 側からの呼び出しを受ける
プラットフォーム 側からの呼び出しを Flutter で受ける場合は、
@override
void initState() {
super.initState();
// メソッドチャンネルを作成
final _channel = MethodChannel("net.cbtdev.sample/method");
// 受信
_channel.setMethodCallHandler((MethodCall call) {
switch (call.method) {
case 'hello':
print('私は Flutter です');
// 引数がある場合は call.arguments に入っています
break;
default:
print('');
break;
}
return;
});
}
呼び出す時と同じく、チャンネルを作成して、.setMethodCallHandler で受信します。
引数がある場合は、call.arguments に入ってきます。
プラットフォーム 側(iOS)の実装
構造は Flutter 側の実装とほとんど同じです。(iOSのみの解説になりますが、Androidでも同じような実装になっていると思われます)
Flutter 側からの呼び出しを受ける
Flutter 側の実装と同じく、チャンネルを作成して、.setMethodCallHandler で受信します。
iOS/Runner/AppDelegate.swift に以下のコード(Swift)を追加。
import UIKit
import Flutter
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
// ----- 追加するコードは、ここから
let _controller = window?.rootViewController as! FlutterViewController
let _channel = FlutterMethodChannel(
name: "net.cbtdev.sample/method",
binaryMessenger: _controller.binaryMessenger)
_channel.setMethodCallHandler({
(call: FlutterMethodCall, result: FlutterResult) -> Void in
switch(call.method) {
case "hello":
result("私は iOS です")
// 引数がある場合は call.arguments に入っています
return
default:
result("No Method")
return
}
})
// ----- ここまで
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
Flutter への戻り値は result() で返します。
引数がある場合は、call.arguments に入ってきます。
Flutter 側のメソッドを呼び出す
こちらも Flutter 側の実装と同じく、.invokeMethod で呼び出します。
// Flutter 側のメソッドを呼び出す
_channel.invokeMethod("hello", arguments: nil)
※ iOS 側では第2引数を省略できないので、arguments: を書いています。
コメント