Browse Source

setRoot on main application window - fix setRoot on iPad

yogevbd 6 years ago
parent
commit
a3922f8481

+ 1
- 1
lib/ios/RNNBridgeManager.m View File

76
 	id<RNNRootViewCreator> rootViewCreator = [[RNNReactRootViewCreator alloc] initWithBridge:bridge];
76
 	id<RNNRootViewCreator> rootViewCreator = [[RNNReactRootViewCreator alloc] initWithBridge:bridge];
77
 	RNNControllerFactory *controllerFactory = [[RNNControllerFactory alloc] initWithRootViewCreator:rootViewCreator eventEmitter:eventEmitter andBridge:bridge];
77
 	RNNControllerFactory *controllerFactory = [[RNNControllerFactory alloc] initWithRootViewCreator:rootViewCreator eventEmitter:eventEmitter andBridge:bridge];
78
 	
78
 	
79
-	_commandsHandler = [[RNNCommandsHandler alloc] initWithStore:_store controllerFactory:controllerFactory eventEmitter:eventEmitter stackManager:[RNNNavigationStackManager new] modalManager:[RNNModalManager new] overlayManager:[RNNOverlayManager new]];
79
+	_commandsHandler = [[RNNCommandsHandler alloc] initWithStore:_store controllerFactory:controllerFactory eventEmitter:eventEmitter stackManager:[RNNNavigationStackManager new] modalManager:[RNNModalManager new] overlayManager:[RNNOverlayManager new] mainWindow:[UIApplication sharedApplication].keyWindow];
80
 	RNNBridgeModule *bridgeModule = [[RNNBridgeModule alloc] initWithCommandsHandler:_commandsHandler];
80
 	RNNBridgeModule *bridgeModule = [[RNNBridgeModule alloc] initWithCommandsHandler:_commandsHandler];
81
 
81
 
82
 	return [@[bridgeModule,eventEmitter] arrayByAddingObjectsFromArray:[self extraModulesFromDelegate]];
82
 	return [@[bridgeModule,eventEmitter] arrayByAddingObjectsFromArray:[self extraModulesFromDelegate]];

+ 1
- 1
lib/ios/RNNCommandsHandler.h View File

9
 
9
 
10
 @interface RNNCommandsHandler : NSObject
10
 @interface RNNCommandsHandler : NSObject
11
 
11
 
12
-- (instancetype)initWithStore:(RNNStore*)store controllerFactory:(RNNControllerFactory*)controllerFactory eventEmitter:(RNNEventEmitter *)eventEmitter stackManager:(RNNNavigationStackManager *)stackManager modalManager:(RNNModalManager *)modalManager overlayManager:(RNNOverlayManager *)overlayManager;
12
+- (instancetype)initWithStore:(RNNStore*)store controllerFactory:(RNNControllerFactory*)controllerFactory eventEmitter:(RNNEventEmitter *)eventEmitter stackManager:(RNNNavigationStackManager *)stackManager modalManager:(RNNModalManager *)modalManager overlayManager:(RNNOverlayManager *)overlayManager mainWindow:(UIWindow *)mainWindow;
13
 
13
 
14
 - (void)setRoot:(NSDictionary*)layout completion:(RNNTransitionCompletionBlock)completion;
14
 - (void)setRoot:(NSDictionary*)layout completion:(RNNTransitionCompletionBlock)completion;
15
 
15
 

+ 10
- 8
lib/ios/RNNCommandsHandler.m View File

34
 	RNNOverlayManager* _overlayManager;
34
 	RNNOverlayManager* _overlayManager;
35
 	RNNNavigationStackManager* _stackManager;
35
 	RNNNavigationStackManager* _stackManager;
36
 	RNNEventEmitter* _eventEmitter;
36
 	RNNEventEmitter* _eventEmitter;
37
+	UIWindow* _mainWindow;
37
 }
38
 }
38
 
39
 
