Flutter与原生通信之iOS

Flutter与原生通信之iOS

Flutter 与原生交互有三种方式:

  • MethodChannel
  • EventChannel
  • BasicMessageChannel

==MethodChannel==

是Flutter与原生交互的一种方式,此种方式传递的是方法,可以双向传递,可以携带参数,双向传递都可以有返回值

Flutter给原生端发送消息

  • Flutter端代码
csharp 复制代码
final methodChannel = const MethodChannel('test_method_channel');
Future<void> sendMessageFromMethodChannel() async {
  final result = await methodChannel.invokeMethod("method_one");
  print(result);
}

定义发送消息 MethodChannel生成对应的channel,需要指定channel的name 发送消息使用的是:invokeMethod 指定方法名,也可以带参数,有返回值

  • 原生端代码配置
swift 复制代码
var channel: FlutterMethodChannel

init(messager: FlutterBinaryMessenger) {

   channel = FlutterMethodChannel(name: "test_method_channel", binaryMessenger: messager)

     channel.setMethodCallHandler { (call , result) in

     print("接收到了来自Flutter发送的方法\(call.method)")

     result("我是原生返回给Flutter的消息")
   }
}

定义好channel,注册方法 setMethodCallHandler 在AppDelegate入口函数处需要初始化

javascript 复制代码
let controller = window.rootViewController as! FlutterBinaryMessenger
MethodChannelManager(messager: controller.binaryMessenger)

原生(iOS为例)给Flutter发送消息

  • iOS原生端配置
