[Flutter] การทำ bridging function (method channel) ไปยัง native iOS, Android
Flutter เป็นการเขียนโปรแกรมแบบ Hybrid หรือ Cross-platform ความจริงที่หนีไม่พ้นคือ มันมักจะตามหลัง Native อยู่บ้าง ทำให้บางครั้งอาจทำให้นักพัฒนาจำเป็นจะต้องทำให้ flutter คุยกับฝั่ง native ได้ด้วยตัวเอง และแน่นอนบทความนี้จะมาช่วยทำให้เห็นภาพมากขึ้น
สิ่งที่ต้องรู้ก่อน
- Channel ใช้เป็นช่องทางพูดคุยกันระหว่าง flutter, native มักมีการต่อ package ID ไปด้วยเพื่อป้องกันชนกับที่อื่น
- Method สำหรับระบุเมธอดการทำงาน
main.dart
static const _channel = MethodChannel('th.in.lordgift.flutter_native_bridged/call_channel');static FuturegetDeviceModel() async { try { final String model = await _channel.invokeMethod('getDeviceModel'); return "Device Model: $model"; } catch (e) { return "Error: $e"; } }
AppDelegate.swift
if let controller = window?.rootViewController as? FlutterViewController {
// Set up the MethodChannel to listen for calls from Flutter
let channel = FlutterMethodChannel(name: CHANNEL_NAME, binaryMessenger: controller.binaryMessenger)
channel.setMethodCallHandler { call, result in
switch call.method {
case "getDeviceModel":
// return value to Dart
result(UIDevice.current.model)
default:
result(FlutterMethodNotImplemented)
}
}
}
MainActivity.kt
// Set up the MethodChannel to listen for calls from Flutter
val channel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL_NAME)
channel.setMethodCallHandler { call, result ->
when (call.method) {
"getDeviceModel" -> {
// return value to Dart
result.success(Build.MODEL)
}
else -> result.notImplemented()
}
}
เท่านี้เราก็จะเรียกไปให้ code ฝั่ง native ทำงานต่อได้แล้ว
หากเราต้องการให้ native เรียกไปที่ flutter บ้างก็ทำคล้ายๆกัน คือต้อง invokeMethod() จาก native และทำ handler รอไว้ที่ flutter ครับ
// invokes another method (Swift)
channel.invokeMethod("nativeInvokesDart", arguments: "iOS")
// invokes another method (Kotlin)
channel.invokeMethod("nativeInvokesDart", "Android")
และฝั่ง flutter ต้องมีการ handle
static channelHandler() {
_channel.setMethodCallHandler((call) async {
if (call.method == 'nativeInvokesDart') {
print("${call.method} : ${call.arguments}");
}
});
}
ตัวอย่าง
ref.