39
-- (instancetype)initWithStore:(RNNStore*)store controllerFactory:(RNNControllerFactory*)controllerFactory eventEmitter:(RNNEventEmitter *)eventEmitter stackManager:(RNNNavigationStackManager *)stackManager modalManager:(RNNModalManager *)modalManager overlayManager:(RNNOverlayManager *)overlayManager {
40
+- (instancetype)initWithStore:(RNNStore*)store controllerFactory:(RNNControllerFactory*)controllerFactory eventEmitter:(RNNEventEmitter *)eventEmitter stackManager:(RNNNavigationStackManager *)stackManager modalManager:(RNNModalManager *)modalManager overlayManager:(RNNOverlayManager *)overlayManager mainWindow:(UIWindow *)mainWindow {
40
 	self = [super init];
41
 	self = [super init];
41
 	_store = store;
42
 	_store = store;
42
 	_controllerFactory = controllerFactory;
43
 	_controllerFactory = controllerFactory;
45
 	_modalManager.delegate = self;
46
 	_modalManager.delegate = self;
46
 	_stackManager = stackManager;
47
 	_stackManager = stackManager;
47
 	_overlayManager = overlayManager;
48
 	_overlayManager = overlayManager;
49
+	_mainWindow = mainWindow;
48
 	return self;
50
 	return self;
49
 }
51
 }
50
 
52
 
54
 	[self assertReady];
56
 	[self assertReady];
55
 	
57
 	
56
 	[_modalManager dismissAllModalsAnimated:NO];
58
 	[_modalManager dismissAllModalsAnimated:NO];
57
-	[_store removeAllComponentsFromWindow:UIApplication.sharedApplication.delegate.window];
59
+	[_store removeAllComponentsFromWindow:_mainWindow];
58
 	
60
 	
59
 	UIViewController *vc = [_controllerFactory createLayout:layout[@"root"] saveToStore:_store];
61
 	UIViewController *vc = [_controllerFactory createLayout:layout[@"root"] saveToStore:_store];
60
 	
62
 	
61
-	[UIApplication sharedApplication].windows.firstObject.rootViewController = vc;
62
-
63
+	_mainWindow.rootViewController = vc;
64
+	
63
 	[_eventEmitter sendOnNavigationCommandCompletion:setRoot params:@{@"layout": layout}];
65
 	[_eventEmitter sendOnNavigationCommandCompletion:setRoot params:@{@"layout": layout}];
64
 	completion();
66
 	completion();
65
 }
67
 }
75
 		
77
 		
76
 		[vc overrideOptions:newOptions];
78
 		[vc overrideOptions:newOptions];
77
 		[vc mergeOptions:newOptions];
79
 		[vc mergeOptions:newOptions];
78
-
80
+		
79
 		[CATransaction commit];
81
 		[CATransaction commit];
80
 	}
82
 	}
81
 }
83
 }
