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

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

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

相关推荐
HSunR36 分钟前
ruoyi 若依 自定义注解 参数校验
java·前端·数据库
梦想的颜色1 小时前
【编程实战】AI 时代 APP 开发全栈硬核指南:技术选型 + AI 架构 + 模型落地全维度决策
python·flutter·react native·react.js·ai·桌面应用·milvus
拆房老料2 小时前
ONLYOFFICE也能像Microsoft Word和WPS一样分别设置中西文字体
前端·html·word·开源软件·wps
Solis程序员2 小时前
Stripe 幂等表:把「不确定的重试」变成「查表返回」
前端·安全·bootstrap·php·agent
李纲明2 小时前
WordPress 站点变慢:按 TTFB → 缓存 → 查询 → 前端 分层排查(含配置注意)
前端·缓存·性能优化·wordpress·后端开发
程序人生8882 小时前
PDF 转 Word 版式错乱、表格丢失?DocConverter Web 格式互转引擎的保真实践
前端·人工智能·opencv·机器学习·pdf·word
粥里有勺糖3 小时前
安利一下最近用的桌面“Agent” | T3 Code
前端·github·ai编程
xy34533 小时前
Axure 9.0 动态面板基本操作
前端·ui·html·axure·原型·产品设计
不停喝水3 小时前
【前端转全栈java速通课】 项目实战④7-11节 操作数据库-登录-注册-修改密码-注销-mubatis-plus简化crud-
java·前端·数据库
一水鉴天4 小时前
统一对象拓扑(UOT)设计全链定稿:从三件事分离到三继承 之1 20261010(豆包“查看聊天内容”继续)
前端·css