Skip to content

Commit d73e6f1

Browse files
committed
test(ios): add test for event dispatcher and code clean
1 parent 17b5c35 commit d73e6f1

File tree

7 files changed

+179
-107
lines changed

7 files changed

+179
-107
lines changed

docs/development/native-event.md

+8-8
Original file line numberDiff line numberDiff line change
@@ -132,14 +132,14 @@ hippyEngine.sendEvent("rotate", hippyMap);
132132
终端在需要发送事件的地方调用代码:
133133

134134
```objectivec
135-
// 也可以参考HippyEventObserverModule.m
136-
[self sendEvent: @"rotate" params: @{@"foo":@"bar"}];
137-
- (void)sendEvent:(NSString *)eventName params:(NSDictionary *)params
138-
{
139-
HippyAssertParam(eventName);
140-
// 这里的"EventDispatcher"和"receiveNativeEvent"是常量,无需也不能更改
141-
[self.bridge.eventDispatcher dispatchEvent:@"EventDispatcher" methodName:@"receiveNativeEvent" args:@{@"eventName": eventName, @"extra": params ? : @{}}];
142-
}
135+
// 调用HippyBridge的如下实例方法,比如:
136+
[self.hippyBridge sendEvent:@"rotate" params:@{@"foo":@"bar"}];
137+
138+
/// Send native event to JS side
139+
/// - Parameters:
140+
/// - eventName: event name
141+
/// - params: event info
142+
- (void)sendEvent:(NSString *)eventName params:(NSDictionary *_Nullable)params;
143143
```
144144
145145
# Voltron

framework/ios/base/bridge/HippyBridge.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ HIPPY_EXTERN NSString *HippyBridgeModuleNameForClass(Class bridgeModuleClass);
298298
- (void)requestReload;
299299

300300

301-
#pragma mark -
301+
#pragma mark - JS Communication Related
302302

303303
/// Access the underlying JavaScript executor.
304304
/// You can use this in unit tests to detect when the executor has been invalidated,

framework/ios/base/bridge/HippyBridge.mm

+43-42
Original file line numberDiff line numberDiff line change
@@ -96,15 +96,23 @@
9696
NSString *const kHippyLaunchOptionsDebugModeKey = @"DebugMode";
9797
NSString *const kHippyLaunchOptionsEnableTurboKey = @"EnableTurbo";
9898

99-
// Global device info keys
100-
static NSString *const HippyNativeGlobalKeyOS = @"OS";
101-
static NSString *const HippyNativeGlobalKeyOSVersion = @"OSVersion";
102-
static NSString *const HippyNativeGlobalKeyDevice = @"Device";
103-
static NSString *const HippyNativeGlobalKeySDKVersion = @"SDKVersion";
104-
static NSString *const HippyNativeGlobalKeyAppVersion = @"AppVersion";
105-
static NSString *const HippyNativeGlobalKeyDimensions = @"Dimensions";
106-
static NSString *const HippyNativeGlobalKeyLocalization = @"Localization";
107-
static NSString *const HippyNativeGlobalKeyNightMode = @"NightMode";
99+
// Global device info keys & values
100+
static NSString *const kHippyNativeGlobalKeyOS = @"OS";
101+
static NSString *const kHippyNativeGlobalKeyOSVersion = @"OSVersion";
102+
static NSString *const kHippyNativeGlobalKeyDevice = @"Device";
103+
static NSString *const kHippyNativeGlobalKeySDKVersion = @"SDKVersion";
104+
static NSString *const kHippyNativeGlobalKeyAppVersion = @"AppVersion";
105+
static NSString *const kHippyNativeGlobalKeyDimensions = @"Dimensions";
106+
static NSString *const kHippyNativeGlobalKeyLocalization = @"Localization";
107+
static NSString *const kHippyNativeGlobalKeyNightMode = @"NightMode";
108+
static NSString *const kHippyNativeGlobalOSValue = @"ios";
109+
static NSString *const kHippyCFBundleShortVersionKey = @"CFBundleShortVersionString";
110+
111+
// Localization infos
112+
static NSString *const kHippyLocalizaitionCountryKey = @"country";
113+
static NSString *const kHippyLocalizaitionLanguageKey = @"language";
114+
static NSString *const kHippyLocalizaitionDirectionKey = @"direction";
115+
static NSString *const kHippyLocalizaitionValueUnknown = @"unknown";
108116

109117
// Key of module config info for js side
110118
static NSString *const kHippyRemoteModuleConfigKey = @"remoteModuleConfig";
@@ -657,7 +665,8 @@ - (id)callNativeModule:(NSUInteger)moduleID method:(NSUInteger)methodID params:(
657665
NSArray<HippyModuleData *> *moduleDataByID = [_moduleSetup moduleDataByID];
658666
if (moduleID >= [moduleDataByID count]) {
659667
if (isValid) {
660-
HippyLogError(@"moduleID %lu exceed range of moduleDataByID %lu, bridge is valid %ld", moduleID, [moduleDataByID count], (long)isValid);
668+
HippyLogError(@"moduleID %lu exceed range of moduleDataByID %lu, bridge is valid %ld",
669+
moduleID, [moduleDataByID count], (long)isValid);
661670
}
662671
return nil;
663672
}
@@ -668,23 +677,19 @@ - (id)callNativeModule:(NSUInteger)moduleID method:(NSUInteger)methodID params:(
668677
}
669678
return nil;
670679
}
671-
// not for UI Actions if NO==_valid
672-
if (!isValid) {
673-
if ([[moduleData name] isEqualToString:@"UIManager"]) {
674-
return nil;
675-
}
676-
}
677680
NSArray<id<HippyBridgeMethod>> *methods = [moduleData.methods copy];
678681
if (methodID >= [methods count]) {
679682
if (isValid) {
680-
HippyLogError(@"methodID %lu exceed range of moduleData.methods %lu, bridge is valid %ld", moduleID, [methods count], (long)isValid);
683+
HippyLogError(@"methodID %lu exceed range of moduleData.methods %lu, bridge is valid %ld",
684+
moduleID, [methods count], (long)isValid);
681685
}
682686
return nil;
683687
}
684688
id<HippyBridgeMethod> method = methods[methodID];
685689
if (HIPPY_DEBUG && !method) {
686690
if (isValid) {
687-
HippyLogError(@"Unknown methodID: %lu for module: %lu (%@)", (unsigned long)methodID, (unsigned long)moduleID, moduleData.name);
691+
HippyLogError(@"Unknown methodID: %lu for module: %lu (%@)",
692+
(unsigned long)methodID, (unsigned long)moduleID, moduleData.name);
688693
}
689694
return nil;
690695
}
@@ -713,7 +718,8 @@ - (id)callNativeModule:(NSUInteger)moduleID method:(NSUInteger)methodID params:(
713718
@throw exception;
714719
}
715720

716-
NSString *message = [NSString stringWithFormat:@"Exception '%@' was thrown while invoking %@ on target %@ with params %@", exception, method.JSMethodName, moduleData.name, params];
721+
NSString *message = [NSString stringWithFormat:@"Exception '%@' was thrown while invoking %@ on target %@ with params %@",
722+
exception, method.JSMethodName, moduleData.name, params];
717723
NSError *error = HippyErrorWithMessage(message);
718724
HippyBridgeFatal(error, self);
719725
return nil;
@@ -737,7 +743,8 @@ - (id)callNativeModuleName:(NSString *)moduleName methodName:(NSString *)methodN
737743
@throw exception;
738744
}
739745

740-
NSString *message = [NSString stringWithFormat:@"Exception '%@' was thrown while invoking %@ on target %@ with params %@", exception, method.JSMethodName, module.name, params];
746+
NSString *message = [NSString stringWithFormat:@"Exception '%@' was thrown while invoking %@ on target %@ with params %@",
747+
exception, method.JSMethodName, module.name, params];
741748
HippyBridgeFatal(HippyErrorWithMessage(message), self);
742749
return nil;
743750
}
@@ -842,30 +849,29 @@ - (NSDictionary *)genRawDeviceInfoDict {
842849
uname(&systemInfo);
843850
NSString *deviceModel = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
844851
NSMutableDictionary *deviceInfo = [NSMutableDictionary dictionary];
845-
[deviceInfo setValue:@"ios" forKey:HippyNativeGlobalKeyOS];
846-
[deviceInfo setValue:iosVersion forKey:HippyNativeGlobalKeyOSVersion];
847-
[deviceInfo setValue:deviceModel forKey:HippyNativeGlobalKeyDevice];
848-
[deviceInfo setValue:_HippySDKVersion forKey:HippyNativeGlobalKeySDKVersion];
849-
850-
NSString *appVer = [[NSBundle.mainBundle infoDictionary] objectForKey:@"CFBundleShortVersionString"];
852+
deviceInfo[kHippyNativeGlobalKeyOS] = kHippyNativeGlobalOSValue;
853+
deviceInfo[kHippyNativeGlobalKeyOSVersion] = iosVersion;
854+
deviceInfo[kHippyNativeGlobalKeyDevice] = deviceModel;
855+
deviceInfo[kHippyNativeGlobalKeySDKVersion] = _HippySDKVersion;
856+
NSString *appVer = [[NSBundle.mainBundle infoDictionary] objectForKey:kHippyCFBundleShortVersionKey];
851857
if (appVer) {
852-
[deviceInfo setValue:appVer forKey:HippyNativeGlobalKeyAppVersion];
858+
deviceInfo[kHippyNativeGlobalKeyAppVersion] = appVer;
853859
}
854860

855861
if (self.cachedDimensionsInfo) {
856-
[deviceInfo setValue:self.cachedDimensionsInfo forKey:HippyNativeGlobalKeyDimensions];
862+
deviceInfo[kHippyNativeGlobalKeyDimensions] = self.cachedDimensionsInfo;
857863
}
858864

859865
NSString *countryCode = [[HippyI18nUtils sharedInstance] currentCountryCode];
860866
NSString *lanCode = [[HippyI18nUtils sharedInstance] currentAppLanguageCode];
861867
NSWritingDirection direction = [[HippyI18nUtils sharedInstance] writingDirectionForCurrentAppLanguage];
862868
NSDictionary *localizaitionInfo = @{
863-
@"country" : countryCode?:@"unknown",
864-
@"language" : lanCode?:@"unknown",
865-
@"direction" : @(direction)
869+
kHippyLocalizaitionCountryKey : countryCode ?: kHippyLocalizaitionValueUnknown,
870+
kHippyLocalizaitionLanguageKey : lanCode ?: kHippyLocalizaitionValueUnknown,
871+
kHippyLocalizaitionDirectionKey : @(direction)
866872
};
867-
[deviceInfo setValue:localizaitionInfo forKey:HippyNativeGlobalKeyLocalization];
868-
[deviceInfo setValue:@([self isOSNightMode]) forKey:HippyNativeGlobalKeyNightMode];
873+
deviceInfo[kHippyNativeGlobalKeyLocalization] = localizaitionInfo;
874+
deviceInfo[kHippyNativeGlobalKeyNightMode] = @([self isOSNightMode]);
869875
return deviceInfo;
870876
}
871877

@@ -889,14 +895,11 @@ - (void)setOSNightMode:(BOOL)isOSNightMode withRootViewTag:(nonnull NSNumber *)r
889895
_isOSNightMode = isOSNightMode;
890896
// Notify to JS Driver Side
891897
// 1. Update global object
892-
[self.javaScriptExecutor updateNativeInfoToHippyGlobalObject:@{ HippyNativeGlobalKeyNightMode: @(isOSNightMode) }];
898+
[self.javaScriptExecutor updateNativeInfoToHippyGlobalObject:@{ kHippyNativeGlobalKeyNightMode: @(isOSNightMode) }];
893899

894900
// 2. Send event
895-
NSDictionary *args = @{@"eventName": hippyOnNightModeChangedEvent,
896-
@"extra": @{ hippyOnNightModeChangedParam1 : @(isOSNightMode),
897-
hippyOnNightModeChangedParam2 : rootViewTag } };
898-
[self.eventDispatcher dispatchEvent:@"EventDispatcher"
899-
methodName:@"receiveNativeEvent" args:args];
901+
[self sendEvent:hippyOnNightModeChangedEvent params:@{ hippyOnNightModeChangedParam1 : @(isOSNightMode),
902+
hippyOnNightModeChangedParam2 : rootViewTag }];
900903
}
901904

902905

@@ -946,9 +949,7 @@ - (void)setContextName:(NSString *)contextName {
946949
}
947950

948951
- (void)sendEvent:(NSString *)eventName params:(NSDictionary *_Nullable)params {
949-
[self.eventDispatcher dispatchEvent:@"EventDispatcher"
950-
methodName:@"receiveNativeEvent"
951-
args:@{@"eventName": eventName, @"extra": params ? : @{}}];
952+
[self.eventDispatcher dispatchNativeEvent:eventName withParams:params];
952953
}
953954

954955

framework/ios/base/modules/HippyEventDispatcher.h

+11-13
Original file line numberDiff line numberDiff line change
@@ -21,34 +21,32 @@
2121
*/
2222

2323
#import <UIKit/UIKit.h>
24-
2524
#import "HippyBridge.h"
2625

27-
/**
28-
* The threshold at which text inputs will start warning that the JS thread
29-
* has fallen behind (resulting in poor input performance, missed keys, etc.)
30-
*/
31-
HIPPY_EXTERN const NSInteger HippyTextUpdateLagWarningThreshold;
32-
33-
/**
34-
* Takes an input event name and normalizes it to the form that is required
35-
* by the events system (currently that means starting with the "top" prefix,
36-
* but that's an implementation detail that may change in future).
37-
*/
38-
HIPPY_EXTERN NSString *HippyNormalizeInputEventName(NSString *eventName);
26+
NS_ASSUME_NONNULL_BEGIN
3927

4028
/**
4129
* This class wraps the -[HippyBridge enqueueJSCall:args:] method, and
4230
* provides some convenience methods for generating event calls.
4331
*/
4432
@interface HippyEventDispatcher : NSObject <HippyBridgeModule>
4533

34+
/// Send event to JS side with given params.
4635
- (void)dispatchEvent:(NSString *)moduleName methodName:(NSString *)methodName args:(NSDictionary *)params;
4736

37+
/// Similar to the above `dispatchEvent` method, but designed to send Native events only.
38+
/// - Parameters:
39+
/// - eventName: name of event
40+
/// - params: event params
41+
- (void)dispatchNativeEvent:(NSString *)eventName withParams:(nullable NSDictionary *)params;
42+
4843
@end
4944

5045
@interface HippyBridge (HippyEventDispatcher)
5146

47+
/// A dispatcher responsible for sending event to js side.
5248
- (HippyEventDispatcher *)eventDispatcher;
5349

5450
@end
51+
52+
NS_ASSUME_NONNULL_END

framework/ios/base/modules/HippyEventDispatcher.mm

+44-27
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,19 @@
2525
#import "HippyUtils.h"
2626
#import "HippyBridge+ModuleManage.h"
2727

28-
const NSInteger HippyTextUpdateLagWarningThreshold = 3;
29-
30-
NSString *HippyNormalizeInputEventName(NSString *eventName) {
31-
if ([eventName hasPrefix:@"on"]) {
32-
eventName = [eventName stringByReplacingCharactersInRange:(NSRange) { 0, 2 } withString:@"top"];
33-
} else if (![eventName hasPrefix:@"top"]) {
34-
eventName = [[@"top" stringByAppendingString:[eventName substringToIndex:1].uppercaseString]
35-
stringByAppendingString:[eventName substringFromIndex:1]];
36-
}
37-
return eventName;
38-
}
28+
static NSString *const kHippyCallJSModuleKey = @"callJsModule";
29+
static NSString *const kHippyEventDispatcherModuleNameKey = @"moduleName";
30+
static NSString *const kHippyEventDispatcherMethodNameKey = @"methodName";
31+
static NSString *const kHippyEventDispatcherParamsKey = @"params";
32+
33+
static NSString *const kHippyEventDispatcherModule = @"EventDispatcher";
34+
static NSString *const kHippyReceiveNativeEventMethod = @"receiveNativeEvent";
35+
static NSString *const kHippyReceiveUIEventMethod = @"receiveUIComponentEvent";
36+
static NSString *const kHippyReceiveGestureEventMethod = @"receiveNativeGesture";
37+
static NSString *const kHippyEventNameKey = @"eventName";
38+
static NSString *const kHippyEventParamsKey = @"extra";
39+
static NSString *const kHippyEventIdKey = @"id";
40+
3941

4042
@implementation HippyEventDispatcher
4143

@@ -44,43 +46,58 @@ @implementation HippyEventDispatcher
4446
HIPPY_EXPORT_MODULE()
4547

