Browse Source

V2 static navigation events (#2577)

* adresses #1078
yogevbd 7 years ago
parent
commit
e10e811c46
No account linked to committer's email address

+ 38
- 11
lib/ios/RNNCommandsHandler.m View File

@@ -64,13 +64,19 @@
64 64
 	[self assertReady];
65 65
 	
66 66
 	UIViewController<RNNRootViewProtocol> *newVc = [_controllerFactory createLayoutAndSaveToStore:layout];
67
-	[_navigationStackManager push:newVc onTop:componentId completion:completion];
67
+	[_navigationStackManager push:newVc onTop:componentId completion:^{
68
+		[_controllerFactory.eventEmitter sendNavigationEvent:[RNNNavigationEvent create:kPush fromComponent:componentId toComponent:newVc.componentId]];
69
+		completion();
70
+	}];
68 71
 }
69 72
 
70 73
 -(void)pop:(NSString*)componentId options:(NSDictionary*)options completion:(RNNTransitionCompletionBlock)completion {
71 74
 	[self assertReady];
72 75
 	[CATransaction begin];
73
-	[CATransaction setCompletionBlock:completion];
76
+	[CATransaction setCompletionBlock:^{
77
+		[_controllerFactory.eventEmitter sendNavigationEvent:[RNNNavigationEvent create:kPop fromComponent:nil toComponent:componentId]];
78
+		completion();
79
+	}];
74 80
 	NSDictionary* animationData = options[@"customTransition"];
75 81
 	if (animationData){
76 82
 		if ([animationData objectForKey:@"animations"]) {
@@ -87,7 +93,10 @@
87 93
 -(void) popTo:(NSString*)componentId completion:(RNNTransitionCompletionBlock)completion {
88 94
 	[self assertReady];
89 95
 	[CATransaction begin];
90
-	[CATransaction setCompletionBlock:completion];
96
+	[CATransaction setCompletionBlock:^{
97
+		[_controllerFactory.eventEmitter sendNavigationEvent:[RNNNavigationEvent create:kPopTo fromComponent:nil toComponent:componentId]];
98
+		completion();
99
+	}];
91 100
 	
92 101
 	[_navigationStackManager popTo:componentId];
93 102
 	
@@ -97,7 +106,10 @@
97 106
 -(void) popToRoot:(NSString*)componentId completion:(RNNTransitionCompletionBlock)completion {
98 107
 	[self assertReady];
99 108
 	[CATransaction begin];
100
-	[CATransaction setCompletionBlock:completion];
109
+	[CATransaction setCompletionBlock:^{
110
+		[_controllerFactory.eventEmitter sendNavigationEvent:[RNNNavigationEvent create:kPopToRoot fromComponent:componentId toComponent:nil]];
111
+		completion();
112
+	}];
101 113
 	
102 114
 	[_navigationStackManager popToRoot:componentId];
103 115
 	
@@ -107,14 +119,20 @@
107 119
 -(void) showModal:(NSDictionary*)layout completion:(RNNTransitionCompletionBlock)completion {
108 120
 	[self assertReady];
109 121
 	
110
-	UIViewController *newVc = [_controllerFactory createLayoutAndSaveToStore:layout];
111
-	[_modalManager showModal:newVc completion:completion];
122
+	UIViewController<RNNRootViewProtocol> *newVc = [_controllerFactory createLayoutAndSaveToStore:layout];
123
+	[_modalManager showModal:newVc completion:^{
124
+		[_controllerFactory.eventEmitter sendNavigationEvent:[RNNNavigationEvent create:kShowModal fromComponent:nil toComponent:newVc.componentId]];
125
+		completion();
126
+	}];
112 127
 }
113 128
 
114 129
 -(void) dismissModal:(NSString*)componentId completion:(RNNTransitionCompletionBlock)completion {
115 130
 	[self assertReady];
116 131
 	[CATransaction begin];
117
-	[CATransaction setCompletionBlock:completion];
132
+	[CATransaction setCompletionBlock:^{
133
+		[_controllerFactory.eventEmitter sendNavigationEvent:[RNNNavigationEvent create:kDismissModal fromComponent:componentId toComponent:nil]];
134
+		completion();
135
+	}];
118 136
 	
119 137
 	[_modalManager dismissModal:componentId];
120 138
 	
@@ -124,7 +142,10 @@
124 142
 -(void) dismissAllModalsWithCompletion:(RNNTransitionCompletionBlock)completion {
125 143
 	[self assertReady];
126 144
 	[CATransaction begin];
127
-	[CATransaction setCompletionBlock:completion];
145
+	[CATransaction setCompletionBlock:^{
146
+		[_controllerFactory.eventEmitter sendNavigationEvent:[RNNNavigationEvent create:kDismissAllModals fromComponent:nil toComponent:nil]];
147
+		completion();
148
+	}];
128 149
 	
129 150
 	[_modalManager dismissAllModals];
130 151
 	
@@ -133,13 +154,19 @@
133 154
 
134 155
 -(void)showOverlay:(NSDictionary *)layout completion:(RNNTransitionCompletionBlock)completion {
135 156
 	[self assertReady];
136
-	UIViewController* overlayVC = [_controllerFactory createOverlay:layout];
137
-	[_overlayManager showOverlay:overlayVC completion:completion];
157
+	UIViewController<RNNRootViewProtocol>* overlayVC = [_controllerFactory createOverlay:layout];
158
+	[_overlayManager showOverlay:overlayVC completion:^{
159
+		[_controllerFactory.eventEmitter sendNavigationEvent:[RNNNavigationEvent create:kShowOverlay fromComponent:nil toComponent:overlayVC.componentId]];
160
+		completion();
161
+	}];
138 162
 }
139 163
 
140 164
 - (void)dismissOverlay:(NSString*)componentId completion:(RNNTransitionCompletionBlock)completion {
141 165
 	[self assertReady];
142
-	[_overlayManager dismissOverlay:componentId completion:completion];
166
+	[_overlayManager dismissOverlay:componentId completion:^{	
167
+		[_controllerFactory.eventEmitter sendNavigationEvent:[RNNNavigationEvent create:kDismissOverlay fromComponent:componentId toComponent:nil]];
168
+		completion();
169
+	}];
143 170
 }
144 171
 
145 172
 #pragma mark - private

+ 15
- 0
lib/ios/RNNComponentLifecycleEvent.h View File

@@ -0,0 +1,15 @@
1
+#import "RNNNavigationEvent.h"
2
+
3
+#define kDidAppear         @"didAppear"
4
+#define kDidDisappear      @"didDisappear"
5
+#define kWillUnmount       @"willUnmount"
6
+#define kDidMount         @"didMount"
7
+typedef NSString*               LifecycleEvent;
8
+
9
+@interface RNNComponentLifecycleEvent : NSObject
10
+
11
++ (instancetype)create:(LifecycleEvent)event componentName:(NSString*)componentName componentId:(NSString*)componentId;
12
+
13
+- (NSDictionary*)body;
14
+
15
+@end

+ 24
- 0
lib/ios/RNNComponentLifecycleEvent.m View File

@@ -0,0 +1,24 @@
1
+#import "RNNComponentLifecycleEvent.h"
2
+
3
+@interface RNNComponentLifecycleEvent()
4
+@property (nonatomic, strong) NSString* componentName;
5
+@property (nonatomic, strong) NSString* componentId;
6
+@property (nonatomic, strong) LifecycleEvent event;
7
+
8
+@end
9
+
10
+@implementation RNNComponentLifecycleEvent
11
+
12
++ (instancetype)create:(LifecycleEvent)event componentName:(NSString *)componentName componentId:(NSString *)componentId {
13
+	RNNComponentLifecycleEvent* lifecycleEvent = [[RNNComponentLifecycleEvent alloc] init];
14
+	lifecycleEvent.componentName = componentName;
15
+	lifecycleEvent.componentId = componentId;
16
+	lifecycleEvent.event = event;
17
+	return lifecycleEvent;
18
+}
19
+
20
+- (NSDictionary *)body {
21
+	return @{@"event": self.event, @"componentName": self.componentName, @"componentId": self.componentId};
22
+}
23
+
24
+@end

+ 2
- 2
lib/ios/RNNControllerFactory.h View File

@@ -15,9 +15,9 @@
15 15
 
16 16
 -(UIViewController<RNNRootViewProtocol> *)createLayoutAndSaveToStore:(NSDictionary*)layout;
17 17
 
18
--(UIViewController *)createOverlay:(NSDictionary*)layout;
18
+- (UIViewController<RNNRootViewProtocol> *)createOverlay:(NSDictionary*)layout;
19 19
 
20 20
 @property (nonatomic, strong) RNNNavigationOptions* defaultOptions;
21
-
21
+@property (nonatomic, strong) RNNEventEmitter *eventEmitter;
22 22
 
23 23
 @end

+ 2
- 3
lib/ios/RNNControllerFactory.m View File

@@ -12,7 +12,6 @@
12 12
 @implementation RNNControllerFactory {
13 13
 	id<RNNRootViewCreator> _creator;
14 14
 	RNNStore *_store;
15
-	RNNEventEmitter *_eventEmitter;
16 15
 	RCTBridge *_bridge;
17 16
 }
18 17
 
@@ -162,8 +161,8 @@
162 161
 	return sideMenuChild;
163 162
 }
164 163
 
165
-- (UIViewController *)createOverlay:(NSDictionary*)layout {
166
-	UIViewController *vc = [self fromTree:layout];
164
+- (UIViewController<RNNRootViewProtocol> *)createOverlay:(NSDictionary*)layout {
165
+	UIViewController<RNNRootViewProtocol> *vc = [self fromTree:layout];
167 166
 	RCTRootView* rootView = (RCTRootView*)vc.view;
168 167
 	rootView.backgroundColor = [UIColor clearColor];
169 168
 	CGSize availableSize = UIApplication.sharedApplication.delegate.window.bounds.size;

+ 7
- 0
lib/ios/RNNEventEmitter.h View File

@@ -4,6 +4,9 @@
4 4
 #import <React/RCTEventEmitter.h>
5 5
 #import <React/RCTBridgeModule.h>
6 6
 
7
+#import "RNNNavigationEvent.h"
8
+#import "RNNComponentLifecycleEvent.h"
9
+
7 10
 @interface RNNEventEmitter : RCTEventEmitter <RCTBridgeModule>
8 11
 
9 12
 -(void)sendOnAppLaunched;
@@ -14,4 +17,8 @@
14 17
 
15 18
 -(void)sendOnNavigationButtonPressed:(NSString*)componentId buttonId:(NSString*)buttonId;
16 19
 
20
+-(void)sendNavigationEvent:(RNNNavigationEvent*)navigationEvent;
21
+
22
+-(void)sendLifecycleEvent:(RNNComponentLifecycleEvent *)navigationEvent;
23
+
17 24
 @end

+ 11
- 1
lib/ios/RNNEventEmitter.m View File

@@ -11,9 +11,11 @@ static NSString* const onAppLaunched	= @"RNN.appLaunched";
11 11
 static NSString* const componentDidAppear	= @"RNN.componentDidAppear";
12 12
 static NSString* const componentDidDisappear	= @"RNN.componentDidDisappear";
13 13
 static NSString* const onNavigationButtonPressed	= @"RNN.navigationButtonPressed";
14
+static NSString* const navigationCommands	= @"RNN.navigationCommands";
15
+static NSString* const componentLifecycle	= @"RNN.componentLifecycle";
14 16
 
15 17
 -(NSArray<NSString *> *)supportedEvents {
16
-	return @[onAppLaunched, componentDidAppear, componentDidDisappear, onNavigationButtonPressed];
18
+	return @[onAppLaunched, componentDidAppear, componentDidDisappear, onNavigationButtonPressed, navigationCommands, componentLifecycle];
17 19
 }
18 20
 
19 21
 # pragma mark public
@@ -26,6 +28,14 @@ static NSString* const onNavigationButtonPressed	= @"RNN.navigationButtonPressed
26 28
 	}
27 29
 }
28 30
 
31
+-(void)sendNavigationEvent:(RNNNavigationEvent *)navigationEvent {
32
+	[self send:navigationCommands body:navigationEvent.body];
33
+}
34
+
35
+-(void)sendLifecycleEvent:(RNNComponentLifecycleEvent *)navigationEvent {
36
+	[self send:componentLifecycle body:navigationEvent.body];
37
+}
38
+
29 39
 -(void)sendComponentDidAppear:(NSString *)componentId {
30 40
 	[self send:componentDidAppear body:componentId];
31 41
 }

+ 4
- 0
lib/ios/RNNNavigationController.m View File

@@ -11,4 +11,8 @@
11 11
 	return NO;
12 12
 }
13 13
 
14
+- (NSString *)componentId {
15
+	return ((UIViewController<RNNRootViewProtocol>*)self.topViewController).componentId;
16
+}
17
+
14 18
 @end

+ 20
- 0
lib/ios/RNNNavigationEvent.h View File

@@ -0,0 +1,20 @@
1
+#import <Foundation/Foundation.h>
2
+
3
+#define kPush              @"push"
4
+#define kPop               @"pop"
5
+#define kPopTo             @"popTo"
6
+#define kPopToRoot         @"popToRoot"
7
+#define kShowModal         @"showModal"
8
+#define kDismissModal      @"dismissModal"
9
+#define kDismissAllModals  @"dismissAllModals"
10
+#define kShowOverlay       @"showOverlay"
11
+#define kDismissOverlay    @"dismissOverlay"
12
+typedef NSString*               NavigationCommand;
13
+
14
+@interface RNNNavigationEvent : NSObject
15
+
16
+@property (nonatomic, strong) NSDictionary* body;
17
+
18
++ (instancetype)create:(NavigationCommand)commandType fromComponent:(NSString *)fromComponentId toComponent:(NSString *)toComponentId;
19
+
20
+@end

+ 26
- 0
lib/ios/RNNNavigationEvent.m View File

@@ -0,0 +1,26 @@
1
+#import "RNNNavigationEvent.h"
2
+
3
+@interface RNNNavigationEvent ()
4
+	@property (nonatomic, strong) NavigationCommand command;
5
+	@property (nonatomic, strong) NSString* toComponentId;
6
+	@property (nonatomic, strong) NSString* fromComponentId;
7
+@end
8
+
9
+@implementation RNNNavigationEvent
10
+
11
++ (instancetype)create:(NavigationCommand)commandType fromComponent:(NSString *)fromComponentId toComponent:(NSString *)toComponentId {
12
+	RNNNavigationEvent* navigationCommand = [[RNNNavigationEvent alloc] init];
13
+	navigationCommand.command = commandType;
14
+	navigationCommand.fromComponentId = fromComponentId;
15
+	navigationCommand.toComponentId = toComponentId;
16
+	return navigationCommand;
17
+}
18
+
19
+- (NSDictionary *)body {
20
+	NSMutableDictionary* mutableParams = [NSMutableDictionary new];
21
+	self.fromComponentId ? [mutableParams setObject:self.fromComponentId forKey:@"fromComponentId"] : nil;
22
+	self.toComponentId ? [mutableParams setObject:self.toComponentId forKey:@"toComponentId"] : nil;
23
+	return @{@"commandName": self.command, @"params": mutableParams};
24
+}
25
+
26
+@end

+ 22
- 10
lib/ios/RNNRootViewController.m View File

@@ -38,12 +38,34 @@
38 38
 -(void)viewWillAppear:(BOOL)animated{
39 39
 	[super viewWillAppear:animated];
40 40
 	[self.options applyOn:self];
41
+	[self sendLifecycleEvent:kDidMount];
42
+}
43
+
44
+-(void)viewDidAppear:(BOOL)animated {
45
+	[super viewDidAppear:animated];
46
+	[self.eventEmitter sendComponentDidAppear:self.componentId];
47
+	[self sendLifecycleEvent:kDidAppear];
48
+}
49
+
50
+- (void)viewWillDisappear:(BOOL)animated {
51
+	[super viewWillDisappear:animated];
52
+	[self sendLifecycleEvent:kWillUnmount];
53
+}
54
+
55
+-(void)viewDidDisappear:(BOOL)animated {
56
+	[super viewDidDisappear:animated];
57
+	[self.eventEmitter sendComponentDidDisappear:self.componentId];
58
+	[self sendLifecycleEvent:kDidDisappear];
41 59
 }
42 60
 
43 61
 - (void)viewDidLoad {
44 62
 	[super viewDidLoad];
45 63
 }
46 64
 
65
+- (void)sendLifecycleEvent:(LifecycleEvent)event {
66
+	[self.eventEmitter sendLifecycleEvent:[RNNComponentLifecycleEvent create:event componentName:self.componentName componentId:self.componentId]];
67
+}
68
+
47 69
 -(BOOL)isCustomTransitioned {
48 70
 	return self.animator != nil;
49 71
 }
@@ -69,16 +91,6 @@
69 91
 	return NO;
70 92
 }
71 93
 
72
--(void)viewDidAppear:(BOOL)animated {
73
-	[super viewDidAppear:animated];
74
-	[self.eventEmitter sendComponentDidAppear:self.componentId];
75
-}
76
-
77
--(void)viewDidDisappear:(BOOL)animated {
78
-	[super viewDidDisappear:animated];
79
-	[self.eventEmitter sendComponentDidDisappear:self.componentId];
80
-}
81
-
82 94
 - (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
83 95
 	RNNRootViewController* vc =  (RNNRootViewController*)viewController;
84 96
 	if (![vc.options.backButtonTransition isEqualToString:@"custom"]){

+ 1
- 0
lib/ios/RNNRootViewProtocol.h View File

@@ -5,6 +5,7 @@
5 5
 @required
6 6
 
7 7
 - (BOOL)isCustomTransitioned;
8
+- (NSString *)componentId;
8 9
 
9 10
 @end
10 11
 

+ 6
- 2
lib/ios/RNNSideMenuChildVC.m View File

@@ -11,13 +11,13 @@
11 11
 @interface RNNSideMenuChildVC ()
12 12
 
13 13
 @property (readwrite) RNNSideMenuChildType type;
14
-@property (readwrite) UIViewController *child;
14
+@property (readwrite) UIViewController<RNNRootViewProtocol> *child;
15 15
 
16 16
 @end
17 17
 
18 18
 @implementation RNNSideMenuChildVC
19 19
 
20
--(instancetype) initWithChild:(UIViewController*)child type:(RNNSideMenuChildType)type {
20
+-(instancetype) initWithChild:(UIViewController<RNNRootViewProtocol>*)child type:(RNNSideMenuChildType)type {
21 21
 	self = [super init];
22 22
 	
23 23
 	self.child = child;
@@ -37,4 +37,8 @@
37 37
 	return NO;
38 38
 }
39 39
 
40
+- (NSString *)componentId {
41
+	return _child.componentId;
42
+}
43
+
40 44
 @end

+ 4
- 0
lib/ios/RNNSideMenuController.m View File

@@ -76,4 +76,8 @@
76 76
 	return NO;
77 77
 }
78 78
 
79
+- (NSString *)componentId {
80
+	return _center.componentId;
81
+}
82
+
79 83
 @end

+ 4
- 0
lib/ios/RNNTabBarController.m View File

@@ -37,4 +37,8 @@
37 37
 	return NO;
38 38
 }
39 39
 
40
+- (NSString *)componentId {
41
+	return ((UIViewController<RNNRootViewProtocol>*)self.selectedViewController).componentId;
42
+}
43
+
40 44
 @end

+ 6
- 2
lib/ios/RNNTopTabsViewController.m View File

@@ -5,7 +5,7 @@
5 5
 
6 6
 @interface RNNTopTabsViewController () {
7 7
 	NSArray* _viewControllers;
8
-	UIViewController* _currentViewController;
8
+	UIViewController<RNNRootViewProtocol>* _currentViewController;
9 9
 	RNNSegmentedControl* _segmentedControl;
10 10
 }
11 11
 
@@ -47,7 +47,7 @@
47 47
 }
48 48
 
49 49
 - (void)setSelectedViewControllerIndex:(NSUInteger)index {
50
-	UIViewController *toVC = _viewControllers[index];
50
+	UIViewController<RNNRootViewProtocol> *toVC = _viewControllers[index];
51 51
 	[_contentView addSubview:toVC.view];
52 52
 	[_currentViewController.view removeFromSuperview];
53 53
 	_currentViewController = toVC;
@@ -76,4 +76,8 @@
76 76
 	return NO;
77 77
 }
78 78
 
79
+- (NSString *)componentId {
80
+	return _currentViewController.componentId;
81
+}
82
+
79 83
 @end

+ 16
- 0
lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj View File

@@ -61,6 +61,10 @@
61 61
 		2DCD9196200014A900EDC75D /* RNNBridgeManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DCD9194200014A900EDC75D /* RNNBridgeManager.m */; };
62 62
 		390AD477200F499D00A8250D /* RNNSwizzles.h in Headers */ = {isa = PBXBuildFile; fileRef = 390AD475200F499D00A8250D /* RNNSwizzles.h */; };
63 63
 		390AD478200F499D00A8250D /* RNNSwizzles.m in Sources */ = {isa = PBXBuildFile; fileRef = 390AD476200F499D00A8250D /* RNNSwizzles.m */; };
64
+		5032774E2015E86D00ECD75D /* RNNNavigationEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 5032774C2015E86D00ECD75D /* RNNNavigationEvent.h */; };
65
+		5032774F2015E86D00ECD75D /* RNNNavigationEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = 5032774D2015E86D00ECD75D /* RNNNavigationEvent.m */; };
66
+		503277602016302900ECD75D /* RNNComponentLifecycleEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 5032775E2016302900ECD75D /* RNNComponentLifecycleEvent.h */; };
67
+		503277612016302900ECD75D /* RNNComponentLifecycleEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = 5032775F2016302900ECD75D /* RNNComponentLifecycleEvent.m */; };
64 68
 		504AFE641FFE53070076E904 /* RNNOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 504AFE621FFE53070076E904 /* RNNOptions.h */; };