swift 复制代码
	var channel: FlutterMethodChannel

    init(messager: FlutterBinaryMessenger) {
        channel = FlutterMethodChannel(name: "test_method_channel", binaryMessenger: messager)
        channel.setMethodCallHandler { (call , result) in
            print("接收到了来自Flutter发送的方法\(call.method)")
            result("我是原生返回给Flutter的消息")
            self.startTimer()
        }
    }

    func startTimer() {
        Timer.scheduledTimer(timeInterval: TimeInterval(2), target: self, selector: #selector(sendMessageToFlutter), userInfo: nil, repeats: false)

    }
    @objc func sendMessageToFlutter() {
        channel.invokeMethod("ios_method", arguments: "我是原生主动发送过来的") {(result) in
            print(result)

     	}
  	}

原生端发送消息也是调用 invokeMethod,也可以以闭包形式接收到Flutter端的返回值

  • Flutter端配置
dart 复制代码
Future<void> setMethodChannelCallHandler() async {
  methodChannel.setMethodCallHandler((call) async {
    print('Flutter收到了原生端的方法:${call.method}, 传参为:${call.arguments} ---- call: $call');
    return Future.value('我是Flutter回传给原生端的数据');
  });
}

@override
void initState() {
  // TODO: implement initState
    super.initState();
    setMethodChannelCallHandler();
}

Flutter中配置的setMethodChannelCallHandler也可以给原生回传数据,直接返回一个 Future即可


==BasicMessageChannel==

也是双向交互,发送字符串和半结构化信息,有返回值

  • Flutter端 需要在Flutter端创建一个channel
ini 复制代码
final basicMessageChannel = const BasicMessageChannel('test_basic_message_channel', StandardMessageCodec());

第一个参数是channel的name 第二个参数是codec

swift 复制代码
/// The message codec used by this channel, not null.
final MessageCodec<T> codec;

看源码注释,它是一个抽象类,是message的编码和解码机制,这里只需要使用系统默认的标准方式 StandardMessageCodec即可 class StandardMessageCodec implements MessageCodec<Object?> StandardMessageCodec实现了抽象类 MessageCodec,具体可以看源码 发送消息

csharp 复制代码
Future<void> sendMessageFromBasicMessageChannel() async {
  final result = await basicMessageChannel.send('我是Flutter主动传递给原生的消息');
  print(result);

send方法返回值是一个Future,类型是泛型,所以可以通过await获取原生端返回给Flutter的值,下面在原生端会体现。 接收消息

csharp 复制代码
Future<void> setBasicMessageChannelCallHandler() async {
  basicMessageChannel.setMessageHandler((message) async {
    print('Flutter收到了原生端的消息:$message');
    return Future.value('我是Flutter回传给原生的消息');
  });
}
  • iOS原生端 定义一个BasicMessageChannelManager管理类,在入口函数中初始化:
javascript 复制代码
let controller = window.rootViewController as! FlutterBinaryMessenger
BasicMessageChannelManager(messager: controller.binaryMessenger)

接收消息

swift 复制代码
class BasicMessageChannelManager {
    var channel: FlutterBasicMessageChannel
    init(messager: FlutterBinaryMessenger) {
        channel = FlutterBasicMessageChannel(name: "test_basic_message_channel", binaryMessenger: messager)
        channel.setMessageHandler { (message, reply) in
            print("原生端收到了来自Flutter端的消息\(message!)")
            reply("原生端返回给Flutter端的消息")
        }
    }
}

在初始化方法中初始化 channel,并配置channel方法监听,message表示Flutter端发送过来的消息,reply是原生端给Flutter返回值的一个闭包 发送消息

scss 复制代码
@objc func sendMessageToFlutter() {
      channel.sendMessage("原生端主动发送给Flutter的消息") {(result) in
         print(result!)
     }
 }

channel通过sendMessage发送消息,可以带上后面的闭包,result为Flutter端返回给原生端的消息


==EventChannel==

是原生向Flutter传递数据流的通道,属于单向传输,只能由原生端调用,Flutter端是接收信息,常见的有网络变化监听,屏幕横竖屏切换,位置切换,电池电量,远程通知等事件。

  • Flutter端代码 final eventChannel = const EventChannel('test_event_channel'); 定义channel
scss 复制代码
Future<void> setEventChannel() async {
  _streamSubscription = eventChannel.receiveBroadcastStream().listen((event) {
    print('Flutter收到了原生端的事件:$event');
  }, onError: (error) {
    print(error);
  }, onDone: () {
    print('done');
  }, cancelOnError: true);
}

组件初始化中设置回调

  1. 闭包第一个回调为onData,参数event为泛型,表示原生端返回的信息内容
  2. onError: 报错会执行
  3. onDone: 时间完成会执行
  4. cancelOnError: 报错后是否取消事件

iOS原生端

swift 复制代码
class EventChannelManager: NSObject  {
    var channel: FlutterEventChannel
    var eventSink: FlutterEventSink?
    var count = 0
    var timer: Timer?
    init(messager: FlutterBinaryMessenger) {
        channel = FlutterEventChannel(name: "test_event_channel", binaryMessenger: messager)
    }
    func config() {
        channel.setStreamHandler(**self**)
    }
    func startTimer() {
       timer = Timer(timeInterval: TimeInterval(2), target: self, selector: #selector triggerEventChannel), userInfo: nil, repeats: true)
        RunLoop.current.add(timer!, forMode: .common)
    }
    @objc func triggerEventChannel() {
        count += 1
        eventSink?("当前数值为:\(count)")
    }
}

extension EventChannelManager : FlutterStreamHandler {

    func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
        self.eventSink = events
        startTimer()
        return nil
    }
    func onCancel(withArguments arguments: **Any**?) -> FlutterError? {
        return nil
    }
}

AppDelegate中调用:

scss 复制代码
let eventChannelManager = EventChannelManager(messager: messager)
eventChannelManager.config()

和其他两种通信方式不同的是,EventChannel需要在原生端实现 FlutterStreamHandler协议,获取到 FlutterEventSink,用它来进行消息的发送 eventSink?("当前数值为:(count)")

相关推荐
崔庆才丨静觅6 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60617 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了7 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅7 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅8 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅8 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment8 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅8 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊8 小时前
jwt介绍
前端
爱敲代码的小鱼8 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax