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 initStatesuper.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 disposesuper.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
學習記錄,每天不停進步。