?在 IOS 中实现 Flutter 与 Object-c通信:效果如下图
一共有两个页面:首先会传入一个 Flutter 路由的初始值;然后实现 原生和Flutter的相互调用
因为是用 Main.storybord 做的页面;所有跳转已经 FlutterViewController 也都是在? prepareForSegue 中实现的
?
FirstViewController.m 中的跳转
//
// NSObject+FirstViewController.m
// NativeFlutter
//
// Created by John on 2021/11/22.
//
#import "FirstViewController.h"
#import "MainViewController.h"
#import <Flutter/Flutter.h>
@interface FirstViewController ()
@end
@implementation FirstViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (IBAction)onClick:(id)sender {
NSLog(@"Button click %@",_textInput.text);
UIStoryboard *sb = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
MainViewController *vc = [sb instantiateViewControllerWithIdentifier:@"MainViewController"];
vc.modalPresentationStyle = UIModalPresentationFullScreen;
vc.inputParam = _textInput.text;
[self presentViewController:vc animated:YES completion:nil];
// MainViewController *vc = [MainViewController new];
//vc.inputParam =_textInput.text;
// TestViewController *vc = [TestViewController alloc];
// [self presentViewController:vc animated:true completion:nil];
// UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
// [self presentViewController:nav animated:YES completion:nil];
}
@end
MainViewController.m 中的具体实现
//
// MainViewController.m
// NativeFlutter
//
// Created by John on 2021/11/22.
//
#import "MainViewController.h"
#import <Flutter/Flutter.h>
@interface MainViewController ()<FlutterStreamHandler>
@property (nonatomic) FlutterViewController* flutterViewController;
@property (nonatomic) FlutterBasicMessageChannel* messageChannel;
@property (nonatomic) FlutterEventChannel* eventChannel;
@property (nonatomic) FlutterMethodChannel* methodChannel;
@property (nonatomic) FlutterEventSink eventSink;
@end
@implementation MainViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sendMessage:) name:@"sendMessage" object:nil];
NSLog(@"MainViewController %@",self.inputParam);
// UIStoryboard *sb = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
// self.flutterViewController = [sb instantiateViewControllerWithIdentifier:@"FlutterViewController"];
// [self.flutterViewController setInitialRoute:self.inputParam];
// [self initChannel];
}
#pragma mark - naviagor
- (void)prepareForSegue:(UIStoryboardSegue*)segue sender:(id)sender {
if ([segue.destinationViewController isKindOfClass:[FlutterViewController class]]) {
self.flutterViewController = segue.destinationViewController;
[self.flutterViewController setInitialRoute:self.inputParam];
[self initChannel];
}
}
- (void)sendMessage:(NSNotification*)notification{
NSString* mesage = [notification.object valueForKey:@"message"];
NSLog(@"---要传入 Flutter的参数 :%@",mesage);
if ([@"true" isEqual:[notification.object valueForKey:@"useEventChannel"]]) {
//用EventChannel传递数据
if (self.eventSink != nil) {
self.eventSink(mesage);
}
} else {
//用MessageChannel传递数据
[self.messageChannel sendMessage: mesage reply:^(id _Nullable reply) {
if (reply != nil) {
[self sendShow:reply];
}
}];
}
}
#pragma mark - init Channel
- (void)initChannel{
[self initMessageChannel];
[self initEventChannel];
[self initMethodChannel];
}
- (void)initMessageChannel{
self.messageChannel = [FlutterBasicMessageChannel messageChannelWithName:@"BasicMessageChannelPlugin" binaryMessenger:self.flutterViewController codec:[FlutterStringCodec sharedInstance]];
MainViewController* __weak weakSelf = self;
//设置消息处理器,处理来自Dart的消息
[self.messageChannel setMessageHandler:^(NSString* message, FlutterReply reply) {
reply([NSString stringWithFormat:@"BasicMessageChannel收到:%@",message]);
[weakSelf sendShow:message];
}];
}
- (void)initEventChannel{
self.eventChannel = [FlutterEventChannel eventChannelWithName:@"EventChannelPlugin" binaryMessenger:self.flutterViewController];
//设置消息处理器,处理来自Dart的消息
[self.eventChannel setStreamHandler:self];
}
- (void)initMethodChannel{
self.methodChannel = [FlutterMethodChannel methodChannelWithName:@"MethodChannelPlugin" binaryMessenger:self.flutterViewController];
MainViewController* __weak weakSelf = self;
[self.methodChannel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult _Nonnull result) {
if ([@"send" isEqualToString:call.method]) {
result([NSString stringWithFormat:@"MethodChannelPlugin收到:%@",call.arguments]);//返回结果给Dart);
[weakSelf sendShow:call.arguments];
}
}];
}
- (void)sendShow:(NSString*) message{
NSLog(@"------sendShow %@",message);
[[NSNotificationCenter defaultCenter] postNotificationName:@"showMessage" object:message];
}
//#pragma mark - <FlutterStreamHandler>
//这个onListen是Flutter端开始监听这个channel时的回调,第二个参数 EventSink是用来传数据的载体
- (FlutterError* _Nullable)onListenWithArguments:(id _Nullable)arguments eventSink:(FlutterEventSink)eventSink {
// arguments flutter给native的参数
// 回调给flutter, 建议使用实例指向,因为该block可以使用多次
self.eventSink = eventSink;
return nil;
}
/// flutter不再接收
- (FlutterError* _Nullable)onCancelWithArguments:(id _Nullable)arguments {
// arguments flutter给native的参数
self.eventSink = nil;
return nil;
}
@end
iso 原生页面中的 两个按钮的实现
//
// ViewController.m
// NativeFlutter
//
// Created by John on 2021/11/22.
//
#import "ViewController.h"
#import <Flutter/Flutter.h>
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(showMessage:) name:@"showMessage" object:nil];
}
- (void)showMessage:(NSNotification*)notification{
id params = notification.object;
self.textInput.text = [NSString stringWithFormat:@"来自Dart:%@",params];
}
- (IBAction)onBasicMessageChannel:(id)sender {
NSLog(@"onBasicMessageChannel");
NSString * text= self.textInput.text;
[[NSNotificationCenter defaultCenter] postNotificationName:@"sendMessage" object:@{@"message": text,@"useEventChannel": @"true"}];
}
- (IBAction)onNethodChannel:(id)sender {
NSLog(@"onNethodChannel");
NSString * text= self.textInput.text;
[[NSNotificationCenter defaultCenter] postNotificationName:@"sendMessage" object:@{@"message": text,@"useEventChannel":@"false"}];
}
@end
|