本文主要从两个点来阐述两者之间的交互:Flutter to OC, OC to Flutter
.
Flutter发送消息到OC
有过OC和H5的朋友肯定知道,如果要从H5发送消息到OC,那么需要双方有一个约定的端口来进行识别,Flutter亦然.
这里举一个简单的例子,在Flutter
界面点击一个按钮,触发OC的方法,回调一个字符串到Flutter
中.
Flutter核心代码如下:
class InteractionState extends State<InteractionF2OC> {
// 对应OC中的FlutterMethodChannel
static const platform = const MethodChannel('com.allen.test.call');
String message = 'null message';
void _getNativeMessage() async{
String result;
try {
// OC回调中对应的”约定” : getFlutterMessage,[1,2,3]:传递参数
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: (){
// 点击按钮发送消息给OC
_getNativeMessage();
},
),
// OC接收到消息之后,会回调一个值过来显示
Text(message)
],
),
),
);
}
}
解释一下上面的代码:
- MethodChannel: 通过异步的方式和不同平台插件进行通信的命名通道.
- invokeMethod: 在当前channel执行一个特定的方法,而且可以携带参数.
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 特定方法的时候会触发到这里
if ([call.method isEqualToString:@"getFlutterMessage"]) {
result(@"接收到flutter的消息,回传信息from OC");
NSLog(@"接收到flutter的参数:%@",call.arguments);
}
}];
}
OC发送消息到Flutter
这里实现需求是,native跳转到flutter页面时,传递一个字符串参数过去.
OC发送消息到Flutter的时候,首先需要OC遵守FlutterStreamHandler
协议.
FlutterEventChannel *event = [FlutterEventChannel eventChannelWithName:@"com.allen.test.post" binaryMessenger:_vc];
[event setStreamHandler:self];
实现两个协议方法,在onListenWithArguments
方法中回调参数给Flutter,同时Flutter会注册一个监听并传递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端,需要注册一个监听,监听com.allen.test.post
这个通知.在监听方法中回调OC传递过来的参数.
class InteractionState extends State<InteractionOC2F> {
static const EventChannel eChanel = const EventChannel('com.allen.test.post');
@override
void initState(){
super.initState();
eChanel.receiveBroadcastStream("flutter 监听了通知").listen(_onEvent,onError: _onError);
}
String _message = 'null message';
// 这里回调过来了参数
_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),
),
);
}
}
以上是两个很简单的例子,解决了基本的交互问题.后续会有更多实用功能的更新.