65 69
 		504AFE651FFE53070076E904 /* RNNOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 504AFE631FFE53070076E904 /* RNNOptions.m */; };
66 70
 		504AFE741FFFF0540076E904 /* RNNTopTabsOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 504AFE721FFFF0540076E904 /* RNNTopTabsOptions.h */; };
@@ -232,6 +236,10 @@
232 236
 		2DCD9194200014A900EDC75D /* RNNBridgeManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNBridgeManager.m; sourceTree = "<group>"; };
233 237
 		390AD475200F499D00A8250D /* RNNSwizzles.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNSwizzles.h; sourceTree = "<group>"; };
234 238
 		390AD476200F499D00A8250D /* RNNSwizzles.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNSwizzles.m; sourceTree = "<group>"; };
239
+		5032774C2015E86D00ECD75D /* RNNNavigationEvent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNNavigationEvent.h; sourceTree = "<group>"; };
240
+		5032774D2015E86D00ECD75D /* RNNNavigationEvent.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNNavigationEvent.m; sourceTree = "<group>"; };
241
+		5032775E2016302900ECD75D /* RNNComponentLifecycleEvent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNComponentLifecycleEvent.h; sourceTree = "<group>"; };
242
+		5032775F2016302900ECD75D /* RNNComponentLifecycleEvent.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNComponentLifecycleEvent.m; sourceTree = "<group>"; };
235 243
 		504AFE621FFE53070076E904 /* RNNOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNOptions.h; sourceTree = "<group>"; };
236 244
 		504AFE631FFE53070076E904 /* RNNOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNOptions.m; sourceTree = "<group>"; };
237 245
 		504AFE721FFFF0540076E904 /* RNNTopTabsOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNTopTabsOptions.h; sourceTree = "<group>"; };
@@ -494,6 +502,10 @@
494 502
 				E8AEDB461F58414D000F5A6A /* Animations */,