4648
- (void)dispatchEvent:(NSString *)moduleName methodName:(NSString *)methodName args:(NSDictionary *)params {
47-
NSString *action = @"callJsModule";
4849
NSMutableArray *events = [NSMutableArray array];
49-
[events addObject:action];
50+
[events addObject:kHippyCallJSModuleKey];
5051

5152
NSMutableDictionary *body = [NSMutableDictionary new];
52-
[body setObject:moduleName forKey:@"moduleName"];
53-
[body setObject:methodName forKey:@"methodName"];
54-
55-
if ([moduleName isEqualToString:@"EventDispatcher"] && params) {
56-
NSNumber *tag = params[@"id"];
57-
NSString *eventName = params[@"eventName"] ?: @"";
58-
NSDictionary *extra = params[@"extra"] ?: @{};
59-
if ([methodName isEqualToString:@"receiveNativeEvent"]) {
53+
[body setObject:moduleName forKey:kHippyEventDispatcherModuleNameKey];
54+
[body setObject:methodName forKey:kHippyEventDispatcherMethodNameKey];
55+
56+
if ([moduleName isEqualToString:kHippyEventDispatcherModule] && params) {
57+
NSString *eventName = params[kHippyEventNameKey] ?: @"";
58+
NSDictionary *extra = params[kHippyEventParamsKey] ?: @{};
59+
if ([methodName isEqualToString:kHippyReceiveNativeEventMethod]) {
6060
NSMutableArray *detail = [NSMutableArray new];
6161
[detail addObject:eventName];
6262
[detail addObject:extra];
63-
[body setValue:detail forKey:@"params"];
64-
} else if ([methodName isEqualToString:@"receiveUIComponentEvent"]) {
63+
[body setValue:detail forKey:kHippyEventDispatcherParamsKey];
64+
} else if ([methodName isEqualToString:kHippyReceiveUIEventMethod]) {
65+
NSNumber *tag = params[kHippyEventIdKey];
6566
NSMutableArray *detail = [NSMutableArray new];
6667
if (tag) {
6768
[detail addObject:tag];
6869
}
6970
[detail addObject:eventName];
7071
[detail addObject:extra];
71-
[body setValue:detail forKey:@"params"];
72-
} else if ([methodName isEqualToString:@"receiveNativeGesture"]) {
73-
[body setValue:params forKey:@"params"];
72+
[body setValue:detail forKey:kHippyEventDispatcherParamsKey];
73+
} else if ([methodName isEqualToString:kHippyReceiveGestureEventMethod]) {
74+
[body setValue:params forKey:kHippyEventDispatcherParamsKey];
7475
}
7576
} else {
76-
[body setValue:params forKey:@"params"];
77+
[body setValue:params forKey:kHippyEventDispatcherParamsKey];
7778
}
7879

7980
[events addObject:body];
8081

8182
[_bridge enqueueJSCall:moduleName method:methodName args:events completion:NULL];
8283
}
8384

85+
- (void)dispatchNativeEvent:(NSString *)eventName withParams:(NSDictionary *)params {
86+
NSMutableDictionary *body = [NSMutableDictionary new];
87+
body[kHippyEventDispatcherModuleNameKey] = kHippyEventDispatcherModule;
88+
body[kHippyEventDispatcherMethodNameKey] = kHippyReceiveNativeEventMethod;
89+
body[kHippyEventDispatcherParamsKey] = @[ (eventName ?: @""), (params ?: @{}) ];
90+
91+
NSMutableArray *events = [NSMutableArray array];
92+
[events addObject:kHippyCallJSModuleKey];
93+
[events addObject:body];
94+
95+
[_bridge enqueueJSCall:kHippyEventDispatcherModule
96+
method:kHippyReceiveNativeEventMethod
97+
args:events
98+
completion:nil];
99+
}
100+
84101
- (dispatch_queue_t)methodQueue {
85102
return HippyJSThread;
86103
}

framework/ios/module/eventobserver/HippyEventObserverModule.mm

+6-16
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,11 @@ @implementation HippyEventObserverModule {
3232

3333
HIPPY_EXPORT_MODULE(EventObserver)
3434

35-
- (dispatch_queue_t)methodQueue
36-
{
35+
- (dispatch_queue_t)methodQueue {
3736
return dispatch_get_main_queue();
3837
}
3938

40-
- (instancetype)init
41-
{
39+
- (instancetype)init {
4240
if (self = [super init]) {
4341
_config = [NSMutableDictionary new];
4442
}
@@ -68,26 +66,18 @@ - (instancetype)init
6866
}
6967
}
7068

71-
- (void)addEventObserverForName:(__unused NSString *)eventName
72-
{
69+
- (void)addEventObserverForName:(__unused NSString *)eventName {
7370
// should override by subclass
7471
// do sth
7572
}
7673

77-
- (void)removeEventObserverForName:(__unused NSString *)eventName
78-
{
74+
- (void)removeEventObserverForName:(__unused NSString *)eventName {
7975
// should override by subclass
8076
// do sth
8177
}
8278

83-
- (void)dealloc
84-
{
85-
[[NSNotificationCenter defaultCenter] removeObserver: self];
86-
}
87-
88-
- (void)sendEvent:(NSString *)eventName params:(NSDictionary *)params
89-
{
79+
- (void)sendEvent:(NSString *)eventName params:(NSDictionary *)params {
9080
HippyAssertParam(eventName);
91-
[self.bridge.eventDispatcher dispatchEvent:@"EventDispatcher" methodName:@"receiveNativeEvent" args:@{@"eventName": eventName, @"extra": params ? : @{}}];
81+
[self.bridge.eventDispatcher dispatchNativeEvent:eventName withParams:params];
9282
}
9383
@end

0 commit comments

Comments
 (0)