103
 		if([vc isKindOfClass:[RNNRootViewController class]]) {
105
 		if([vc isKindOfClass:[RNNRootViewController class]]) {
104
 			RNNRootViewController* rootVc = (RNNRootViewController*)vc;
106
 			RNNRootViewController* rootVc = (RNNRootViewController*)vc;
105
 			rootVc.previewController = newVc;
107
 			rootVc.previewController = newVc;
106
-
107
-      		rootVc.previewCallback = ^(UIViewController *vcc) {
108
+			
109
+			rootVc.previewCallback = ^(UIViewController *vcc) {
108
 				RNNRootViewController* rvc  = (RNNRootViewController*)vcc;
110
 				RNNRootViewController* rvc  = (RNNRootViewController*)vcc;
109
 				[self->_eventEmitter sendOnPreviewCompleted:componentId previewComponentId:newVc.layoutInfo.componentId];
111
 				[self->_eventEmitter sendOnPreviewCompleted:componentId previewComponentId:newVc.layoutInfo.componentId];
110
 				if ([newVc.resolveOptions.preview.commit getWithDefaultValue:NO]) {
112
 				if ([newVc.resolveOptions.preview.commit getWithDefaultValue:NO]) {
131
 			if (newVc.resolveOptions.preview.width.hasValue || newVc.resolveOptions.preview.height.hasValue) {
133
 			if (newVc.resolveOptions.preview.width.hasValue || newVc.resolveOptions.preview.height.hasValue) {
132
 				newVc.preferredContentSize = size;
134
 				newVc.preferredContentSize = size;
133
 			}
135
 			}
134
-      
136
+			
135
 			RCTExecuteOnMainQueue(^{
137
 			RCTExecuteOnMainQueue(^{
136
 				UIView *view = [[ReactNativeNavigation getBridge].uiManager viewForReactTag:newVc.resolveOptions.preview.reactTag.get];
138
 				UIView *view = [[ReactNativeNavigation getBridge].uiManager viewForReactTag:newVc.resolveOptions.preview.reactTag.get];
137
 				[rootVc registerForPreviewingWithDelegate:(id)rootVc sourceView:view];
139
 				[rootVc registerForPreviewingWithDelegate:(id)rootVc sourceView:view];

+ 37
- 17
lib/ios/ReactNativeNavigationTests/RNNCommandsHandlerTest.m View File

32
 @property (nonatomic, strong) RNNRootViewController* vc2;
32
 @property (nonatomic, strong) RNNRootViewController* vc2;
33
 @property (nonatomic, strong) RNNRootViewController* vc3;
33
 @property (nonatomic, strong) RNNRootViewController* vc3;
34
 @property (nonatomic, strong) MockUINavigationController* nvc;
34
 @property (nonatomic, strong) MockUINavigationController* nvc;
35
+@property (nonatomic, strong) id mainWindow;
35
 @property (nonatomic, strong) id controllerFactory;
36
 @property (nonatomic, strong) id controllerFactory;
36
 @property (nonatomic, strong) id overlayManager;
37
 @property (nonatomic, strong) id overlayManager;
37
 @property (nonatomic, strong) id eventEmmiter;
38
 @property (nonatomic, strong) id eventEmmiter;
42
 
43
 
43
 - (void)setUp {
44
 - (void)setUp {
44
 	[super setUp];
45
 	[super setUp];
46
+	self.mainWindow = [OCMockObject partialMockForObject:[UIWindow new]];
45
 	self.store = [OCMockObject partialMockForObject:[[RNNStore alloc] init]];
47
 	self.store = [OCMockObject partialMockForObject:[[RNNStore alloc] init]];
46
 	self.eventEmmiter = [OCMockObject partialMockForObject:[RNNEventEmitter new]];
48
 	self.eventEmmiter = [OCMockObject partialMockForObject:[RNNEventEmitter new]];
47
 	self.overlayManager = [OCMockObject partialMockForObject:[RNNOverlayManager new]];
49
 	self.overlayManager = [OCMockObject partialMockForObject:[RNNOverlayManager new]];
48
 	self.controllerFactory = [OCMockObject partialMockForObject:[[RNNControllerFactory alloc] initWithRootViewCreator:nil eventEmitter:self.eventEmmiter andBridge:nil]];
50
 	self.controllerFactory = [OCMockObject partialMockForObject:[[RNNControllerFactory alloc] initWithRootViewCreator:nil eventEmitter:self.eventEmmiter andBridge:nil]];
49
-	self.uut = [[RNNCommandsHandler alloc] initWithStore:self.store controllerFactory:self.controllerFactory eventEmitter:self.eventEmmiter stackManager:[RNNNavigationStackManager new] modalManager:[RNNModalManager new] overlayManager:self.overlayManager];
51
+	self.uut = [[RNNCommandsHandler alloc] initWithStore:self.store controllerFactory:self.controllerFactory eventEmitter:self.eventEmmiter stackManager:[RNNNavigationStackManager new] modalManager:[RNNModalManager new] overlayManager:self.overlayManager mainWindow:self.mainWindow];
50
 	self.vc1 = [RNNRootViewController new];
52
 	self.vc1 = [RNNRootViewController new];
51
 	self.vc2 = [RNNRootViewController new];
53
 	self.vc2 = [RNNRootViewController new];
52
 	self.vc3 = [RNNRootViewController new];
54
 	self.vc3 = [RNNRootViewController new];
72
 
74
 
73
 -(NSArray*) getPublicMethodNamesForObject:(NSObject*)obj{
75
 -(NSArray*) getPublicMethodNamesForObject:(NSObject*)obj{
74
 	NSMutableArray* skipMethods = [NSMutableArray new];
76
 	NSMutableArray* skipMethods = [NSMutableArray new];
75
-
76
-	[skipMethods addObject:@"initWithStore:controllerFactory:eventEmitter:stackManager:modalManager:overlayManager:"];
77
+	
78
+	[skipMethods addObject:@"initWithStore:controllerFactory:eventEmitter:stackManager:modalManager:overlayManager:mainWindow:"];
77
 	[skipMethods addObject:@"assertReady"];
79
 	[skipMethods addObject:@"assertReady"];
78
 	[skipMethods addObject:@"removePopedViewControllers:"];
80
 	[skipMethods addObject:@"removePopedViewControllers:"];
79
 	[skipMethods addObject:@".cxx_destruct"];
81
 	[skipMethods addObject:@".cxx_destruct"];
80
 	[skipMethods addObject:@"dismissedModal:"];
82
 	[skipMethods addObject:@"dismissedModal:"];
81
 	[skipMethods addObject:@"dismissedMultipleModals:"];
83
 	[skipMethods addObject:@"dismissedMultipleModals:"];
82
-
84
+	
83
 	NSMutableArray* result = [NSMutableArray new];
85
 	NSMutableArray* result = [NSMutableArray new];
84
-
86
+	
85
 	// count and names:
87
 	// count and names:
86
 	int i=0;
88
 	int i=0;
87
 	unsigned int mc = 0;
89
 	unsigned int mc = 0;
88
 	Method * mlist = class_copyMethodList(object_getClass(obj), &mc);
90
 	Method * mlist = class_copyMethodList(object_getClass(obj), &mc);
89
-
91
+	
90
 	for(i=0; i<mc; i++) {
92
 	for(i=0; i<mc; i++) {
91
 		NSString *methodName = [NSString stringWithUTF8String:sel_getName(method_getName(mlist[i]))];
93
 		NSString *methodName = [NSString stringWithUTF8String:sel_getName(method_getName(mlist[i]))];
92
-
94
+		
93
 		// filter skippedMethods
95
 		// filter skippedMethods
94
 		if (methodName && ![skipMethods containsObject:methodName]) {
96
 		if (methodName && ![skipMethods containsObject:methodName]) {
95
 			[result addObject:methodName];
97
 			[result addObject:methodName];
96
 		}
98
 		}
97
 	}
99
 	}
98
-
100
+	
99
 	return result;
101
 	return result;
100
 }
102
 }
101
 
103
 
112
 	
114
 	
113
 	[vc viewWillAppear:false];
115
 	[vc viewWillAppear:false];
114
 	XCTAssertTrue([vc.navigationItem.title isEqual:@"the title"]);
116
 	XCTAssertTrue([vc.navigationItem.title isEqual:@"the title"]);
115
-
117
+	
116
 	[self.store setReadyToReceiveCommands:true];
118
 	[self.store setReadyToReceiveCommands:true];
117
 	[self.store setComponent:vc componentId:@"componentId"];
119
 	[self.store setComponent:vc componentId:@"componentId"];
118
 	
120
 	
119
 	NSDictionary* dictFromJs = @{@"topBar": @{@"background" : @{@"color" : @(0xFFFF0000)}}};
121
 	NSDictionary* dictFromJs = @{@"topBar": @{@"background" : @{@"color" : @(0xFFFF0000)}}};
120
 	UIColor* expectedColor = [UIColor colorWithRed:1 green:0 blue:0 alpha:1];
122
 	UIColor* expectedColor = [UIColor colorWithRed:1 green:0 blue:0 alpha:1];
121
-
123
+	
122
 	[self.uut mergeOptions:@"componentId" options:dictFromJs completion:^{
124
 	[self.uut mergeOptions:@"componentId" options:dictFromJs completion:^{
123
 		XCTAssertTrue([vc.navigationItem.title isEqual:@"the title"]);
125
 		XCTAssertTrue([vc.navigationItem.title isEqual:@"the title"]);
124
 		XCTAssertTrue([nav.navigationBar.barTintColor isEqual:expectedColor]);
126
 		XCTAssertTrue([nav.navigationBar.barTintColor isEqual:expectedColor]);
149
 - (void)testPop_removeTopVCFromStore {
151
 - (void)testPop_removeTopVCFromStore {
150
 	[self.store setReadyToReceiveCommands:true];
152
 	[self.store setReadyToReceiveCommands:true];
151
 	XCTestExpectation *expectation = [self expectationWithDescription:@"Testing Async Method"];
153
 	XCTestExpectation *expectation = [self expectationWithDescription:@"Testing Async Method"];
152
-
154
+	
153
 	[self.uut pop:@"vc3" mergeOptions:nil completion:^{
155
 	[self.uut pop:@"vc3" mergeOptions:nil completion:^{
154
 		XCTAssertNil([self.store findComponentForId:@"vc3"]);
156
 		XCTAssertNil([self.store findComponentForId:@"vc3"]);
155
 		XCTAssertNotNil([self.store findComponentForId:@"vc2"]);
157
 		XCTAssertNotNil([self.store findComponentForId:@"vc2"]);
224
 	[self.store setReadyToReceiveCommands:true];
226
 	[self.store setReadyToReceiveCommands:true];
225
 	OCMStub([self.overlayManager showOverlayWindow:[OCMArg any]]);
227
 	OCMStub([self.overlayManager showOverlayWindow:[OCMArg any]]);
226
 	OCMStub([self.controllerFactory createLayout:[OCMArg any] saveToStore:[OCMArg any]]);
228
 	OCMStub([self.controllerFactory createLayout:[OCMArg any] saveToStore:[OCMArg any]]);
227
-
229
+	
228
 	NSDictionary* layout = @{};
230
 	NSDictionary* layout = @{};
229
 	
231
 	
230
 	[[self.eventEmmiter expect] sendOnNavigationCommandCompletion:@"showOverlay" params:[OCMArg any]];
232
 	[[self.eventEmmiter expect] sendOnNavigationCommandCompletion:@"showOverlay" params:[OCMArg any]];
254
 - (void)testDismissOverlay_handleErrorIfNoOverlayExists {
256
 - (void)testDismissOverlay_handleErrorIfNoOverlayExists {
255
 	[self.store setReadyToReceiveCommands:true];
257
 	[self.store setReadyToReceiveCommands:true];
256
 	NSString* componentId = @"componentId";
258
 	NSString* componentId = @"componentId";
257
-    id errorHandlerMockClass = [OCMockObject mockForClass:[RNNErrorHandler class]];
259
+	id errorHandlerMockClass = [OCMockObject mockForClass:[RNNErrorHandler class]];
258
 	
260
 	
259
-    [[errorHandlerMockClass expect] reject:[OCMArg any] withErrorCode:1010 errorDescription:[OCMArg any]];
260
-    [self.uut dismissOverlay:componentId completion:[OCMArg any] rejection:[OCMArg any]];
261
-    [errorHandlerMockClass verify];
261
+	[[errorHandlerMockClass expect] reject:[OCMArg any] withErrorCode:1010 errorDescription:[OCMArg any]];
262
+	[self.uut dismissOverlay:componentId completion:[OCMArg any] rejection:[OCMArg any]];
263
+	[errorHandlerMockClass verify];
262
 }
264
 }
263
 
265
 
264
 - (void)testDismissOverlay_invokeNavigationCommandEvent {
266
 - (void)testDismissOverlay_invokeNavigationCommandEvent {
270
 	[self.uut dismissOverlay:componentId completion:^{
272
 	[self.uut dismissOverlay:componentId completion:^{
271
 		
273
 		
272
 	} rejection:^(NSString *code, NSString *message, NSError *error) {}];
274
 	} rejection:^(NSString *code, NSString *message, NSError *error) {}];
273
-	 
275
+	
274
 	[self.eventEmmiter verify];
276
 	[self.eventEmmiter verify];
275
 }
277
 }
276
 
278
 
279
+- (void)testSetRoot_setRootViewControllerOnMainWindow {
280
+	[self.store setReadyToReceiveCommands:true];
281
+	OCMStub([self.controllerFactory createLayout:[OCMArg any] saveToStore:self.store]).andReturn(self.vc1);
282
+	
283
+	[[self.mainWindow expect] setRootViewController:self.vc1];
284
+	[self.uut setRoot:@{} completion:^{}];
285
+	[self.mainWindow verify];
286
+}
287
+
288
+- (void)testSetRoot_removeAllComponentsFromMainWindow {
289
+	[self.store setReadyToReceiveCommands:true];
290
+	OCMStub([self.controllerFactory createLayout:[OCMArg any] saveToStore:self.store]).andReturn(self.vc1);
291
+	
292
+	[[self.store expect] removeAllComponentsFromWindow:self.mainWindow];
293
+	[self.uut setRoot:@{} completion:^{}];
294
+	[self.store verify];
295
+}
296
+
277
 @end
297
 @end