Flutter とプラットフォーム(iOS)間で相互にメソッドを呼び出す

Flutter

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: を書いています。

コメント

タイトルとURLをコピーしました