495 503
 				504AFE611FFE52EF0076E904 /* Options */,
496 504
 				50D031312005146C00386B3D /* Managers */,
505
+				5032774C2015E86D00ECD75D /* RNNNavigationEvent.h */,
506
+				5032774D2015E86D00ECD75D /* RNNNavigationEvent.m */,
507
+				5032775E2016302900ECD75D /* RNNComponentLifecycleEvent.h */,
508
+				5032775F2016302900ECD75D /* RNNComponentLifecycleEvent.m */,
497 509
 				26916C941E4B9CCC00D13680 /* RNNRootViewCreator.h */,
498 510
 				26916C961E4B9E7700D13680 /* RNNReactRootViewCreator.h */,
499 511
 				26916C971E4B9E7700D13680 /* RNNReactRootViewCreator.m */,
@@ -671,6 +683,7 @@
671 683
 				507F43F41FF4FCFE00D9425B /* HMSegmentedControl.h in Headers */,
672 684
 				50A00C37200F84D6000F01A6 /* RNNOverlayOptions.h in Headers */,
673 685
 				7B4928081E70415400555040 /* RNNCommandsHandler.h in Headers */,
686
+				5032774E2015E86D00ECD75D /* RNNNavigationEvent.h in Headers */,
674 687
 				263905AE1E4C6F440023D7D3 /* MMDrawerBarButtonItem.h in Headers */,
