flutter与native之间可以通过Platform Channels 通信方式
MethodChanel
:用于传递方法调用(method invocation)用来调用native中方法EventChannel
:用于数据流(event streams)的通信。BasicMessageChannel
:用于传递字符串和半结构化的信息
flutter与native直接的交互方式和h5与native交互方式比较相似,下面通过PIO搜索插件封装说明下flutter与iOS交互。
PIO搜索插件
文件目录
AMapFlutterSearchPlugin
:编写OC调用高德地图搜索方法,处理PIO搜索结果处理AMapFlutterStreamManager
:数据流单例,用于传递PIO搜索结果AMapFlutterSearchRegistran
:注册搜索插件amap_search_util.dart
:高德搜索Flutter插件入口类
iOS端编码
AppDelegate
:在appDelegate中注册插件
[AMapFlutterSearchRegistran registerWithRegistry:self];
AMapFlutterSearchRegistran
:调用flutter插件注册方法,registerWithRegistrar:
+ (void)registerWithRegistry:(NSObject<FlutterPluginRegistry> *)registy {
[AMapFlutterSearchPlugin registerWithRegistrar:[registy registrarForPlugin:@"AMapFlutterSearchPlugin"]];
}
AMapFlutterSearchPlugin
高德PIO搜索插件
- 实现
FlutterPlugin
代理方法,注册MethodChanel
的keyamap_flutter_search
,注册EventChannel
的keyamap_flutter_search_stream
。
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar {
FlutterMethodChannel *channel = [FlutterMethodChannel methodChannelWithName:@"amap_flutter_search" binaryMessenger:[registrar messenger]];
AMapFlutterSearchPlugin *instance = [[AMapFlutterSearchPlugin alloc] init];
[registrar addMethodCallDelegate:instance channel:channel];
FlutterEventChannel *eventChanel = [FlutterEventChannel eventChannelWithName:@"amap_flutter_search_stream" binaryMessenger:[registrar messenger]];
[eventChanel setStreamHandler:[[AMapFlutterStreamManager sharedInstance] streamHandler]];
}
// 响应flutter调用Native方法
- (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result {
if ([@"AMapInputTipsSearch" isEqualToString:call.method]) {
[self searchTipsWithKey:call.arguments];
}
}
searchTipsWithKey
:编写iOS调用高德搜索接口
- (void)searchTipsWithKey:(NSDictionary *)searchDict {
NSString *keywords = [searchDict objectForKey:@"keywords"];
if (keywords.length == 0) {
return;
}
AMapInputTipsSearchRequest *tips = [[AMapInputTipsSearchRequest alloc] init];
tips.keywords = keywords;
[self.searchAPI AMapInputTipsSearch:tips];
}
onInputTipsSearchDone
:搜索结果代理方法,返回搜索结果
- (void)onInputTipsSearchDone:(AMapInputTipsSearchRequest *)request response:(AMapInputTipsSearchResponse *)response {
// Stream传递给flutter
[self handleAMapSearchResult:response.tips];
}
handleAMapSearchResult
:处理搜索结果,通过StreamManager
进行数据传递
- (**void**)handleAMapSearchResult:(NSArray<AMapTip *> *)tips {
NSMutableArray *array = [NSMutableArray array];
[tips enumerateObjectsUsingBlock:^(AMapTip * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:obj.name.length > 0 ? obj.name : @"" forKey:@"name"];
[dict setObject:obj.address.length > 0 ? obj.address : @"" forKey:@"address"];
[dict setObject:[NSString stringWithFormat:@"%f",obj.location.latitude] forKey:@"latitude"];
[dict setObject:[NSString stringWithFormat:@"%f",obj.location.longitude] forKey:@"longitude"];
[array addObject:dict];
}];
NSDictionary *resultDict = @{
@"results" : array
};
[[AMapFlutterStreamManager sharedInstance] streamHandler].eventSink(resultDict);
}
Flutter编码---AMapFlutterSearch
高德搜索Flutter插件入口类
- 注册
MethodChannel
和EventChannel
,注册的key需要与iOS使用的key保持一致。
static const MethodChannel _methodChannel = const MethodChannel(_CHANNEL_METHOD_SEARCH);
static const EventChannel _eventChannel = const EventChannel(_CHANNEL_STREAM_SEARCH);
Stream<Map<String, Object>> _onSearchResults
:监听数据流。
static Stream<Map<String, Object>> _onSearchResults = _eventChannel
.receiveBroadcastStream()
.asBroadcastStream()
.map<Map<String, Object>>((element) => element.cast<String, Object>());
StreamController<Map<String, Object>>? _receiveStream;
Stream<Map<String, Object>> onSearchResults() {
if (_receiveStream == null) {
_receiveStream = StreamController();
_subscription = _onSearchResults.listen((Map<String, Object> event) {
Map<String, Object> newEvent = Map<String, Object>.of(event);
_receiveStream?.add(newEvent);
});
}
return _receiveStream!.stream;
}
- 调用Native搜索方法: key值需要与Native中保持一致
void searchTipsWithKey(Map<String, dynamic> searchDict) {
_methodChannel.invokeMethod('AMapInputTipsSearch', searchDict);
}