Flutter踩坑:原生IOS页面向Flutter通信
前言
在 Flutter APP
的开发过程中,有时不仅需要使用 Flutter
提供的组件,还需要使用原生的组件。
例如在对接外部 SDK
时,如果自己重新实现 SDK
的逻辑,无疑是本末倒置。
前文中我们已经完成原生安卓向 Flutter
发送信息,那么本篇文章我们来完成iOS原生页面
向Flutter
通信。
操作雷同,就是将 method channel
的调用,反过来,由原生执行 invokeMethod
,由 Flutter
接收 method
。
iOS
相对安卓的调用要更加顺畅一些,但是同样存在 MethodChannel
传递的问题。
执行
在插件中实例化FlutterMethodChannel
,并且注册 MethodCallHandler
。
同时将这个 MethodChannel
放到静态变量中,以便在 objc
页面中调用。
这个我在网上搜了很多方式,都是让实例化 Flutter Engine
或者实例化 plugin
插件,但是实际上都没能成功,估计重新实例化的已经不是当前的这个 Flutter Engine
实例或者插件实例了。
objc
代码的方式
c
// 省略import
+ (instancetype)sharedInstance {
static TestPluginIosPlugin *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
- (void)sendMessageToFlutter:(NSString *)message {
if (message) {
NSLog(@"Sending message to Flutter: %@", message);
NSLog(@"self.flutterChannel:::: %@", self.flutterChannel);
[self.flutterChannel invokeMethod:@"receiveMessageFromiOS" arguments:message];
} else {
NSLog(@"Message is nil, cannot send to Flutter.");
}
}
objc
页面中调用
c
[[TestPluginIosPlugin sharedInstance] sendMessageToFlutter:result];
如果是 Swift
的话,直接静态变量调用即可
swift
import Flutter
import UIKit
public class IosSdkFlutterPlugin: NSObject, FlutterPlugin {
// 静态变量
static var channel: FlutterMethodChannel?
public static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(name: "ios_sdk_flutter_plugin", binaryMessenger: registrar.messenger())
IosSdkFlutterPlugin.channel = channel
let instance = IosSdkFlutterPlugin()
registrar.addMethodCallDelegate(instance, channel: channel)
}
}
Swift中调用
swift
import UIKit
class YourViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.white
let button = UIButton(frame: CGRect(x: 50, y: 100, width: 200, height: 50))
button.setTitle("Tap Me", for: .normal)
button.addTarget(self, action: #selector(labelTapped), for: .touchUpInside)
self.view.addSubview(button)
}
@objc func labelTapped(){
IosSdkFlutterPlugin.channel!.invokeMethod("onMessageReceived", arguments: "your_arguments")
}
}
在 Flutter
页面中接收到信息
c
MethodChannel("test_plugin").setMethodCallHandler((call) async {
print("接到方法调用: ${call.method}");
if (call.method == 'onMessageReceived') {
final String message = call.arguments as String;
print('========aaa Received message from IOS: $message');
// TODO: 处理接收到的信息
}
});
总结
原生向 Flutter
发送信息时,会遇到许多莫名其妙的问题,网上搜了很多方法,但是都无效。
安卓的调用方式通了过后,再来处理 iOS
的通信就容易多了。
当然,我觉得这个问题应该有更好的解决方案,但是目前没有找到,先使用这个方式解决问题,以作记录。
如果有更好的解决方案的同学欢迎交流。👏🏻