675 688
 				50F5DFC11F407A8C001A00BC /* RNNTabBarController.h in Headers */,
676 689
 				50CB3B691FDE911400AA153B /* RNNSideMenuOptions.h in Headers */,
@@ -685,6 +698,7 @@
685 698
 				263905C01E4C6F440023D7D3 /* SidebarAirbnbAnimation.h in Headers */,
686 699
 				E8367B801F7A8A4700675C05 /* VICMAImageView.h in Headers */,
687 700
 				263905E61E4CAC950023D7D3 /* RNNSideMenuChildVC.h in Headers */,
701
+				503277602016302900ECD75D /* RNNComponentLifecycleEvent.h in Headers */,
688 702
 				263905C41E4C6F440023D7D3 /* SidebarFacebookAnimation.h in Headers */,
689 703
 				50F5DFC51F407AA0001A00BC /* RNNNavigationController.h in Headers */,
690 704
 				21B85E5F1F44482A00B314B5 /* RNNNavigationButtons.h in Headers */,
@@ -861,6 +875,8 @@
861 875
 				263905C11E4C6F440023D7D3 /* SidebarAirbnbAnimation.m in Sources */,
862 876
 				263905D71E4C94970023D7D3 /* RNNSideMenuController.m in Sources */,
863 877
 				507F43CA1FF4F9CC00D9425B /* RNNTopTabOptions.m in Sources */,
