flutter开发实战-MethodChannel实现flutter与iOS双向通信

news/2024/7/8 5:21:11

flutter开发实战-MethodChannel实现flutter与iOS双向通信

最近开发中需要iOS与flutter实现通信,这里使用的MethodChannel

如果需要flutter与Android实现双向通信,请看
https://blog.csdn.net/gloryFlow/article/details/132218837

这部分与https://blog.csdn.net/gloryFlow/article/details/132218837中的一致,这里实现一下iOS端的MethodChannel设置。

一、MethodChannel

MethodChannel:用于传递方法调用(method invocation)。
通道的客户端和宿主端通过传递给通道构造函数的通道名称进行连接

一个应用中所使用的所有通道名称必须是唯一的
使用唯一的域前缀为通道名称添加前缀,比如:samples.flutter.dev/battery

官网 https://flutter.cn/docs/development/platform-integration/platform-channels

二、在flutter端实现MethodChannel

我们需要创建一个名字为"samples.flutter.dev/test"的通道名称。
通过invokeNativeMethod与setMethodCallHandler来实现

invokeNativeMethod:调用Android端的代码
setMethodCallHandler:设置方法回调,用于接收Android端的参数

代码如下

import 'package:flutter/services.dart';

//MethodChannel
const methodChannel = const MethodChannel('samples.flutter.dev/test');

class FlutterMethodChannel {
  /*
 * MethodChannel
 * 在方法通道上调用方法invokeMethod
 * methodName 方法名称
 * params 发送给原生的参数
 * return数据 原生发给Flutter的参数
 */
  static Future<Map> invokeNativeMethod(String methodName,
      [Map? params]) async {
    var res;
    try {
      if (params == null) {
        res = await methodChannel.invokeMethod('$methodName');
      } else {
        res = await methodChannel.invokeMethod('$methodName', params);
      }
    } catch (e) {
      res = {'Failed': e.toString()};
    }
    return res;
  }

  /*
 * MethodChannel
 * 接收methodHandler
 * methodName 方法名称
 * params 发送给原生的参数
 * return数据 原生发给Flutter的参数
 */
  static void methodHandlerListener(Future<dynamic> Function(MethodCall call)? handler) {
    methodChannel.setMethodCallHandler(handler);
  }
}

使用该MethodChannel,我们需要使用MethodChannel
使用代码如下

  
  void initState() {
    // TODO: implement initState
    super.initState();

    setMethodHandle();
  }

  void setMethodHandle() {
    FlutterMethodChannel.methodHandlerListener((call) {
      print("methodHandlerListener call:${call.toString()}");
      if ("methodToFlutter" == call.method) {
        print("methodToFlutter arg:${call.arguments}");
      }
      return Future.value("message from flutter");
    });
  }

  Future<void> invokeNativeMethod() async {
    var result = await FlutterMethodChannel.invokeNativeMethod("methodTest", {"param":"params from flutter"});
    print("invokeNativeMethod result:${result.toString()}");
  }

  void testButtonTouched() {
    invokeNativeMethod();
  }

  
  void dispose() {
    // TODO: implement dispose
    super.dispose();
  }

这里我们处理了方法methodToFlutter来接收iOS端的传参数调用,同时处理后我们将结果"message from flutter"返回给iOS端。
我们调用iOS端的方法methodTest,并且传参,获取iOS端传回的结果。

三、在iOS端实现MethodChannel

在iOS中,同样我们实现了MethodChannel。
iOS实现MethodChannel需要实现FlutterPlugin,实现registerWithRegistrar
我这里命名一个SDFlutterMethodChannelPlugin继承NSObject,通过实现registerWithRegistrar方法

+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
    FlutterMethodChannel *methodChannel = [FlutterMethodChannel methodChannelWithName:kFlutterMethodChannelName binaryMessenger:[registrar messenger] codec:[FlutterStandardMethodCodec sharedInstance]];
        
    SDFlutterMethodChannelPlugin *instance = [[SDFlutterMethodChannelPlugin alloc] initWithMethodChannel:methodChannel];
    
    // 将插件注册为来自Dart端的传入方法调用的接收者 在指定的“ FlutterMethodChannel”上。
    [registrar addMethodCallDelegate:instance channel:methodChannel];
}

