Skip to content

Commit

Permalink
setRoot on main application window - fix setRoot on iPad
Browse files Browse the repository at this point in the history
  • Loading branch information
yogevbd committed Dec 4, 2018
1 parent b369a54 commit a3922f8
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 27 deletions.
2 changes: 1 addition & 1 deletion lib/ios/RNNBridgeManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge {
id<RNNRootViewCreator> rootViewCreator = [[RNNReactRootViewCreator alloc] initWithBridge:bridge];
RNNControllerFactory *controllerFactory = [[RNNControllerFactory alloc] initWithRootViewCreator:rootViewCreator eventEmitter:eventEmitter andBridge:bridge];

_commandsHandler = [[RNNCommandsHandler alloc] initWithStore:_store controllerFactory:controllerFactory eventEmitter:eventEmitter stackManager:[RNNNavigationStackManager new] modalManager:[RNNModalManager new] overlayManager:[RNNOverlayManager new]];
_commandsHandler = [[RNNCommandsHandler alloc] initWithStore:_store controllerFactory:controllerFactory eventEmitter:eventEmitter stackManager:[RNNNavigationStackManager new] modalManager:[RNNModalManager new] overlayManager:[RNNOverlayManager new] mainWindow:[UIApplication sharedApplication].keyWindow];
RNNBridgeModule *bridgeModule = [[RNNBridgeModule alloc] initWithCommandsHandler:_commandsHandler];

return [@[bridgeModule,eventEmitter] arrayByAddingObjectsFromArray:[self extraModulesFromDelegate]];
Expand Down
2 changes: 1 addition & 1 deletion lib/ios/RNNCommandsHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

@interface RNNCommandsHandler : NSObject

- (instancetype)initWithStore:(RNNStore*)store controllerFactory:(RNNControllerFactory*)controllerFactory eventEmitter:(RNNEventEmitter *)eventEmitter stackManager:(RNNNavigationStackManager *)stackManager modalManager:(RNNModalManager *)modalManager overlayManager:(RNNOverlayManager *)overlayManager;
- (instancetype)initWithStore:(RNNStore*)store controllerFactory:(RNNControllerFactory*)controllerFactory eventEmitter:(RNNEventEmitter *)eventEmitter stackManager:(RNNNavigationStackManager *)stackManager modalManager:(RNNModalManager *)modalManager overlayManager:(RNNOverlayManager *)overlayManager mainWindow:(UIWindow *)mainWindow;

- (void)setRoot:(NSDictionary*)layout completion:(RNNTransitionCompletionBlock)completion;

Expand Down
18 changes: 10 additions & 8 deletions lib/ios/RNNCommandsHandler.m
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ @implementation RNNCommandsHandler {
RNNOverlayManager* _overlayManager;
RNNNavigationStackManager* _stackManager;
RNNEventEmitter* _eventEmitter;
UIWindow* _mainWindow;
}

- (instancetype)initWithStore:(RNNStore*)store controllerFactory:(RNNControllerFactory*)controllerFactory eventEmitter:(RNNEventEmitter *)eventEmitter stackManager:(RNNNavigationStackManager *)stackManager modalManager:(RNNModalManager *)modalManager overlayManager:(RNNOverlayManager *)overlayManager {
- (instancetype)initWithStore:(RNNStore*)store controllerFactory:(RNNControllerFactory*)controllerFactory eventEmitter:(RNNEventEmitter *)eventEmitter stackManager:(RNNNavigationStackManager *)stackManager modalManager:(RNNModalManager *)modalManager overlayManager:(RNNOverlayManager *)overlayManager mainWindow:(UIWindow *)mainWindow {
self = [super init];
_store = store;
_controllerFactory = controllerFactory;
Expand All @@ -45,6 +46,7 @@ - (instancetype)initWithStore:(RNNStore*)store controllerFactory:(RNNControllerF
_modalManager.delegate = self;
_stackManager = stackManager;
_overlayManager = overlayManager;
_mainWindow = mainWindow;
return self;
}

Expand All @@ -54,12 +56,12 @@ - (void)setRoot:(NSDictionary*)layout completion:(RNNTransitionCompletionBlock)c
[self assertReady];

[_modalManager dismissAllModalsAnimated:NO];
[_store removeAllComponentsFromWindow:UIApplication.sharedApplication.delegate.window];
[_store removeAllComponentsFromWindow:_mainWindow];

UIViewController *vc = [_controllerFactory createLayout:layout[@"root"] saveToStore:_store];

[UIApplication sharedApplication].windows.firstObject.rootViewController = vc;

_mainWindow.rootViewController = vc;
[_eventEmitter sendOnNavigationCommandCompletion:setRoot params:@{@"layout": layout}];
completion();
}
Expand All @@ -75,7 +77,7 @@ - (void)mergeOptions:(NSString*)componentId options:(NSDictionary*)mergeOptions

[vc overrideOptions:newOptions];
[vc mergeOptions:newOptions];

[CATransaction commit];
}
}
Expand Down Expand Up @@ -103,8 +105,8 @@ - (void)push:(NSString*)componentId layout:(NSDictionary*)layout completion:(RNN
if([vc isKindOfClass:[RNNRootViewController class]]) {
RNNRootViewController* rootVc = (RNNRootViewController*)vc;
rootVc.previewController = newVc;

rootVc.previewCallback = ^(UIViewController *vcc) {
rootVc.previewCallback = ^(UIViewController *vcc) {
RNNRootViewController* rvc = (RNNRootViewController*)vcc;
[self->_eventEmitter sendOnPreviewCompleted:componentId previewComponentId:newVc.layoutInfo.componentId];
if ([newVc.resolveOptions.preview.commit getWithDefaultValue:NO]) {
Expand All @@ -131,7 +133,7 @@ - (void)push:(NSString*)componentId layout:(NSDictionary*)layout completion:(RNN
if (newVc.resolveOptions.preview.width.hasValue || newVc.resolveOptions.preview.height.hasValue) {
newVc.preferredContentSize = size;
}
RCTExecuteOnMainQueue(^{
UIView *view = [[ReactNativeNavigation getBridge].uiManager viewForReactTag:newVc.resolveOptions.preview.reactTag.get];
[rootVc registerForPreviewingWithDelegate:(id)rootVc sourceView:view];
Expand Down
54 changes: 37 additions & 17 deletions lib/ios/ReactNativeNavigationTests/RNNCommandsHandlerTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ @interface RNNCommandsHandlerTest : XCTestCase
@property (nonatomic, strong) RNNRootViewController* vc2;
@property (nonatomic, strong) RNNRootViewController* vc3;
@property (nonatomic, strong) MockUINavigationController* nvc;
@property (nonatomic, strong) id mainWindow;
@property (nonatomic, strong) id controllerFactory;
@property (nonatomic, strong) id overlayManager;
@property (nonatomic, strong) id eventEmmiter;
Expand All @@ -42,11 +43,12 @@ @implementation RNNCommandsHandlerTest

- (void)setUp {
[super setUp];
self.mainWindow = [OCMockObject partialMockForObject:[UIWindow new]];
self.store = [OCMockObject partialMockForObject:[[RNNStore alloc] init]];
self.eventEmmiter = [OCMockObject partialMockForObject:[RNNEventEmitter new]];
self.overlayManager = [OCMockObject partialMockForObject:[RNNOverlayManager new]];
self.controllerFactory = [OCMockObject partialMockForObject:[[RNNControllerFactory alloc] initWithRootViewCreator:nil eventEmitter:self.eventEmmiter andBridge:nil]];
self.uut = [[RNNCommandsHandler alloc] initWithStore:self.store controllerFactory:self.controllerFactory eventEmitter:self.eventEmmiter stackManager:[RNNNavigationStackManager new] modalManager:[RNNModalManager new] overlayManager:self.overlayManager];
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];
self.vc1 = [RNNRootViewController new];
self.vc2 = [RNNRootViewController new];
self.vc3 = [RNNRootViewController new];
Expand All @@ -72,30 +74,30 @@ - (void)testAssertReadyForEachMethodThrowsExceptoins {

-(NSArray*) getPublicMethodNamesForObject:(NSObject*)obj{
NSMutableArray* skipMethods = [NSMutableArray new];

[skipMethods addObject:@"initWithStore:controllerFactory:eventEmitter:stackManager:modalManager:overlayManager:"];
[skipMethods addObject:@"initWithStore:controllerFactory:eventEmitter:stackManager:modalManager:overlayManager:mainWindow:"];
[skipMethods addObject:@"assertReady"];
[skipMethods addObject:@"removePopedViewControllers:"];
[skipMethods addObject:@".cxx_destruct"];
[skipMethods addObject:@"dismissedModal:"];
[skipMethods addObject:@"dismissedMultipleModals:"];

NSMutableArray* result = [NSMutableArray new];

// count and names:
int i=0;
unsigned int mc = 0;
Method * mlist = class_copyMethodList(object_getClass(obj), &mc);

for(i=0; i<mc; i++) {
NSString *methodName = [NSString stringWithUTF8String:sel_getName(method_getName(mlist[i]))];

// filter skippedMethods
if (methodName && ![skipMethods containsObject:methodName]) {
[result addObject:methodName];
}
}

return result;
}

Expand All @@ -112,13 +114,13 @@ -(void)testDynamicStylesMergeWithStaticStyles {

[vc viewWillAppear:false];
XCTAssertTrue([vc.navigationItem.title isEqual:@"the title"]);

[self.store setReadyToReceiveCommands:true];
[self.store setComponent:vc componentId:@"componentId"];

NSDictionary* dictFromJs = @{@"topBar": @{@"background" : @{@"color" : @(0xFFFF0000)}}};
UIColor* expectedColor = [UIColor colorWithRed:1 green:0 blue:0 alpha:1];

[self.uut mergeOptions:@"componentId" options:dictFromJs completion:^{
XCTAssertTrue([vc.navigationItem.title isEqual:@"the title"]);
XCTAssertTrue([nav.navigationBar.barTintColor isEqual:expectedColor]);
Expand Down Expand Up @@ -149,7 +151,7 @@ - (void)testMergeOptions_shouldOverrideOptions {
- (void)testPop_removeTopVCFromStore {
[self.store setReadyToReceiveCommands:true];
XCTestExpectation *expectation = [self expectationWithDescription:@"Testing Async Method"];

[self.uut pop:@"vc3" mergeOptions:nil completion:^{
XCTAssertNil([self.store findComponentForId:@"vc3"]);
XCTAssertNotNil([self.store findComponentForId:@"vc2"]);
Expand Down Expand Up @@ -224,7 +226,7 @@ - (void)testShowOverlay_invokeNavigationCommandEventWithLayout {
[self.store setReadyToReceiveCommands:true];
OCMStub([self.overlayManager showOverlayWindow:[OCMArg any]]);
OCMStub([self.controllerFactory createLayout:[OCMArg any] saveToStore:[OCMArg any]]);

NSDictionary* layout = @{};

[[self.eventEmmiter expect] sendOnNavigationCommandCompletion:@"showOverlay" params:[OCMArg any]];
Expand Down Expand Up @@ -254,11 +256,11 @@ - (void)testDismissOverlay_dismissReturnedViewController {
- (void)testDismissOverlay_handleErrorIfNoOverlayExists {
[self.store setReadyToReceiveCommands:true];
NSString* componentId = @"componentId";
id errorHandlerMockClass = [OCMockObject mockForClass:[RNNErrorHandler class]];
id errorHandlerMockClass = [OCMockObject mockForClass:[RNNErrorHandler class]];

[[errorHandlerMockClass expect] reject:[OCMArg any] withErrorCode:1010 errorDescription:[OCMArg any]];
[self.uut dismissOverlay:componentId completion:[OCMArg any] rejection:[OCMArg any]];
[errorHandlerMockClass verify];
[[errorHandlerMockClass expect] reject:[OCMArg any] withErrorCode:1010 errorDescription:[OCMArg any]];
[self.uut dismissOverlay:componentId completion:[OCMArg any] rejection:[OCMArg any]];
[errorHandlerMockClass verify];
}

- (void)testDismissOverlay_invokeNavigationCommandEvent {
Expand All @@ -270,8 +272,26 @@ - (void)testDismissOverlay_invokeNavigationCommandEvent {
[self.uut dismissOverlay:componentId completion:^{

} rejection:^(NSString *code, NSString *message, NSError *error) {}];

[self.eventEmmiter verify];
}

- (void)testSetRoot_setRootViewControllerOnMainWindow {
[self.store setReadyToReceiveCommands:true];
OCMStub([self.controllerFactory createLayout:[OCMArg any] saveToStore:self.store]).andReturn(self.vc1);

[[self.mainWindow expect] setRootViewController:self.vc1];
[self.uut setRoot:@{} completion:^{}];
[self.mainWindow verify];
}

- (void)testSetRoot_removeAllComponentsFromMainWindow {
[self.store setReadyToReceiveCommands:true];
OCMStub([self.controllerFactory createLayout:[OCMArg any] saveToStore:self.store]).andReturn(self.vc1);

[[self.store expect] removeAllComponentsFromWindow:self.mainWindow];
[self.uut setRoot:@{} completion:^{}];
[self.store verify];
}

@end

0 comments on commit a3922f8

Please sign in to comment.