878
+				503277612016302900ECD75D /* RNNComponentLifecycleEvent.m in Sources */,
879
+				5032774F2015E86D00ECD75D /* RNNNavigationEvent.m in Sources */,
864 880
 				26916C991E4B9E7700D13680 /* RNNReactRootViewCreator.m in Sources */,
865 881
 				214545251F4DC125006E8DA1 /* RNNUIBarButtonItem.m in Sources */,
866 882
 				263905B81E4C6F440023D7D3 /* UIViewController+MMDrawerController.m in Sources */,

+ 8
- 0
lib/src/adapters/NativeEventsReceiver.js View File

@@ -17,6 +17,14 @@ class NativeEventsReceiver {
17 17
     this.emitter.addListener('RNN.appLaunched', callback);
18 18
   }
19 19
 
20
+  registerNavigationCommands(callback) {
21
+    this.emitter.addListener('RNN.navigationCommands', callback);
22
+  }
23
+
24
+  registerComponentLifecycle(callback) {
25
+    this.emitter.addListener('RNN.componentLifecycle', callback);
26
+  }
27
+
20 28
   registerNavigationButtonPressed(callback) {
21 29
     this.emitter.addListener('RNN.navigationButtonPressed', callback);
22 30
   }

+ 8
- 0
lib/src/events/PublicEventsRegistry.js View File

