本文主要從兩個點來闡述兩者之間的交互:Flutter to OC, OC to Flutter
.
Flutter發(fā)送消息到OC
有過OC和H5的朋友肯定知道,如果要從H5發(fā)送消息到OC,那么需要雙方有一個約定的端口來進行識別,Flutter亦然.
這里舉一個簡單的例子,在Flutter
界面點擊一個按鈕,觸發(fā)OC的方法,回調(diào)一個字符串到Flutter
中.
Flutter核心代碼如下:
class InteractionState extends State<InteractionF2OC> {
// 對應(yīng)OC中的FlutterMethodChannel
static const platform = const MethodChannel('com.allen.test.call');
String message = 'null message';
void _getNativeMessage() async{
String result;
try {
// OC回調(diào)中對應(yīng)的”約定” : getFlutterMessage,[1,2,3]:傳遞參數(shù)
result = await platform.invokeMethod('getFlutterMessage',[1,2,3]);
} on PlatformException catch (e) {
result = "error message $e";
}
setState(() {
message = result;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('test page')
),
body: Center(
child: Column(
children: <Widget>[
RaisedButton(
child: Text('get message'),
onPressed: (){
// 點擊按鈕發(fā)送消息給OC
_getNativeMessage();
},
),
// OC接收到消息之后,會回調(diào)一個值過來顯示
Text(message)
],
),
),
);
}
}
解釋一下上面的代碼:
- MethodChannel: 通過異步的方式和不同平臺插件進行通信的命名通道.
- invokeMethod: 在當前channel執(zhí)行一個特定的方法,而且可以攜帶參數(shù).
OC中的代碼如下:
- (IBAction)push:(id)sender {
FlutterViewController *vc = [[FlutterViewController alloc] initWithProject:nil nibName:nil bundle:nil];
vc.navigationItem.title = @"first flutter app";
[self.navigationController.navigationBar setHidden:YES];
[self.navigationController pushViewController:vc animated:YES];
_vc = vc;
// 從flutter 接收到消息,并傳值到OC
[self getFlutterMessage];
}
- (void)getFlutterMessage{
FlutterMethodChannel *channel = [FlutterMethodChannel methodChannelWithName:@"com.allen.test.call" binaryMessenger:_vc];
[channel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult _Nonnull result) {
// Flutter invokeMethod 特定方法的時候會觸發(fā)到這里
if ([call.method isEqualToString:@"getFlutterMessage"]) {
result(@"接收到flutter的消息,回傳信息from OC");
NSLog(@"接收到flutter的參數(shù):%@",call.arguments);
}
}];
}
OC發(fā)送消息到Flutter
這里實現(xiàn)需求是,native跳轉(zhuǎn)到flutter頁面時,傳遞一個字符串參數(shù)過去.
OC發(fā)送消息到Flutter的時候,首先需要OC遵守FlutterStreamHandler
協(xié)議.
FlutterEventChannel *event = [FlutterEventChannel eventChannelWithName:@"com.allen.test.post" binaryMessenger:_vc];
[event setStreamHandler:self];
實現(xiàn)兩個協(xié)議方法,在onListenWithArguments
方法中回調(diào)參數(shù)給Flutter,同時Flutter會注冊一個監(jiān)聽并傳遞arguments
過來:
- (FlutterError *)onListenWithArguments:(id)arguments eventSink:(FlutterEventSink)events{
if (events) {
events(@"OC post message to flutter");
}
NSLog(@"arguments 1 : %@",arguments);
return nil;
}
- (FlutterError *)onCancelWithArguments:(id)arguments{
NSLog(@"arguments 2 : %@",arguments);
return nil;
}
在Flutter端,需要注冊一個監(jiān)聽,監(jiān)聽com.allen.test.post
這個通知.在監(jiān)聽方法中回調(diào)OC傳遞過來的參數(shù).
class InteractionState extends State<InteractionOC2F> {
static const EventChannel eChanel = const EventChannel('com.allen.test.post');
@override
void initState(){
super.initState();
eChanel.receiveBroadcastStream("flutter 監(jiān)聽了通知").listen(_onEvent,onError: _onError);
}
String _message = 'null message';
// 這里回調(diào)過來了參數(shù)
_onEvent(Object event){
setState(() {
_message = event.toString();
});
}
_onError(Object error){
setState(() {
_message = "error message : $error";
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('test page')
),
body: Center(
// 這個message就是OC傳遞過來的值
child: Text(_message),
),
);
}
}
以上是兩個很簡單的例子,解決了基本的交互問題.后續(xù)會有更多實用功能的更新.