同样在插件SDFlutterMethodChannelPlugin中设置setMethodCallHandler及调用Flutter的方法

例如

__weak typeof(self) weakSelf = self;
        [self.methodChannel setMethodCallHandler:^(FlutterMethodCall *call, FlutterResult result) {
            [weakSelf handleMethodCall:call result:result];
        }];

通过handleMethodCall可以处理方法methodTest处理接收来自flutter的参数,处理后并将结果返回给flutter。

整体代码如下

SDFlutterMethodChannelPlugin.h

#import <Foundation/Foundation.h>
#import <Flutter/Flutter.h>

@class SDFlutterMethodChannelPlugin;

typedef void (^SDFlutterMethodChannelPluginCompletionBlock)(SDFlutterMethodChannelPlugin *plugin);

@interface SDFlutterMethodChannelPlugin : NSObject<FlutterPlugin>

- (instancetype)initWithMethodChannel:(FlutterMethodChannel *)methodChannel;

@end

SDFlutterMethodChannelPlugin.m

#define kFlutterMethodChannelName @"samples.flutter.dev/test"


@interface SDFlutterMethodChannelPlugin ()<FlutterStreamHandler>

@property (nonatomic, strong) FlutterMethodChannel *methodChannel;

@property (nonatomic, strong) NSTimer *sendMessageTimer;


@end

@implementation SDFlutterMethodChannelPlugin

- (instancetype)initWithMethodChannel:(FlutterMethodChannel *)methodChannel {
    self = [super init];
    if (self) {
        self.flutterBridgeConfig = [[DFFlutterBridgeConfig alloc] init];
                
        self.methodChannel = methodChannel;
        __weak typeof(self) weakSelf = self;
        [self.methodChannel setMethodCallHandler:^(FlutterMethodCall *call, FlutterResult result) {
            [weakSelf handleMethodCall:call result:result];
        }];
        [self startSendMessageTimer];
    }
    return self;
}

+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
    FlutterMethodChannel *methodChannel = [FlutterMethodChannel methodChannelWithName:kFlutterMethodChannelName binaryMessenger:[registrar messenger] codec:[FlutterStandardMethodCodec sharedInstance]];
        
    SDFlutterMethodChannelPlugin *instance = [[SDFlutterMethodChannelPlugin alloc] initWithMethodChannel:methodChannel];
    
    // 将插件注册为来自Dart端的传入方法调用的接收者 在指定的“ FlutterMethodChannel”上。
    [registrar addMethodCallDelegate:instance channel:methodChannel];
}

#pragma mark - FlutterPlugin协议方法
- (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result {
    NSLog(@"config handleMethodChannel callmethod:%@,params:%@,result:%@", call.method, call.arguments, result);
    
    // 没有处理,需要单独处理
    NSString *method=call.method;
    if ([method isEqualToString:@"methodTest"]) {
        
        NSLog(@"flutter 调用到了 ios test");
        NSMutableDictionary *dic = [NSMutableDictionary dictionary];
        [dic setObject:@"result.success 返回给flutter的数据" forKey:@"message"];
        [dic setObject: [NSNumber numberWithInt:200] forKey:@"code"];

        result(dic);
        
    } else if ([method isEqualToString:@"test2"]) {
        NSLog(@"flutter 调用到了 ios test2");
        result(@YES);
    } else {
        result(FlutterMethodNotImplemented);
    }
}

#pragma mark - 开启定时器
- (void)sendMessageTimerAction {
    // 开启
    [self.methodChannel invokeMethod:@"methodToFlutter" arguments:@"Params from Android"];
}

/**
 开启定时器
*/
- (void)startSendMessageTimer {
    if (_sendMessageTimer) {
        return;
    }
    //开始其实就是开始定时器
    _sendMessageTimer = [NSTimer timerWithTimeInterval:6 target:self selector:@selector(sendMessageTimerAction) userInfo:nil repeats:YES];
    //加到runloop
    [[NSRunLoop currentRunLoop] addTimer:_sendMessageTimer forMode:NSRunLoopCommonModes];
}

/**
 结束定时器
 */
- (void)stopSendMessageTimer {
    //暂停其实就是销毁计时器
    [_sendMessageTimer invalidate];
    _sendMessageTimer = nil;
}

@end

在iOS中需要在AppDelegate中设置,在- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions方法中实现

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
	
[SDFlutterMethodChannelPlugin registerWithRegistrar:[(id)[SDWeakProxy proxyWithTarget:self] registrarForPlugin:@"SDFlutterMethodChannelPlugin"]];

return YES;
}
    