@@ -6,6 +6,14 @@ class PublicEventsRegistry {
6 6
   onAppLaunched(callback) {
7 7
     this.nativeEventsReceiver.registerAppLaunched(callback);
8 8
   }
9
+
10
+  navigationCommands(callback) {
11
+    this.nativeEventsReceiver.registerNavigationCommands(callback);
12
+  }
13
+
14
+  componentLifecycle(callback) {
15
+    this.nativeEventsReceiver.registerComponentLifecycle(callback);
16
+  }
9 17
 }
10 18
 
11 19
 module.exports = PublicEventsRegistry;

+ 14
- 0
lib/src/events/PublicEventsRegistry.test.js View File

@@ -16,4 +16,18 @@ describe('PublicEventsRegistry', () => {
16 16
     expect(nativeEventsReceiver.registerAppLaunched).toHaveBeenCalledTimes(1);
17 17
     expect(nativeEventsReceiver.registerAppLaunched).toHaveBeenCalledWith(cb);
18 18
   });
19
+
20
+  it('exposes navigationCommands events', () => {
21
+    const cb = jest.fn();
22
+    uut.navigationCommands(cb);
23
+    expect(nativeEventsReceiver.registerNavigationCommands).toHaveBeenCalledTimes(1);
24
+    expect(nativeEventsReceiver.registerNavigationCommands).toHaveBeenCalledWith(cb);
25
+  });
26
+
27
+  it('exposes componentLifecycle events', () => {
28
+    const cb = jest.fn();
29
+    uut.componentLifecycle(cb);
30
+    expect(nativeEventsReceiver.registerComponentLifecycle).toHaveBeenCalledTimes(1);
31
+    expect(nativeEventsReceiver.registerComponentLifecycle).toHaveBeenCalledWith(cb);
32
+  });
19 33
 });