Flutter: Adding custom platform-specific code (EventChannel)
西山 勇毅
Flutter
iOS
Swift
Development
Sensors

Flutterアプリで、ネイティブ側(バックエンド)からイベントを発行してUI側(フロントエンド)を更新する方法について説明します。以前、Flutterプラグインの実装方法の一部としてEventChannelを実装する方法は書いたことがあります、今回はプラグインを使わないで同じ機能実装する方法です。
フロントエンドとバックエンドで通信を行う方法として、MethodChannelとEventChannel大きく2つの方法があります。今回は、EventChannelを使った方法を説明します。MethodChannelを使う方法は、公式ドキュメントに詳しく記述されています。何故か、EventChannelを使う方法は公式ページでは見当たらない。。

Backend (iOS)¶
AppDelegate.swiftのdidFinishLaunchingWithOptions内に、FlutterEventChannelを生成し、FlutterStreamHandlerを設定する。
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
let measurementEvent = FlutterEventChannel(name: "com.sample.app/event", binaryMessenger: controller.binaryMessenger)
measurementEvent.setStreamHandler(HomeStreamHandler())
FlutterStreamHandlerには、onListenとonCancelの2つのメソッドが必要。onListenで、イベントのコールバック(FlutterEventSink)を取得し、onCancelでリスナーを解除する。
public class HomeStreamHandler: NSObject, FlutterStreamHandler {
var eventSink: FlutterEventSink?
public func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
self.eventSink = events
// TODO: イベントが発生したら、eventSink(Any)メソッドに任意の値を与えることで、UI側に値を引き渡すことができる。
// NOTE: サポートしてデータ形式は、表1を参照してください。
return nil
}
public func onCancel(withArguments arguments: Any?) -> FlutterError? {
eventSink = nil
return nil
}
}
Frontend (Flutter)¶
フロントエンド側では、EventChannelを生成し、receiveBroadcastStreamでイベントを受信する。
import 'package:flutter/services.dart';
import 'dart:collection';
class _MyHomePageState extends State<MyHomePage> {
static const eventChannel = const EventChannel('com.sample.app/event');
StreamSubscription _onChangedSubscription;
@override
void initState() {
// TODO: implement initState
super.initState();
this._onChangedSubscription = eventChannel.receiveBroadcastStream().listen((event) {
// NOTE: eventはdynamicなので、送信元の型に応じてキャストが必要
// NOTE: Dictionary型の場合、Mapになるかと思いきや、LinkedHashMapになっていた。
var data = event as LinkedHashMap;
var value = data['key'];
setState((){
// TODO: do something
});
});
}
サポートされているデータ形式¶
