From 792589182ea43ebd58ead27dfa65fa3f65443a36 Mon Sep 17 00:00:00 2001 From: Jidong Chen <jidongchen93@gmail.com> Date: Thu, 13 Jun 2019 20:17:54 +0800 Subject: [PATCH] broadcast 1,ios 2,dart --- ios/Classes/Boost/FlutterBoostPlugin.h | 9 +++ ios/Classes/Boost/FlutterBoostPlugin.m | 25 ++++++- .../Boost/FlutterBoostPlugin_private.h | 1 + .../handlers/NavigationService_closePage.mm | 7 ++ .../NavigationService_onFlutterPageResult.mm | 6 ++ ...vigationService_onShownContainerChanged.mm | 5 ++ .../handlers/NavigationService_openPage.mm | 6 ++ .../handlers/NavigationService_pageOnStart.mm | 6 ++ ios/Classes/Messaging/base/FLBBroadcastor.h | 32 +++++++++ ios/Classes/Messaging/base/FLBBroadcastor.m | 72 +++++++++++++++++++ .../Messaging/base/FLBMessageDispather.m | 3 +- .../Messaging/base/FLBMessageHandlerImp.m | 32 +++++---- ios/flutter_boost.podspec | 1 + lib/flutter_boost.dart | 9 ++- lib/messaging/base/broadcastor.dart | 66 +++++++++++++++++ 15 files changed, 264 insertions(+), 16 deletions(-) create mode 100644 ios/Classes/Messaging/base/FLBBroadcastor.h create mode 100644 ios/Classes/Messaging/base/FLBBroadcastor.m create mode 100644 lib/messaging/base/broadcastor.dart diff --git a/ios/Classes/Boost/FlutterBoostPlugin.h b/ios/Classes/Boost/FlutterBoostPlugin.h index 4654c66..9332a66 100755 --- a/ios/Classes/Boost/FlutterBoostPlugin.h +++ b/ios/Classes/Boost/FlutterBoostPlugin.h @@ -24,6 +24,7 @@ #import <Flutter/Flutter.h> #import "FLB2Platform.h" +#import "FLBBroadcastor.h" @interface FlutterBoostPlugin : NSObject<FlutterPlugin> @@ -38,6 +39,14 @@ - (BOOL)isRunning; - (FlutterViewController *)currentViewController; +#pragma mark - broadcast event to/from flutter +- (void)sendEvent:(NSString *)eventName + arguments:(NSDictionary *)arguments + result:(FlutterResult)result; + +- (FLBVoidCallback)addEventListener:(FLBEventListener)listner + forName:(NSString *)name; + #pragma mark - handing vc result. - (void)openPage:(NSString *)name params:(NSDictionary *)params diff --git a/ios/Classes/Boost/FlutterBoostPlugin.m b/ios/Classes/Boost/FlutterBoostPlugin.m index e4945f1..6afd976 100755 --- a/ios/Classes/Boost/FlutterBoostPlugin.m +++ b/ios/Classes/Boost/FlutterBoostPlugin.m @@ -47,14 +47,18 @@ methodChannelWithName:@"flutter_boost" binaryMessenger:[registrar messenger]]; FlutterBoostPlugin* instance = [self.class sharedInstance]; + [instance registerHandlers]; instance.methodChannel = channel; + instance.broadcastor = [[FLBBroadcastor alloc] initWithMethodChannel:channel]; [registrar addMethodCallDelegate:instance channel:channel]; } - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { if ([@"getPlatformVersion" isEqualToString:call.method]) { result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]); - } else { + } else if([@"__event__" isEqual: call.method]){ + [_broadcastor handleMethodCall:call result:result]; + }else{ FLBMessageImp *msg = FLBMessageImp.new; msg.name = call.method; msg.params = call.arguments; @@ -94,7 +98,7 @@ { if (self = [super init]) { _resultMediator = [FLBResultMediator new]; - [self registerHandlers]; + _dispatcher = FLBMessageDispather.new; } return self; @@ -172,4 +176,21 @@ [_resultMediator removeHandlerForKey:vcid]; } +#pragma mark - broadcast event to/from flutter +- (void)sendEvent:(NSString *)eventName + arguments:(NSDictionary *)arguments + result:(FlutterResult)result +{ + [_broadcastor sendEvent:eventName + arguments:arguments + result:result]; +} + +- (FLBVoidCallback)addEventListener:(FLBEventListener)listner + forName:(NSString *)name +{ + [_broadcastor addEventListener:listner + forName:name]; +} + @end diff --git a/ios/Classes/Boost/FlutterBoostPlugin_private.h b/ios/Classes/Boost/FlutterBoostPlugin_private.h index 8bdcd2c..5c2dbcc 100644 --- a/ios/Classes/Boost/FlutterBoostPlugin_private.h +++ b/ios/Classes/Boost/FlutterBoostPlugin_private.h @@ -38,6 +38,7 @@ - (id<FLBAbstractFactory>)factory; @property (nonatomic,strong) FlutterMethodChannel *methodChannel; +@property (nonatomic,strong) FLBBroadcastor *broadcastor; @property (nonatomic,copy) NSString *fPageId; @property (nonatomic,copy) NSString *fPagename; @property (nonatomic,strong) NSDictionary *fParams; diff --git a/ios/Classes/Messaging/Generated/NavigationService/handlers/NavigationService_closePage.mm b/ios/Classes/Messaging/Generated/NavigationService/handlers/NavigationService_closePage.mm index 902a28d..f39fba7 100755 --- a/ios/Classes/Messaging/Generated/NavigationService/handlers/NavigationService_closePage.mm +++ b/ios/Classes/Messaging/Generated/NavigationService/handlers/NavigationService_closePage.mm @@ -55,6 +55,7 @@ pageName:args[@"pageName"] params:args[@"params"] animated:args[@"animated"]]; + return YES; } - (NSString *)returnType @@ -62,4 +63,10 @@ return @"BOOL"; } +- (NSArray *)handledMessageNames +{ + return @[@"closePage"]; +} + + @end diff --git a/ios/Classes/Messaging/Generated/NavigationService/handlers/NavigationService_onFlutterPageResult.mm b/ios/Classes/Messaging/Generated/NavigationService/handlers/NavigationService_onFlutterPageResult.mm index efe729f..929ceb5 100755 --- a/ios/Classes/Messaging/Generated/NavigationService/handlers/NavigationService_onFlutterPageResult.mm +++ b/ios/Classes/Messaging/Generated/NavigationService/handlers/NavigationService_onFlutterPageResult.mm @@ -43,8 +43,14 @@ { NSDictionary *args = msg.params; [self onCall:result uniqueId:args[@"uniqueId"] key:args[@"key"] resultData:args[@"resultData"] params:args[@"params"]]; + return YES; } +- (NSArray *)handledMessageNames +{ + return @[@"onFlutterPageResult"]; +} + - (NSString *)returnType { return @"BOOL"; diff --git a/ios/Classes/Messaging/Generated/NavigationService/handlers/NavigationService_onShownContainerChanged.mm b/ios/Classes/Messaging/Generated/NavigationService/handlers/NavigationService_onShownContainerChanged.mm index 0a0d382..655cd60 100755 --- a/ios/Classes/Messaging/Generated/NavigationService/handlers/NavigationService_onShownContainerChanged.mm +++ b/ios/Classes/Messaging/Generated/NavigationService/handlers/NavigationService_onShownContainerChanged.mm @@ -42,12 +42,17 @@ { NSDictionary *args = msg.params; [self onCall:result newName:args[@"newName"] oldName:args[@"oldName"] params:args[@"params"]]; + return YES; } - (NSString *)returnType { return @"BOOL"; } +- (NSArray *)handledMessageNames +{ + return @[@"onShownContainerChanged"]; +} @end diff --git a/ios/Classes/Messaging/Generated/NavigationService/handlers/NavigationService_openPage.mm b/ios/Classes/Messaging/Generated/NavigationService/handlers/NavigationService_openPage.mm index 71d20b8..f8285f8 100755 --- a/ios/Classes/Messaging/Generated/NavigationService/handlers/NavigationService_openPage.mm +++ b/ios/Classes/Messaging/Generated/NavigationService/handlers/NavigationService_openPage.mm @@ -48,11 +48,17 @@ NSDictionary *args = msg.params; [self onCall:result pageName:args[@"pageName"] params:args[@"params"] animated:args[@"animated"]]; + return YES; } - (NSString *)returnType { return @"BOOL"; } + +- (NSArray *)handledMessageNames +{ + return @[@"openPage"]; +} @end diff --git a/ios/Classes/Messaging/Generated/NavigationService/handlers/NavigationService_pageOnStart.mm b/ios/Classes/Messaging/Generated/NavigationService/handlers/NavigationService_pageOnStart.mm index dc5d99e..5f5c0fc 100755 --- a/ios/Classes/Messaging/Generated/NavigationService/handlers/NavigationService_pageOnStart.mm +++ b/ios/Classes/Messaging/Generated/NavigationService/handlers/NavigationService_pageOnStart.mm @@ -45,6 +45,7 @@ { NSDictionary *args = msg.params; [self onCall:result params:args[@"params"]]; + return YES; } - (NSString *)returnType @@ -52,4 +53,9 @@ return @"NSDictionary *"; } +- (NSArray *)handledMessageNames +{ + return @[@"pageOnStart"]; +} + @end diff --git a/ios/Classes/Messaging/base/FLBBroadcastor.h b/ios/Classes/Messaging/base/FLBBroadcastor.h new file mode 100644 index 0000000..8848f3a --- /dev/null +++ b/ios/Classes/Messaging/base/FLBBroadcastor.h @@ -0,0 +1,32 @@ +// +// FLBBroadcastor.h +// flutter_boost +// +// Created by Jidong Chen on 2019/6/13. +// + +#import <Foundation/Foundation.h> +#import <Flutter/Flutter.h> + +NS_ASSUME_NONNULL_BEGIN + +typedef void (^FLBEventListener) (NSString *name , + NSDictionary *arguments); +typedef void (^FLBVoidCallback)(void); + +@interface FLBBroadcastor : NSObject + +- (instancetype)initWithMethodChannel:(FlutterMethodChannel *)channel; + +- (void)sendEvent:(NSString *)eventName + arguments:(NSDictionary *)arguments + result:(FlutterResult)result; + +- (FLBVoidCallback)addEventListener:(FLBEventListener)listner + forName:(NSString *)name; + +- (void)handleMethodCall:(FlutterMethodCall *)call + result:(FlutterResult)result; +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/Classes/Messaging/base/FLBBroadcastor.m b/ios/Classes/Messaging/base/FLBBroadcastor.m new file mode 100644 index 0000000..de7ec6b --- /dev/null +++ b/ios/Classes/Messaging/base/FLBBroadcastor.m @@ -0,0 +1,72 @@ +// +// FLBBroadcastor.m +// flutter_boost +// +// Created by Jidong Chen on 2019/6/13. +// + +#import "FLBBroadcastor.h" + +@interface FLBBroadcastor() +@property (nonatomic,strong) FlutterMethodChannel *channel; +@property (nonatomic,strong) NSMutableDictionary *lists; + +@end + +@implementation FLBBroadcastor + +- (instancetype)initWithMethodChannel:(FlutterMethodChannel *)channel +{ + if (self = [super init]) { + _channel = channel; + _lists = NSMutableDictionary.new; + } + return self; +} + +- (void)sendEvent:(NSString *)eventName + arguments:(NSDictionary *)arguments + result:(void (^)(id _Nonnull))result +{ + if(!eventName) return; + NSMutableDictionary *msg = NSMutableDictionary.new; + msg[@"name"] = eventName; + msg[@"arguments"] = arguments; + [_channel invokeMethod:@"__event__" + arguments:msg + result:result]; +} + +- (FLBVoidCallback)addEventListener:(FLBEventListener)listner + forName:(NSString *)name +{ + if(!name || !listner) return ^{}; + + NSMutableArray *list = _lists[name]; + if(!list){ + list = NSMutableArray.new; + _lists[name] = list; + } + [list addObject:listner]; + return ^{ + [list removeObject:listner]; + }; +} + +- (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result +{ + if([call.method isEqual:@"__event__"]){ + NSString *name = call.arguments[@"name"]; + NSDictionary *arguments = call.arguments[@"arguments"]; + if(name){ + NSMutableArray *list = _lists[name]; + if(list){ + for(FLBEventListener l in list){ + l(name,arguments); + } + } + } + } +} + +@end diff --git a/ios/Classes/Messaging/base/FLBMessageDispather.m b/ios/Classes/Messaging/base/FLBMessageDispather.m index 5f22ea6..e9398b9 100755 --- a/ios/Classes/Messaging/base/FLBMessageDispather.m +++ b/ios/Classes/Messaging/base/FLBMessageDispather.m @@ -44,7 +44,8 @@ { if (msg) { id<FLBMessageHandler> handler = _handlerMap[msg.name]; - return [handler handle:msg result:result]; + [handler handle:msg result:result]; + return handler != nil; }else{ return NO; } diff --git a/ios/Classes/Messaging/base/FLBMessageHandlerImp.m b/ios/Classes/Messaging/base/FLBMessageHandlerImp.m index 3cd06ef..4f85bd1 100755 --- a/ios/Classes/Messaging/base/FLBMessageHandlerImp.m +++ b/ios/Classes/Messaging/base/FLBMessageHandlerImp.m @@ -22,6 +22,7 @@ * THE SOFTWARE. */ #import "FLBMessageHandlerImp.h" +#import "FLBMessageImp.h" typedef void (^SendResult)(NSObject *result); @@ -76,21 +77,28 @@ typedef void (^SendResult)(NSObject *result); #pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-performSelector-leaks" SEL method = @selector(call:result:); - if (_callHandlers[NSStringFromSelector(method)]) { - return; - } + - __weak typeof(self) weakSelf = self; - _callHandlers[NSStringFromSelector(method)] = ^(NSDictionary *args,SendResult result){ - id resultBlock = [weakSelf getHandlerBlockForType:weakSelf.returnType result:result]; - if (resultBlock && result) { - [weakSelf performSelector:method withObject:args withObject:resultBlock]; - }else{ + for(NSString *name in self.handledMessageNames){ + if (_callHandlers[name]) { + continue; + } + __weak typeof(self) weakSelf = self; + _callHandlers[name] = ^(NSDictionary *args,SendResult result){ + id resultBlock = [weakSelf getHandlerBlockForType:weakSelf.returnType result:result]; + if (resultBlock && result) { + FLBMessageImp *msg = FLBMessageImp.new; + msg.name = name; + msg.params = args; + [weakSelf performSelector:method withObject:msg withObject:resultBlock]; + }else{ #if DEBUG - [NSException raise:@"invalid call" format:@"missing handler and result!"]; + [NSException raise:@"invalid call" format:@"missing handler and result!"]; #endif - } - }; + } + }; + } + #pragma clang diagnostic pop } diff --git a/ios/flutter_boost.podspec b/ios/flutter_boost.podspec index 3975ae2..64fd2ac 100755 --- a/ios/flutter_boost.podspec +++ b/ios/flutter_boost.podspec @@ -21,6 +21,7 @@ A new Flutter plugin make flutter better to use! 'Classes/Boost/FLB2Platform.h', 'Classes/Boost/FLBFlutterContainer.h', 'Classes/Boost/FLBFlutterAppDelegate.h', + 'Classes/Boost/FLBBroadcastor.h', 'Classes/1.0/FLBFlutterViewContainer.h', 'Classes/1.5/FLB2FlutterViewContainer.h' diff --git a/lib/flutter_boost.dart b/lib/flutter_boost.dart index 4985291..a313903 100755 --- a/lib/flutter_boost.dart +++ b/lib/flutter_boost.dart @@ -39,6 +39,7 @@ import 'messaging/handlers/on_native_page_result_handler.dart'; import 'messaging/handlers/will_dealloc_page_container_handler.dart'; import 'messaging/handlers/will_show_page_container_handler.dart'; import 'messaging/handlers/will_disappear_page_container_handler.dart'; +import 'messaging/base/broadcastor.dart'; import 'observers_holders.dart'; export 'container/boost_container.dart'; @@ -64,6 +65,7 @@ class FlutterBoost { final MethodChannel _methodChannel = MethodChannel('flutter_boost'); final MessageDispatcher _dispatcher = MessageDispatcher(); + final Broadcastor _broadcastor = Broadcastor(_methodChannel); FlutterBoost() { _router.resultMediator = _resultMediator; @@ -78,7 +80,12 @@ class FlutterBoost { _dispatcher.registerHandler(WillShowPageContainerHandler()); _dispatcher.registerHandler(WillDisappearPageContainerHandler()); _methodChannel.setMethodCallHandler((MethodCall call){ - _dispatcher.dispatch(call); + if(call.method == "__event__"){ + //Handler broadcast event. + return _broadcastor.handleCall(call); + }else{ + return _dispatcher.dispatch(call); + } }); } diff --git a/lib/messaging/base/broadcastor.dart b/lib/messaging/base/broadcastor.dart new file mode 100644 index 0000000..c3d3dd0 --- /dev/null +++ b/lib/messaging/base/broadcastor.dart @@ -0,0 +1,66 @@ + + +import 'package:flutter/services.dart'; + +typedef void VoidCallback(); +typedef Future<dynamic> EventListener(String name , Map arguments); + +class Broadcastor{ + + MethodChannel _channel; + Map<String,List<EventListener>> _lists = Map(); + + Broadcastor(MethodChannel channel){ + _channel = channel; + } + + void sendEvent(String name , Map arguments){ + + if(name == null) { + return; + } + + if(arguments == null){ + arguments = Map(); + } + + Map msg = Map(); + msg["name"] = name; + msg["arguments"] = arguments; + _channel.invokeMethod("__event__",msg); + } + + VoidCallback addEventListener(String name , EventListener listener){ + if(name == null || listener == null){ + return (){}; + } + + List<EventListener> list = _lists[name]; + if(list == null){ + list = List(); + _lists[name] = list; + } + + list.add(listener); + + return (){ + list.remove(listener); + }; + } + + Future<dynamic> handleCall(MethodCall call){ + if(!_lists.containsKey(call.method) || call.method != "__event__"){ + return Future<dynamic>(); + } + + String name = call.arguments["name"]; + String arg = call.arguments["arguments"]; + List<EventListener> list = _lists[call.method]; + for(EventListener l in list){ + l(name,arg); + } + + return Future<dynamic>(); + } + +} \ No newline at end of file -- 2.26.2