我们在iOS代码中实现MethodChanel,通过定时器NSTimer定时调用方法methodToFlutter将参数传递给Flutter端。通过在iOS端setMethodCallHandler根据方法methodTest处理接收来自flutter的参数,处理后并将结果返回给flutter。

四、小结

flutter开发实战-MethodChannel实现flutter与iOS双向通信。实现MethodChannel在flutter端与iOS端实现相互通信功能。

https://blog.csdn.net/gloryFlow/article/details/132240415

学习记录,每天不停进步。


http://lihuaxi.xjx100.cn/news/1436043.html

相关文章

CANdelaStudio 使用介绍

CANdela Studio使用_哔哩哔哩_bilibili 一.CANdelaStudio使用tips 1.开始菜单打开软件&#xff0c;避免软件字体是德文的 2.打开软件之后&#xff0c;用“Open”打开.cdd或者.cddt文件&#xff0c;不要双击文件打开&#xff0c;这样容易报错 3.查看软件版本信息 4.只有Admin版…

由于找不到msvcp100.dll无法继续执行代码怎么解决

当遇到程序无法正常运行&#xff0c;提示缺少msvcp100.dll文件时&#xff0c;最初的反应可能是困惑和不知所措。然而&#xff0c;通过修复msvcp100.dll文件&#xff0c;我发现这个问题实际上并不复杂&#xff0c;并且可以通过一些简单的步骤解决。 在修复msvcp100.dll文件的时候…

【Wamp】安装 | 局域网内设备访问

安装教程&#xff1a; https://wampserver.site/article/1.html 下载 https://www.wampserver.com/en/ 安装路径上不能有中文 安装好之后图标呈绿色 放入网页文件 将网页文件放置于wamp文件夹的www子文件夹 例如&#xff1a;\Wamp\program\www 修改http端口 WAMP服务器…

【Git】—— 标签管理

目录 &#xff08;一&#xff09;理解标签 1、作用 &#xff08;二&#xff09;创建标签 &#xff08;三&#xff09;操作标签 1、删除标签 2、推送标签 3、删除远程标签 &#xff08;一&#xff09;理解标签 标签 tag &#xff0c;可以简单的理解为是对某次 commit 的…

多用户一体化建设跨境电商小程序、app开发

跨境电商是指通过互联网技术&#xff0c;进行国际贸易的电子商务活动。随着跨境电商的快速发展&#xff0c;许多企业开始关注开发跨境电商小程序和app&#xff0c;以扩大其国际业务。下面是多用户一体化建设跨境电商小程序和app的开发步骤。 第一步&#xff1a;需求分析和规划…

八、复用(3)

本章概要 final 关键字 final 数据空白 finalfinal 参数final 方法final 和 privatefinal 类final 忠告 类初始化和加载 继承和初始化 final关键字 根据上下文环境&#xff0c;Java 的关键字 final 的含义有些微的不同&#xff0c;但通常它指的是“这是不能被改变的”。防止…

DC-DC拓扑

任何电子产品都离不开电源的设计&#xff0c;其中DCDC是使用频率最高的。 DCDC共分三种&#xff0c;降压电路&#xff0c;升压电路&#xff0c;升降压电路,常用的是前两种。 BUCK: 此拓扑结构几乎是所有DCDC降压电路的模型 原理分析&#xff1a; 1、开关管导通时&#xff0…

Jetson nano镜像备份

首先我们要做的准备工作有&#xff1a;含有镜像的 SD 卡、读卡器、安装了 ubuntu 环境的电脑。 备份步骤&#xff1a; 1、把含有镜像的卡用读卡器插到硬盘剩余空间大于 64G&#xff08;具体根据镜像大小使用&#xff09; 的 Ubuntu 电脑上&#xff0c;注意这里不能使用虚拟机…