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

2023-11-16

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
使用代码如下

  @override
  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();
  }

  @override
  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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

flutter开发实战-MethodChannel实现flutter与iOS双向通信 的相关文章

  • 在FLUTTER/DART中,为什么我们有时在声明变量时要在“String”后面加一个问号?

    在演示应用程序中 我们找到一个实例 最终字符串 标题 gt 为什么要加这个 在 String 类型之后 class MyHomePage extends StatefulWidget MyHomePage Key key this titl
  • 苹果企业程序分发问题[关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 这个问题涉及到Apple iOS 开发者企业计划 http developer apple com programs ios enterprise 我
  • UIWebView Bug:-[UIWebView cut:]:无法识别的选择器发送到实例

    In the UIWebView 如果包含文本的输入元素具有焦点 并且按下按钮导致输入失去焦点 则随后双击输入以重新获得焦点并从出现的弹出栏中选择 剪切 或 复制 或 粘贴 会导致这UIWebView因错误而崩溃 UIWebView cut
  • 如何反转 CGPath 的点顺序

    我想画一个圆圈 并用它打出字母 为此 我需要顺时针抚摸圆圈 逆时针抚摸字母 这一切都很好 但是当我使用 Core Text 获取字母路径时 我不知道如何从本质上反转该路径 不是镜像或旋转或任何东西 这很简单 我希望点笔画顺序是逆时针的 这实
  • 使用基于约束的布局自动调整 NSTokenField 的大小

    有没有办法自动调整大小height使用约束的 NSTokenField 保持宽度恒定 sizeToFit应该有效 但事实并非如此 如果我设置一个约束来保持宽度不变并调用此方法 它将忽略约束并仅调整宽度大小 当我想要的是仅调整高度大小时 基于
  • ui 测试 xcode,如何使用 cellquery 点击表视图单元格按钮

    我目前正在为我的应用程序进行 ui 测试 并一直点击我的应用程序的登录按钮 我无法找到我提供了标识符注册按钮的元素 该元素是索引中的第三个 这不是问题 let cellQuery self app tables cells element
  • 在 swrevealcontroller 之前实现登录屏幕

    我刚刚开始学习 IOS 开发 我已经按照给定的在线教程成功实现了 SWRevealViewController 一切都按预期工作 然后 我决定添加一个登录屏幕 这将是应用程序运行时用户看到的第一个页面 我采取的步骤如下 将 UIViewCo
  • IOS7 状态栏在选定控制器上隐藏/显示

    我想在某些控制器上显示和隐藏状态栏 这可以完成吗 或者它更像是一个整体应用程序设置 我看过很多关于 plist 更新的帖子 问题 View controller based status bar appearance NO 如果这完成了 那
  • 在 Xcode 5.1 中构建时,“您必须提供 5.5 英寸 Retina 显示屏的屏幕截图,因为您的应用程序二进制文件支持 5.5 英寸 Retina 显示屏”

    我更新了一个旧应用程序并修复了一些小错误 该应用程序是使用 Xcode 5 1 编译的 无法使用资产目录或添加 iPhone 6 和 6 Plus 图像 但当我尝试提交它进行审查时 我仍然收到此错误 您必须提供 4 7 英寸 Retina
  • 检索 iPhone 中的 Outlook 联系人

    我想通过应用程序导入所有 Outlook 联系人 有什么办法可以做到这一点吗 请告诉我 您可以通过实施 Microsoft Exchange 服务器协议来实现此目的 微软MSDN http msdn microsoft com en us
  • 径向渐变绘制性能 - OpenGL-ES 可以改进吗?

    我正在开发一个图像处理应用程序 它将径向渐变叠加在从照片库加载的图像上 在屏幕上 我有一个滑块可以动态地增大 减小径向渐变的半径 我发现模拟器上的性能很好 但在 iPhone 3G 或 3GS 上就很糟糕了much移动滑块时重绘速度较慢 我
  • 获取对 iOS 应用程序中最顶层视图/窗口的引用

    我正在创建一个可重用的框架 用于在 iOS 应用程序中显示通知 我希望将通知视图添加到应用程序中其他所有内容的顶部 有点像 UIAlertView 当我初始化监听 NSNotification 事件并添加视图作为响应的管理器时 我需要获取对
  • 如何使用MKMapView完成加载委托,可能的“完成显示”委托?

    当用户在选择注释后点击 保存 时 我尝试保存地图视图的缩略图 当用户尚未放大该注释时会出现问题 因此尚未加载关闭缩放级别 这就是用户点击保存后我正在做的事情 将布尔值 saving 设置为 true 居中并放大注释 无动画 当调用mapVi
  • 使用 iPhone 摄像头检测心率 [重复]

    这个问题在这里已经有答案了 可能的重复 使用摄像头检测心率 https stackoverflow com questions 9274027 detecting heart rate using the camera 我正在研究 iOS
  • CBPeripheral 名称有时为 null

    我正在开发一个应用程序来与蓝牙 LE 外围设备进行通信 我目前正在测试的外围设备是其中之一these http www ti com tool cc2540dk mini 有趣的是 有时当我发现它时 我会得到它的正确名称 SimpleBLE
  • 如何在 UICollectionView 的节标题中动态添加标签和按钮?

    请帮助我如何水平添加标签和水平添加类似的按钮 但每个按钮应像另一个部分一样在每个标签的下方对齐 这应该在 UICollectionView 的标题中动态发生 因为标签和按钮的数量根据我的数据 我想制作一种 Excel 类型的布局 并在标题中
  • 防止UIScrollView的UIPanGestureRecognizer遮挡UIScreenEdgePanGestureRecognizer

    我有一个UIScrollView它填满了我应用程序的一页上的屏幕 但我希望允许用户从屏幕边缘平移以显示其后面的视图 问题是 UIScrollView 窃取了我的触摸UIScreenEdgePanGestureRecognizer在屏幕边缘
  • 使用 NSURLSessionDataTask 显示文件下载进度

    我想显示特定文件的文件下载进度 收到了多少字节 它与 NSURLSessionDownloadTask 配合得很好 我的问题是我想用 NSURLSessionDataTask 实现同样的效果 以下是将文件接收到 NSData 并写入文档文件
  • 在 Flutter 中显示 iOS 的 PDF 内联文件

    我正在 flutter 中专门为 iOS 开发一个应用程序 现阶段 我需要向其中添加 PDF 文件 问题是 flutter 没有原生的方式来显示 PDF 文件 据我研究 由此tread https github com flutter fl
  • GMSMapView 中的倒多边形

    我必须在我的 iPhone 项目中使用 Google 地图 并且我正在使用 GMSPolygon 来绘制多边形 但是如何填充地图上除多边形内部之外的所有位置 就像下图一样 谢谢 我玩过你的问题 主要思想是用多边形填充整个地球 然后为您的特定

随机推荐

  • Qwt使用总结,初步整理

    最近研究了一些Qwt 至此总结Qwt的认识以便以后的备忘 从什么方面开始说起呢 从这个类是什么 可以用来做什么 关于Qwt的简介就不说了 主要说说其中用到的几个类吧 QwtPlot 是一个2D画图控件 Widget 继承于QFram和Qwt
  • Mybatis Plus 3.1.0枚举类处理器重写TypeHandler

    我的环境 Springboot 2 13 Mybatis Plus 3 1 Oracle 11g 驱动版本oracle6 1 我尝试用 Mybatis Plus 3 1 以上版本 如 3 2 3 3 时 oracle6 驱动无法适配 2 枚
  • JAVA线程的中断

    每个线程都有一个boolean类型的标志来表明线程是否发生了中断 并且包含了中断相关的函数 interrupt 用于设置线程的中断状态为true isInterrupted 用于返回线程的中断状态 interrupted 方法用于清除中断状
  • cast函数_QT槽函数获取信号发送对象

    Qt 在槽函数中获取信号发送对象 Qt中提供了一个函数 qobject cast QObject object 可以通过这个函数判断信号发出对象 Qt 帮助文档的解释 Returns the given object cast to typ
  • 通讯录(C语言)

    结合指针 结构体 枚举 实现增删改查 test c 用于测试主函数 contact h 用于函数的声明 contact c 用于函数的实现 test c 主要思路 用do while 实现基本分支结构 并用枚举类型 规定出选择以增加代码可读
  • yarn创建vue项目报错解决

    1 使用yarn create vue创建项目时报如下错误 2 原因是由于安装包目录和bin目录不在统一磁盘下 查看方法 查看bin目录 yarn global bin 查看安装包目录 yarn global dir 3 解决 1 将yar
  • 代码审计工具之Fortify安装以及初步使用

    目录 1 Fortify Fortify工具介绍 1 Fortify Fortify工具介绍 Fortify SCA 是一个静态的 白盒的软件源代码安全测试工具 它通过内置的五大主要分析引擎 数据流 语义 结构 控制流 配置流等对应用软件的
  • 【Transformer】9、CrossFormer:A versatile vision transformer based on cross-scale attention

    文章目录 一 背景 二 动机 三 方法 3 1 Cross scale Embedding Layer CEL 3 2 Cross former Block 3 2 1 Long Short Distance Attention LSDA
  • 解决RuntimeError: CUDA unknown error - this may be due to an incorrectly set up environment

    RuntimeError CUDA unknown error this may be due to an incorrectly set up environment e g changing env variable CUDA VISI
  • IDEA代码规范插件(CheckStyle插件、alibaba插件)

    IDEA代码规范插件 CheckStyle插件 alibaba插件 代码规范插件 CheckStyle插件 alibaba插件 代码规范插件 CheckStyle插件 1 安装 打开idea的file settings plugins 再搜
  • 关于 微软商店无法加载页面 显示错误代码0x80131500的解决办法

    目录 一 误删系统文件导致Microsoft Store无法打开 1 运行 SFC 和 DISM 2 尝试修复或者重置微软应用商店 3 重新部署 Microsoft Store 4 运行Windows疑难解答 5 对系统镜像进行无损修复 二
  • 渗透测试——提权方式总结

    内容整理自网络 一 什么是提权 提权就是通过各种办法和漏洞 提高自己在服务器中的权限 以便控制全局 Windows User gt gt System Linux User gt gt Root 二 怎样进行提权 提权的方式有哪些 1 系统
  • AI算法工程师面试题基础精选

    AI算法工程师的相关面试题包括机器学习 深度学习以及强化学习等等 在面试时由于涉及范围比较广泛 一般面试官不会问一些比较深比较偏的问题 一般都会结合你经手的项目或者在校期间的项目进行一些算法的基础问题进行提问 在这里我们对在面试中常见中的基
  • 分享CSS3里box-shadow属性的使用方法,包括内阴影box-shadow:inset

    一 box shadow语法 box shadow none inset 可选值 不设置 为外投影 设置 为内投影 x offset 阴影水平偏移量 正方向为right y offset 阴影垂直偏移量 正方向为bottom blur ra
  • 记录好项目D16

    记录好项目 你好呀 这里是我专门记录一下从某些地方收集起来的项目 对项目修改 进行添砖加瓦 变成自己的闪亮项目 修修补补也可以成为毕设哦 本次的项目是个电影购票系统 一 系统介绍 前台 普通用户注册 登录 注销 用户信息修改 邮箱 密码 头
  • Qt编译时,出现 first defined here,原因及解决方法

    场景 今天想着把之前写过的模块 都整合到一起 结果一编译程序就出现这个错误 原因 因为头文件出现重复包含了 后来我想了一下 我每个模块都是独立编写的 怎么会重复呢 然后去了pro文件里看了一下 里面果然有两个一模一样的头文件名 QT诚不欺我
  • Newtonsoft.Json基本使用

    Newtonsoft Json基本使用 使用强类型进行序列化反序列化 准备一个学生类 public class Student public string Name get set public int Age get set public
  • Android系统启动流程

    文章目录 总结 1 rc脚本语法规则 2 init进程启动 init first stage init second stage 3 ServiceManager启动 4 Zygote进程启动 5 Launcher启动 总结 android
  • [sql]使用sql语句增加列,并且设置默认值

    有的时候 我们需要对已存在的表进行插入列的情况 当然 可以使用navicat等工具直接可视化操作 命令行的话 如下 alter table 表名 add column 列名 数据类型 default 默认值 demo alter table
  • flutter开发实战-MethodChannel实现flutter与iOS双向通信

    flutter开发实战 MethodChannel实现flutter与iOS双向通信 最近开发中需要iOS与flutter实现通信 这里使用的MethodChannel 如果需要flutter与Android实现双向通信 请看 https