Flutter踩坑:原生IOS页面向Flutter通信

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 的通信就容易多了。

当然,我觉得这个问题应该有更好的解决方案,但是目前没有找到,先使用这个方式解决问题,以作记录。

如果有更好的解决方案的同学欢迎交流。👏🏻

相关推荐
随风一样自由3 小时前
【前端独角兽】刚进入前端领域的前端开发用jQuery还是Vue3?
前端·javascript·vue3·jquery
IMPYLH4 小时前
HTML 的 <data> 元素
前端·html
YHHLAI4 小时前
[特殊字符] 面试中的 Promise —— 从入门到精通
前端·javascript·面试
kyriewen6 小时前
我扒了 GPT-5.6 的全部编程跑分——有一项 OpenAI 没敢放出来
前端·gpt·ai编程
前端H7 小时前
微前端 v3 架构升级:从加载隔离到状态协同
前端·架构·状态模式
ZZZMMM.zip7 小时前
基于鸿蒙HarmonyOS NEXT开发AI英语口语应用:智能口语练习新体验与鸿蒙Flutter框架跨端实
人工智能·flutter·华为·harmonyos·鸿蒙·鸿蒙系统
陆枫Larry8 小时前
小程序包体积优化:用 SVG 图片替换 iconfont,并保留 CSS 控色能力
前端
心中有国也有家8 小时前
AtomGit Flutter 鸿蒙客户端:白噪音场景的视觉设计
学习·flutter·华为·harmonyos
心中有国也有家8 小时前
AtomGit Flutter 鸿蒙客户端:呼吸练习的完整生命周期
学习·flutter·华为·harmonyos
黑科技iOS上架9 小时前
ReactNative入门介绍
经验分享·ios