From 275304c88e8f35bc053aec2328a94a38a6fce088 Mon Sep 17 00:00:00 2001 From: Yogev Ben David Date: Wed, 17 Apr 2019 18:42:16 +0300 Subject: [PATCH] Stop manually manage viewControllers store, Iterate layout instead (#4991) * Stop manually manage viewControllers store, Iterate layout instead * Update RNNCommandsHandlerTest.m --- lib/ios/RNNBridgeManager.h | 2 - lib/ios/RNNBridgeManager.m | 11 +- lib/ios/RNNCommandsHandler.h | 5 +- lib/ios/RNNCommandsHandler.m | 25 ++- lib/ios/RNNControllerFactory.h | 4 +- lib/ios/RNNControllerFactory.m | 6 +- lib/ios/RNNExternalComponentStore.h | 12 ++ lib/ios/RNNExternalComponentStore.m | 26 ++++ lib/ios/RNNLayoutManager.h | 9 ++ lib/ios/RNNLayoutManager.m | 47 ++++++ lib/ios/RNNModalManager.h | 5 +- lib/ios/RNNOverlayManager.h | 1 - lib/ios/RNNReactComponentRegistry.h | 1 - lib/ios/RNNRootViewController.m | 28 +--- lib/ios/RNNStore.h | 28 ---- lib/ios/RNNStore.m | 92 ----------- lib/ios/RNNViewControllerPresenter.m | 13 -- lib/ios/ReactNativeNavigation.m | 4 +- .../project.pbxproj | 36 +++-- .../RNNCommandsHandlerTest.m | 73 +++++---- .../RNNControllerFactoryTest.m | 17 +- .../RNNExternalComponentStoreTest.m | 33 ++++ .../RNNLayoutManagerTest.m | 88 +++++++++++ .../RNNNavigationStackManagerTest.m | 1 - .../ReactNativeNavigationTests/RNNStoreTest.m | 147 ------------------ .../UIViewController+LayoutProtocolTest.m | 14 -- lib/ios/UIViewController+LayoutProtocol.h | 2 - lib/ios/UIViewController+LayoutProtocol.m | 14 -- 28 files changed, 311 insertions(+), 433 deletions(-) create mode 100644 lib/ios/RNNExternalComponentStore.h create mode 100644 lib/ios/RNNExternalComponentStore.m create mode 100644 lib/ios/RNNLayoutManager.h create mode 100644 lib/ios/RNNLayoutManager.m delete mode 100644 lib/ios/RNNStore.h delete mode 100644 lib/ios/RNNStore.m create mode 100644 lib/ios/ReactNativeNavigationTests/RNNExternalComponentStoreTest.m create mode 100644 lib/ios/ReactNativeNavigationTests/RNNLayoutManagerTest.m delete mode 100644 lib/ios/ReactNativeNavigationTests/RNNStoreTest.m diff --git a/lib/ios/RNNBridgeManager.h b/lib/ios/RNNBridgeManager.h index faf695752e2..cf3ecc2d3b2 100644 --- a/lib/ios/RNNBridgeManager.h +++ b/lib/ios/RNNBridgeManager.h @@ -1,7 +1,6 @@ #import #import #import "RNNBridgeManagerDelegate.h" -#import "RNNStore.h" typedef UIViewController * (^RNNExternalViewCreator)(NSDictionary* props, RCTBridge* bridge); @@ -12,6 +11,5 @@ typedef UIViewController * (^RNNExternalViewCreator)(NSDictionary* props, RCTBri - (void)registerExternalComponent:(NSString *)name callback:(RNNExternalViewCreator)callback; @property (readonly, nonatomic, strong) RCTBridge *bridge; -@property (readonly, nonatomic, strong) RNNStore *store; @end diff --git a/lib/ios/RNNBridgeManager.m b/lib/ios/RNNBridgeManager.m index da34af5771e..1c3798d300c 100644 --- a/lib/ios/RNNBridgeManager.m +++ b/lib/ios/RNNBridgeManager.m @@ -13,7 +13,7 @@ @interface RNNBridgeManager() @property (nonatomic, strong, readwrite) RCTBridge *bridge; -@property (nonatomic, strong, readwrite) RNNStore *store; +@property (nonatomic, strong, readwrite) RNNExternalComponentStore *store; @property (nonatomic, strong, readwrite) RNNReactComponentRegistry *componentRegistry; @end @@ -25,7 +25,7 @@ @implementation RNNBridgeManager { RCTBridge* _bridge; UIWindow* _mainWindow; - RNNStore* _store; + RNNExternalComponentStore* _store; RNNCommandsHandler* _commandsHandler; } @@ -37,7 +37,7 @@ - (instancetype)initWithJsCodeLocation:(NSURL *)jsCodeLocation launchOptions:(NS _launchOptions = launchOptions; _delegate = delegate; - _store = [RNNStore new]; + _store = [RNNExternalComponentStore new]; _bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:_launchOptions]; @@ -82,7 +82,7 @@ - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge { _componentRegistry = [[RNNReactComponentRegistry alloc] initWithCreator:rootViewCreator]; RNNControllerFactory *controllerFactory = [[RNNControllerFactory alloc] initWithRootViewCreator:rootViewCreator eventEmitter:eventEmitter store:_store componentRegistry:_componentRegistry andBridge:bridge]; - _commandsHandler = [[RNNCommandsHandler alloc] initWithStore:_store controllerFactory:controllerFactory eventEmitter:eventEmitter stackManager:[RNNNavigationStackManager new] modalManager:[RNNModalManager new] overlayManager:[RNNOverlayManager new] mainWindow:_mainWindow]; + _commandsHandler = [[RNNCommandsHandler alloc] initWithControllerFactory:controllerFactory eventEmitter:eventEmitter stackManager:[RNNNavigationStackManager new] modalManager:[RNNModalManager new] overlayManager:[RNNOverlayManager new] mainWindow:_mainWindow]; RNNBridgeModule *bridgeModule = [[RNNBridgeModule alloc] initWithCommandsHandler:_commandsHandler]; return [@[bridgeModule,eventEmitter] arrayByAddingObjectsFromArray:[self extraModulesFromDelegate]]; @@ -91,12 +91,11 @@ - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge { # pragma mark - JavaScript & Bridge Notifications - (void)onJavaScriptWillLoad { - [_store clean]; [_componentRegistry clear]; } - (void)onJavaScriptLoaded { - [_store setReadyToReceiveCommands:true]; + [_commandsHandler setReadyToReceiveCommands:true]; [[_bridge moduleForClass:[RNNEventEmitter class]] sendOnAppLaunched]; } diff --git a/lib/ios/RNNCommandsHandler.h b/lib/ios/RNNCommandsHandler.h index 21927c0c16e..ad1f256ab9f 100644 --- a/lib/ios/RNNCommandsHandler.h +++ b/lib/ios/RNNCommandsHandler.h @@ -2,14 +2,15 @@ #import #import "RNNControllerFactory.h" -#import "RNNStore.h" #import "RNNModalManager.h" #import "RNNNavigationStackManager.h" #import "RNNOverlayManager.h" @interface RNNCommandsHandler : NSObject -- (instancetype)initWithStore:(RNNStore*)store controllerFactory:(RNNControllerFactory*)controllerFactory eventEmitter:(RNNEventEmitter *)eventEmitter stackManager:(RNNNavigationStackManager *)stackManager modalManager:(RNNModalManager *)modalManager overlayManager:(RNNOverlayManager *)overlayManager mainWindow:(UIWindow *)mainWindow; +- (instancetype)initWithControllerFactory:(RNNControllerFactory*)controllerFactory eventEmitter:(RNNEventEmitter *)eventEmitter stackManager:(RNNNavigationStackManager *)stackManager modalManager:(RNNModalManager *)modalManager overlayManager:(RNNOverlayManager *)overlayManager mainWindow:(UIWindow *)mainWindow; + +@property (nonatomic) BOOL readyToReceiveCommands; - (void)setRoot:(NSDictionary*)layout commandId:(NSString*)commandId completion:(RNNTransitionCompletionBlock)completion; diff --git a/lib/ios/RNNCommandsHandler.m b/lib/ios/RNNCommandsHandler.m index cb86b562159..1bfe3fd91ad 100644 --- a/lib/ios/RNNCommandsHandler.m +++ b/lib/ios/RNNCommandsHandler.m @@ -9,6 +9,7 @@ #import "UIViewController+RNNOptions.h" #import "React/RCTI18nUtil.h" #import "UIViewController+LayoutProtocol.h" +#import "RNNLayoutManager.h" static NSString* const setRoot = @"setRoot"; static NSString* const setStackRoot = @"setStackRoot"; @@ -31,7 +32,6 @@ @interface RNNCommandsHandler() @implementation RNNCommandsHandler { RNNControllerFactory *_controllerFactory; - RNNStore *_store; RNNModalManager* _modalManager; RNNOverlayManager* _overlayManager; RNNNavigationStackManager* _stackManager; @@ -39,9 +39,8 @@ @implementation RNNCommandsHandler { UIWindow* _mainWindow; } -- (instancetype)initWithStore:(RNNStore*)store controllerFactory:(RNNControllerFactory*)controllerFactory eventEmitter:(RNNEventEmitter *)eventEmitter stackManager:(RNNNavigationStackManager *)stackManager modalManager:(RNNModalManager *)modalManager overlayManager:(RNNOverlayManager *)overlayManager mainWindow:(UIWindow *)mainWindow { +- (instancetype)initWithControllerFactory:(RNNControllerFactory*)controllerFactory eventEmitter:(RNNEventEmitter *)eventEmitter stackManager:(RNNNavigationStackManager *)stackManager modalManager:(RNNModalManager *)modalManager overlayManager:(RNNOverlayManager *)overlayManager mainWindow:(UIWindow *)mainWindow { self = [super init]; - _store = store; _controllerFactory = controllerFactory; _eventEmitter = eventEmitter; _modalManager = modalManager; @@ -87,7 +86,7 @@ - (void)setRoot:(NSDictionary*)layout commandId:(NSString*)commandId completion: - (void)mergeOptions:(NSString*)componentId options:(NSDictionary*)mergeOptions completion:(RNNTransitionCompletionBlock)completion { [self assertReady]; - UIViewController* vc = (UIViewController*)[_store findComponentForId:componentId]; + UIViewController* vc = (UIViewController*)[RNNLayoutManager findComponentForId:componentId]; RNNNavigationOptions* newOptions = [[RNNNavigationOptions alloc] initWithDict:mergeOptions]; if ([vc conformsToProtocol:@protocol(RNNLayoutProtocol)] || [vc isKindOfClass:[RNNRootViewController class]]) { [CATransaction begin]; @@ -115,10 +114,10 @@ - (void)push:(NSString*)componentId commandId:(NSString*)commandId layout:(NSDic [self assertReady]; UIViewController *newVc = [_controllerFactory createLayout:layout]; - UIViewController *fromVC = [_store findComponentForId:componentId]; + UIViewController *fromVC = [RNNLayoutManager findComponentForId:componentId]; if ([[newVc.resolveOptions.preview.reactTag getWithDefaultValue:@(0)] floatValue] > 0) { - UIViewController* vc = [_store findComponentForId:componentId]; + UIViewController* vc = [RNNLayoutManager findComponentForId:componentId]; if([vc isKindOfClass:[RNNRootViewController class]]) { RNNRootViewController* rootVc = (RNNRootViewController*)vc; @@ -177,7 +176,7 @@ - (void)setStackRoot:(NSString*)componentId commandId:(NSString*)commandId child [viewController renderTreeAndWait:NO perform:nil]; } RNNNavigationOptions* options = [childViewControllers.lastObject getCurrentChild].resolveOptions; - UIViewController *fromVC = [_store findComponentForId:componentId]; + UIViewController *fromVC = [RNNLayoutManager findComponentForId:componentId]; __weak typeof(RNNEventEmitter*) weakEventEmitter = _eventEmitter; [_stackManager setStackChildren:childViewControllers fromViewController:fromVC animated:[options.animations.setStackRoot.enable getWithDefaultValue:YES] completion:^{ [weakEventEmitter sendOnNavigationCommandCompletion:setStackRoot commandId:commandId params:@{@"componentId": componentId}]; @@ -188,7 +187,7 @@ - (void)setStackRoot:(NSString*)componentId commandId:(NSString*)commandId child - (void)pop:(NSString*)componentId commandId:(NSString*)commandId mergeOptions:(NSDictionary*)mergeOptions completion:(RNNTransitionCompletionBlock)completion rejection:(RCTPromiseRejectBlock)rejection { [self assertReady]; - RNNRootViewController *vc = (RNNRootViewController*)[_store findComponentForId:componentId]; + RNNRootViewController *vc = (RNNRootViewController*)[RNNLayoutManager findComponentForId:componentId]; RNNNavigationOptions *options = [[RNNNavigationOptions alloc] initWithDict:mergeOptions]; [vc overrideOptions:options]; @@ -214,7 +213,7 @@ - (void)pop:(NSString*)componentId commandId:(NSString*)commandId mergeOptions:( - (void)popTo:(NSString*)componentId commandId:(NSString*)commandId mergeOptions:(NSDictionary *)mergeOptions completion:(RNNTransitionCompletionBlock)completion rejection:(RCTPromiseRejectBlock)rejection { [self assertReady]; - RNNRootViewController *vc = (RNNRootViewController*)[_store findComponentForId:componentId]; + RNNRootViewController *vc = (RNNRootViewController*)[RNNLayoutManager findComponentForId:componentId]; RNNNavigationOptions *options = [[RNNNavigationOptions alloc] initWithDict:mergeOptions]; [vc overrideOptions:options]; @@ -226,7 +225,7 @@ - (void)popTo:(NSString*)componentId commandId:(NSString*)commandId mergeOptions - (void)popToRoot:(NSString*)componentId commandId:(NSString*)commandId mergeOptions:(NSDictionary *)mergeOptions completion:(RNNTransitionCompletionBlock)completion rejection:(RCTPromiseRejectBlock)rejection { [self assertReady]; - RNNRootViewController *vc = (RNNRootViewController*)[_store findComponentForId:componentId]; + RNNRootViewController *vc = (RNNRootViewController*)[RNNLayoutManager findComponentForId:componentId]; RNNNavigationOptions *options = [[RNNNavigationOptions alloc] initWithDict:mergeOptions]; [vc overrideOptions:options]; @@ -261,7 +260,7 @@ - (void)showModal:(NSDictionary*)layout commandId:(NSString *)commandId completi - (void)dismissModal:(NSString*)componentId commandId:(NSString*)commandId mergeOptions:(NSDictionary *)mergeOptions completion:(RNNTransitionCompletionBlock)completion rejection:(RNNTransitionRejectionBlock)reject { [self assertReady]; - UIViewController *modalToDismiss = (UIViewController *)[_store findComponentForId:componentId]; + UIViewController *modalToDismiss = (UIViewController *)[RNNLayoutManager findComponentForId:componentId]; if (!modalToDismiss.isModal) { [RNNErrorHandler reject:reject withErrorCode:1013 errorDescription:@"component is not a modal"]; @@ -310,7 +309,7 @@ - (void)showOverlay:(NSDictionary *)layout commandId:(NSString*)commandId comple - (void)dismissOverlay:(NSString*)componentId commandId:(NSString*)commandId completion:(RNNTransitionCompletionBlock)completion rejection:(RNNTransitionRejectionBlock)reject { [self assertReady]; - UIViewController* viewController = [_store findComponentForId:componentId]; + UIViewController* viewController = [RNNLayoutManager findComponentForId:componentId]; if (viewController) { [_overlayManager dismissOverlay:viewController]; [_eventEmitter sendOnNavigationCommandCompletion:dismissOverlay commandId:commandId params:@{@"componentId": componentId}]; @@ -323,7 +322,7 @@ - (void)dismissOverlay:(NSString*)componentId commandId:(NSString*)commandId com #pragma mark - private - (void)assertReady { - if (!_store.isReadyToReceiveCommands) { + if (!self.readyToReceiveCommands) { [[NSException exceptionWithName:@"BridgeNotLoadedError" reason:@"Bridge not yet loaded! Send commands after Navigation.events().onAppLaunched() has been called." userInfo:nil] diff --git a/lib/ios/RNNControllerFactory.h b/lib/ios/RNNControllerFactory.h index 9c97fc1f537..108b21639a5 100644 --- a/lib/ios/RNNControllerFactory.h +++ b/lib/ios/RNNControllerFactory.h @@ -2,7 +2,7 @@ #import #import #import "RNNRootViewCreator.h" -#import "RNNStore.h" +#import "RNNExternalComponentStore.h" #import "RNNEventEmitter.h" #import "RNNReactComponentRegistry.h" #import "RNNNavigationOptions.h" @@ -11,7 +11,7 @@ -(instancetype)initWithRootViewCreator:(id )creator eventEmitter:(RNNEventEmitter*)eventEmitter - store:(RNNStore *)store + store:(RNNExternalComponentStore *)store componentRegistry:(RNNReactComponentRegistry *)componentRegistry andBridge:(RCTBridge*)bridge; diff --git a/lib/ios/RNNControllerFactory.m b/lib/ios/RNNControllerFactory.m index d03ad42bbb6..75dcdebbdf6 100644 --- a/lib/ios/RNNControllerFactory.m +++ b/lib/ios/RNNControllerFactory.m @@ -18,7 +18,7 @@ @implementation RNNControllerFactory { id _creator; - RNNStore *_store; + RNNExternalComponentStore *_store; RCTBridge *_bridge; RNNReactComponentRegistry* _componentRegistry; } @@ -28,7 +28,7 @@ @implementation RNNControllerFactory { - (instancetype)initWithRootViewCreator:(id )creator eventEmitter:(RNNEventEmitter*)eventEmitter - store:(RNNStore *)store + store:(RNNExternalComponentStore *)store componentRegistry:(RNNReactComponentRegistry *)componentRegistry andBridge:(RCTBridge *)bridge { @@ -107,8 +107,6 @@ - (UIViewController *)fromTree:(NSDictionary*)json { @throw [NSException exceptionWithName:@"UnknownControllerType" reason:[@"Unknown controller type " stringByAppendingString:node.type] userInfo:nil]; } - result.store = _store; - return result; } diff --git a/lib/ios/RNNExternalComponentStore.h b/lib/ios/RNNExternalComponentStore.h new file mode 100644 index 00000000000..8d52e4117d3 --- /dev/null +++ b/lib/ios/RNNExternalComponentStore.h @@ -0,0 +1,12 @@ + +#import +#import +#import "ReactNativeNavigation.h" +#import "RNNLayoutInfo.h" + +@interface RNNExternalComponentStore : NSObject + +- (void)registerExternalComponent:(NSString *)name callback:(RNNExternalViewCreator)callback; +- (UIViewController *)getExternalComponent:(RNNLayoutInfo *)layoutInfo bridge:(RCTBridge *)bridge; + +@end diff --git a/lib/ios/RNNExternalComponentStore.m b/lib/ios/RNNExternalComponentStore.m new file mode 100644 index 00000000000..bde00a34de1 --- /dev/null +++ b/lib/ios/RNNExternalComponentStore.m @@ -0,0 +1,26 @@ +#import "RNNExternalComponentStore.h" + +@interface RNNExternalComponentStore () + +@end + +@implementation RNNExternalComponentStore { + NSMutableDictionary* _externalComponentCreators; +} + +-(instancetype)init { + self = [super init]; + _externalComponentCreators = [NSMutableDictionary new]; + return self; +} + +- (void)registerExternalComponent:(NSString *)name callback:(RNNExternalViewCreator)callback { + [_externalComponentCreators setObject:[callback copy] forKey:name]; +} + +- (UIViewController *)getExternalComponent:(RNNLayoutInfo *)layoutInfo bridge:(RCTBridge *)bridge { + RNNExternalViewCreator creator = [_externalComponentCreators objectForKey:layoutInfo.name]; + return creator(layoutInfo.props, bridge); +} + +@end diff --git a/lib/ios/RNNLayoutManager.h b/lib/ios/RNNLayoutManager.h new file mode 100644 index 00000000000..9da9ad25839 --- /dev/null +++ b/lib/ios/RNNLayoutManager.h @@ -0,0 +1,9 @@ + +#import +#import + +@interface RNNLayoutManager : NSObject + ++ (UIViewController *)findComponentForId:(NSString *)componentId; + +@end diff --git a/lib/ios/RNNLayoutManager.m b/lib/ios/RNNLayoutManager.m new file mode 100644 index 00000000000..a6c08de792f --- /dev/null +++ b/lib/ios/RNNLayoutManager.m @@ -0,0 +1,47 @@ + +#import "RNNLayoutManager.h" +#import "RNNLayoutProtocol.h" +#import "UIViewController+LayoutProtocol.h" + +@implementation RNNLayoutManager + ++ (UIViewController *)findComponentForId:(NSString *)componentId { + for (UIWindow* window in UIApplication.sharedApplication.windows) { + UIViewController* result = [self findChildComponentForParent:window.rootViewController ForId:componentId]; + if (result) { + return result; + } + } + + return nil; +} + ++ (UIViewController *)findChildComponentForParent:(UIViewController *)parentViewController ForId:(NSString *)componentId { + if ([parentViewController.layoutInfo.componentId isEqualToString:componentId]) { + return parentViewController; + } + + if (parentViewController.presentedViewController) { + if ([parentViewController.presentedViewController.layoutInfo.componentId isEqualToString:componentId]) { + return parentViewController.presentedViewController; + } + + UIViewController* modalResult = [self findChildComponentForParent:parentViewController.presentedViewController ForId:componentId]; + if (modalResult) { + return modalResult; + } + + } + + for (UIViewController* childVC in parentViewController.childViewControllers) { + UIViewController* result = [self findChildComponentForParent:childVC ForId:componentId]; + if (result) { + return result; + } + } + + return nil; +} + + +@end diff --git a/lib/ios/RNNModalManager.h b/lib/ios/RNNModalManager.h index 04f9245289d..9809db0217e 100644 --- a/lib/ios/RNNModalManager.h +++ b/lib/ios/RNNModalManager.h @@ -1,6 +1,9 @@ #import #import -#import "RNNStore.h" + +typedef void (^RNNTransitionCompletionBlock)(void); +typedef void (^RNNTransitionWithComponentIdCompletionBlock)(NSString *componentId); +typedef void (^RNNTransitionRejectionBlock)(NSString *code, NSString *message, NSError *error); @protocol RNNModalManagerDelegate diff --git a/lib/ios/RNNOverlayManager.h b/lib/ios/RNNOverlayManager.h index fa6c3579151..aa6d0ac1231 100644 --- a/lib/ios/RNNOverlayManager.h +++ b/lib/ios/RNNOverlayManager.h @@ -1,6 +1,5 @@ #import #import -#import "RNNStore.h" #import "RNNOverlayWindow.h" @interface RNNOverlayManager : NSObject diff --git a/lib/ios/RNNReactComponentRegistry.h b/lib/ios/RNNReactComponentRegistry.h index 8f3d0254b95..726b883970a 100644 --- a/lib/ios/RNNReactComponentRegistry.h +++ b/lib/ios/RNNReactComponentRegistry.h @@ -1,7 +1,6 @@ #import #import "RNNReactView.h" #import "RNNComponentOptions.h" -#import "RNNStore.h" #import "RNNRootViewCreator.h" @interface RNNReactComponentRegistry : NSObject diff --git a/lib/ios/RNNRootViewController.m b/lib/ios/RNNRootViewController.m index cb7f20905b5..9bf90ba04e9 100644 --- a/lib/ios/RNNRootViewController.m +++ b/lib/ios/RNNRootViewController.m @@ -15,10 +15,6 @@ - (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo rootViewCreator:( self.animator = [[RNNAnimator alloc] initWithTransitionOptions:self.resolveOptions.customTransition]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(onJsReload) - name:RCTJavaScriptWillStartLoadingNotification - object:nil]; self.navigationController.delegate = self; return self; @@ -84,7 +80,7 @@ - (void)renderTreeAndWait:(BOOL)wait perform:(RNNReactViewReadyCompletionBlock)r } }]; }]; - + self.view = reactView; if (!wait && readyBlock) { @@ -213,27 +209,5 @@ -(void)onButtonPress:(RNNUIBarButtonItem *)barButtonItem { [self.eventEmitter sendOnNavigationButtonPressed:self.layoutInfo.componentId buttonId:barButtonItem.buttonId]; } -/** - * fix for #877, #878 - */ --(void)onJsReload { - [self cleanReactLeftovers]; -} - -/** - * fix for #880 - */ --(void)dealloc { - [self cleanReactLeftovers]; -} - --(void)cleanReactLeftovers { - [[NSNotificationCenter defaultCenter] removeObserver:self]; - [[NSNotificationCenter defaultCenter] removeObserver:self.view]; - self.view = nil; - self.navigationItem.titleView = nil; - self.navigationItem.rightBarButtonItems = nil; - self.navigationItem.leftBarButtonItems = nil; -} @end diff --git a/lib/ios/RNNStore.h b/lib/ios/RNNStore.h deleted file mode 100644 index 88e72d3abb0..00000000000 --- a/lib/ios/RNNStore.h +++ /dev/null @@ -1,28 +0,0 @@ - -#import -#import -#import "ReactNativeNavigation.h" -#import "RNNLayoutInfo.h" - -typedef void (^RNNTransitionCompletionBlock)(void); -typedef void (^RNNTransitionWithComponentIdCompletionBlock)(NSString *componentId); -typedef void (^RNNTransitionRejectionBlock)(NSString *code, NSString *message, NSError *error); - -@interface RNNStore : NSObject - -- (UIViewController*)findComponentForId:(NSString*)componentId; -- (void)setComponent:(UIViewController*)viewController componentId:(NSString*)componentId; -- (void)removeComponent:(NSString*)componentId; -- (void)removeAllComponents; -- (void)removeAllComponentsFromWindow:(UIWindow *)window; -- (void)registerExternalComponent:(NSString *)name callback:(RNNExternalViewCreator)callback; -- (UIViewController *)getExternalComponent:(RNNLayoutInfo *)layoutInfo bridge:(RCTBridge *)bridge; - -- (NSString*)componentKeyForInstance:(UIViewController*)instance; - -- (void)setReadyToReceiveCommands:(BOOL)isReady; -- (BOOL)isReadyToReceiveCommands; - -- (void)clean; - -@end diff --git a/lib/ios/RNNStore.m b/lib/ios/RNNStore.m deleted file mode 100644 index 71a1fa83589..00000000000 --- a/lib/ios/RNNStore.m +++ /dev/null @@ -1,92 +0,0 @@ -#import "RNNStore.h" - -@interface RNNStore () - -@end - -@implementation RNNStore { - NSMapTable* _componentStore; - NSMutableDictionary* _externalComponentCreators; - BOOL _isReadyToReceiveCommands; -} - --(instancetype)init { - self = [super init]; - _isReadyToReceiveCommands = false; - _componentStore = [NSMapTable strongToWeakObjectsMapTable]; - _externalComponentCreators = [NSMutableDictionary new]; - return self; -} - --(UIViewController *)findComponentForId:(NSString *)componentId { - return [_componentStore objectForKey:componentId]; -} - -- (void)setComponent:(UIViewController*)viewController componentId:(NSString*)componentId { - UIViewController *existingVewController = [self findComponentForId:componentId]; - if (existingVewController) { - @throw [NSException exceptionWithName:@"MultipleComponentId" reason:[@"Component id already exists " stringByAppendingString:componentId] userInfo:nil]; - } - - [_componentStore setObject:viewController forKey:componentId]; -} - -- (void)removeComponent:(NSString*)componentId { - [_componentStore removeObjectForKey:componentId]; -} - -- (void)removeAllComponents { - [_componentStore removeAllObjects]; -} - -- (void)removeAllComponentsFromWindow:(UIWindow *)window { - for (NSString *key in [self componentsForWindow:window]) { - [_componentStore removeObjectForKey:key]; - } -} - -- (NSArray *)componentsForWindow:(UIWindow *)window { - NSMutableArray* keyWindowComponents = [NSMutableArray new]; - for (NSString* key in _componentStore) { - UIViewController *component = [_componentStore objectForKey:key]; - if (component.view.window == window) { - [keyWindowComponents addObject:key]; - } - } - - return keyWindowComponents; -} - --(void)setReadyToReceiveCommands:(BOOL)isReady { - _isReadyToReceiveCommands = isReady; -} - --(BOOL)isReadyToReceiveCommands { - return _isReadyToReceiveCommands; -} - --(void)clean { - _isReadyToReceiveCommands = false; - [self removeAllComponents]; -} - --(NSString*)componentKeyForInstance:(UIViewController*)instance { - for (NSString *key in _componentStore) { - UIViewController *value = [_componentStore objectForKey:key]; - if (value == instance) { - return key; - } - } - return nil; -} - -- (void)registerExternalComponent:(NSString *)name callback:(RNNExternalViewCreator)callback { - [_externalComponentCreators setObject:[callback copy] forKey:name]; -} - -- (UIViewController *)getExternalComponent:(RNNLayoutInfo *)layoutInfo bridge:(RCTBridge *)bridge { - RNNExternalViewCreator creator = [_externalComponentCreators objectForKey:layoutInfo.name]; - return creator(layoutInfo.props, bridge); -} - -@end diff --git a/lib/ios/RNNViewControllerPresenter.m b/lib/ios/RNNViewControllerPresenter.m index 7babcb8591b..acd32bce459 100644 --- a/lib/ios/RNNViewControllerPresenter.m +++ b/lib/ios/RNNViewControllerPresenter.m @@ -17,16 +17,6 @@ @interface RNNViewControllerPresenter() { @implementation RNNViewControllerPresenter -- (instancetype)init { - self = [super init]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(cleanReactLeftovers) - name:RCTJavaScriptWillStartLoadingNotification - object:nil]; - - return self; -} - - (instancetype)initWithComponentRegistry:(RNNReactComponentRegistry *)componentRegistry { self = [self init]; _componentRegistry = componentRegistry; @@ -220,8 +210,5 @@ - (void)dealloc { [_componentRegistry clearComponentsForParentId:self.bindedComponentId]; } -- (void)cleanReactLeftovers { - _customTitleView = nil; -} @end diff --git a/lib/ios/ReactNativeNavigation.m b/lib/ios/ReactNativeNavigation.m index dbb2dbc93de..fa671acad8f 100644 --- a/lib/ios/ReactNativeNavigation.m +++ b/lib/ios/ReactNativeNavigation.m @@ -4,6 +4,7 @@ #import "RNNBridgeManager.h" #import "RNNSplashScreen.h" +#import "RNNLayoutManager.h" @interface ReactNativeNavigation() @@ -32,8 +33,7 @@ + (RCTBridge *)getBridge { } + (UIViewController *)findViewController:(NSString *)componentId { - RNNStore *store = [[ReactNativeNavigation sharedInstance].bridgeManager store]; - return [store findComponentForId:componentId]; + return [RNNLayoutManager findComponentForId:componentId]; } # pragma mark - instance diff --git a/lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj b/lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj index 7633d173be2..066d4091281 100644 --- a/lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj +++ b/lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj @@ -53,8 +53,6 @@ 263905D71E4C94970023D7D3 /* RNNSideMenuController.m in Sources */ = {isa = PBXBuildFile; fileRef = 263905D51E4C94970023D7D3 /* RNNSideMenuController.m */; }; 263905E61E4CAC950023D7D3 /* RNNSideMenuChildVC.h in Headers */ = {isa = PBXBuildFile; fileRef = 263905E41E4CAC950023D7D3 /* RNNSideMenuChildVC.h */; }; 263905E71E4CAC950023D7D3 /* RNNSideMenuChildVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 263905E51E4CAC950023D7D3 /* RNNSideMenuChildVC.m */; }; - 268692821E5054F800E2C612 /* RNNStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 268692801E5054F800E2C612 /* RNNStore.h */; }; - 268692831E5054F800E2C612 /* RNNStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 268692811E5054F800E2C612 /* RNNStore.m */; }; 26916C981E4B9E7700D13680 /* RNNReactRootViewCreator.h in Headers */ = {isa = PBXBuildFile; fileRef = 26916C961E4B9E7700D13680 /* RNNReactRootViewCreator.h */; }; 26916C991E4B9E7700D13680 /* RNNReactRootViewCreator.m in Sources */ = {isa = PBXBuildFile; fileRef = 26916C971E4B9E7700D13680 /* RNNReactRootViewCreator.m */; }; 2DCD9195200014A900EDC75D /* RNNBridgeManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DCD9193200014A900EDC75D /* RNNBridgeManager.h */; }; @@ -141,6 +139,10 @@ 50451D0D2042F70900695F00 /* RNNTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = 50451D0B2042F70900695F00 /* RNNTransition.h */; }; 50451D0E2042F70900695F00 /* RNNTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = 50451D0C2042F70900695F00 /* RNNTransition.m */; }; 504753782109C13C00FFFBE6 /* RNNOverlayManagerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 504753772109C13C00FFFBE6 /* RNNOverlayManagerTest.m */; }; + 5047E4F022674AD400908DD3 /* RNNLayoutManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 5047E4EE22674AD400908DD3 /* RNNLayoutManager.h */; }; + 5047E4F122674AD400908DD3 /* RNNLayoutManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5047E4EF22674AD400908DD3 /* RNNLayoutManager.m */; }; + 5047E4F42267568800908DD3 /* RNNExternalComponentStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 5047E4F22267568500908DD3 /* RNNExternalComponentStore.h */; }; + 5047E4F52267568800908DD3 /* RNNExternalComponentStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 5047E4F32267568700908DD3 /* RNNExternalComponentStore.m */; }; 5048862D20BE976D000908DE /* RNNLayoutOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 5048862B20BE976D000908DE /* RNNLayoutOptions.h */; }; 5048862E20BE976D000908DE /* RNNLayoutOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 5048862C20BE976D000908DE /* RNNLayoutOptions.m */; }; 50495939216E5750006D2B81 /* Bool.h in Headers */ = {isa = PBXBuildFile; fileRef = 50495937216E5750006D2B81 /* Bool.h */; }; @@ -174,6 +176,7 @@ 50570B272061473D006A1B5C /* RNNTitleOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 50570B252061473D006A1B5C /* RNNTitleOptions.m */; }; 50570BEA2063E09B006A1B5C /* RNNTitleViewHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 50570BE82063E09B006A1B5C /* RNNTitleViewHelper.h */; }; 50570BEB2063E09B006A1B5C /* RNNTitleViewHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 50570BE92063E09B006A1B5C /* RNNTitleViewHelper.m */; }; + 505963F722676A0000EBB63C /* RNNLayoutManagerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 505963F622676A0000EBB63C /* RNNLayoutManagerTest.m */; }; 505EDD32214E4BE80071C7DE /* RNNNavigationControllerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 505EDD31214E4BE80071C7DE /* RNNNavigationControllerTest.m */; }; 505EDD34214E7B7B0071C7DE /* RNNLeafProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 505EDD33214E7A6A0071C7DE /* RNNLeafProtocol.h */; }; 505EDD3C214FA8000071C7DE /* RNNViewControllerPresenter.h in Headers */ = {isa = PBXBuildFile; fileRef = 505EDD3A214FA8000071C7DE /* RNNViewControllerPresenter.h */; }; @@ -258,7 +261,7 @@ 7B4928091E70415400555040 /* RNNCommandsHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B4928071E70415400555040 /* RNNCommandsHandler.m */; }; 7B49FEC01E95090800DEB3EA /* libReactNativeNavigation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D8AFADBD1BEE6F3F00A4592D /* libReactNativeNavigation.a */; }; 7B49FECB1E95098500DEB3EA /* RNNControllerFactoryTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B49FEC61E95098500DEB3EA /* RNNControllerFactoryTest.m */; }; - 7B49FECC1E95098500DEB3EA /* RNNStoreTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B49FEC71E95098500DEB3EA /* RNNStoreTest.m */; }; + 7B49FECC1E95098500DEB3EA /* RNNExternalComponentStoreTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B49FEC71E95098500DEB3EA /* RNNExternalComponentStoreTest.m */; }; 7B49FECD1E95098500DEB3EA /* RNNModalManagerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B49FEC81E95098500DEB3EA /* RNNModalManagerTest.m */; }; 7B49FECE1E95098500DEB3EA /* RNNCommandsHandlerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B49FEC91E95098500DEB3EA /* RNNCommandsHandlerTest.m */; }; 7B49FECF1E95098500DEB3EA /* RNNNavigationStackManagerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B49FECA1E95098500DEB3EA /* RNNNavigationStackManagerTest.m */; }; @@ -391,8 +394,6 @@ 263905D51E4C94970023D7D3 /* RNNSideMenuController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNNSideMenuController.m; sourceTree = ""; }; 263905E41E4CAC950023D7D3 /* RNNSideMenuChildVC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNNSideMenuChildVC.h; sourceTree = ""; }; 263905E51E4CAC950023D7D3 /* RNNSideMenuChildVC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNNSideMenuChildVC.m; sourceTree = ""; }; - 268692801E5054F800E2C612 /* RNNStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNNStore.h; sourceTree = ""; }; - 268692811E5054F800E2C612 /* RNNStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNNStore.m; sourceTree = ""; }; 26916C941E4B9CCC00D13680 /* RNNRootViewCreator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNRootViewCreator.h; sourceTree = ""; }; 26916C961E4B9E7700D13680 /* RNNReactRootViewCreator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNNReactRootViewCreator.h; sourceTree = ""; }; 26916C971E4B9E7700D13680 /* RNNReactRootViewCreator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNNReactRootViewCreator.m; sourceTree = ""; }; @@ -481,6 +482,10 @@ 50451D0B2042F70900695F00 /* RNNTransition.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNTransition.h; sourceTree = ""; }; 50451D0C2042F70900695F00 /* RNNTransition.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNTransition.m; sourceTree = ""; }; 504753772109C13C00FFFBE6 /* RNNOverlayManagerTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNNOverlayManagerTest.m; sourceTree = ""; }; + 5047E4EE22674AD400908DD3 /* RNNLayoutManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNLayoutManager.h; sourceTree = ""; }; + 5047E4EF22674AD400908DD3 /* RNNLayoutManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNLayoutManager.m; sourceTree = ""; }; + 5047E4F22267568500908DD3 /* RNNExternalComponentStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNNExternalComponentStore.h; sourceTree = ""; }; + 5047E4F32267568700908DD3 /* RNNExternalComponentStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNNExternalComponentStore.m; sourceTree = ""; }; 5048862B20BE976D000908DE /* RNNLayoutOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNLayoutOptions.h; sourceTree = ""; }; 5048862C20BE976D000908DE /* RNNLayoutOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNLayoutOptions.m; sourceTree = ""; }; 50495937216E5750006D2B81 /* Bool.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Bool.h; sourceTree = ""; }; @@ -513,6 +518,7 @@ 50570B252061473D006A1B5C /* RNNTitleOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNTitleOptions.m; sourceTree = ""; }; 50570BE82063E09B006A1B5C /* RNNTitleViewHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNTitleViewHelper.h; sourceTree = ""; }; 50570BE92063E09B006A1B5C /* RNNTitleViewHelper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNTitleViewHelper.m; sourceTree = ""; }; + 505963F622676A0000EBB63C /* RNNLayoutManagerTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNLayoutManagerTest.m; sourceTree = ""; }; 505EDD31214E4BE80071C7DE /* RNNNavigationControllerTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNNavigationControllerTest.m; sourceTree = ""; }; 505EDD33214E7A6A0071C7DE /* RNNLeafProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNLeafProtocol.h; sourceTree = ""; }; 505EDD3A214FA8000071C7DE /* RNNViewControllerPresenter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNViewControllerPresenter.h; sourceTree = ""; }; @@ -596,7 +602,7 @@ 7B49FEBB1E95090800DEB3EA /* ReactNativeNavigationTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ReactNativeNavigationTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 7B49FEBF1E95090800DEB3EA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 7B49FEC61E95098500DEB3EA /* RNNControllerFactoryTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNNControllerFactoryTest.m; sourceTree = ""; }; - 7B49FEC71E95098500DEB3EA /* RNNStoreTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNNStoreTest.m; sourceTree = ""; }; + 7B49FEC71E95098500DEB3EA /* RNNExternalComponentStoreTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNNExternalComponentStoreTest.m; sourceTree = ""; }; 7B49FEC81E95098500DEB3EA /* RNNModalManagerTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNNModalManagerTest.m; sourceTree = ""; }; 7B49FEC91E95098500DEB3EA /* RNNCommandsHandlerTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNNCommandsHandlerTest.m; sourceTree = ""; }; 7B49FECA1E95098500DEB3EA /* RNNNavigationStackManagerTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNNNavigationStackManagerTest.m; sourceTree = ""; }; @@ -1004,6 +1010,8 @@ 50D031332005149000386B3D /* RNNOverlayManager.m */, 5050465221F8F4490035497A /* RNNReactComponentRegistry.h */, 5050465321F8F4490035497A /* RNNReactComponentRegistry.m */, + 5047E4EE22674AD400908DD3 /* RNNLayoutManager.h */, + 5047E4EF22674AD400908DD3 /* RNNLayoutManager.m */, ); name = Managers; sourceTree = ""; @@ -1052,7 +1060,7 @@ isa = PBXGroup; children = ( 7B49FEC61E95098500DEB3EA /* RNNControllerFactoryTest.m */, - 7B49FEC71E95098500DEB3EA /* RNNStoreTest.m */, + 7B49FEC71E95098500DEB3EA /* RNNExternalComponentStoreTest.m */, 7B49FEC81E95098500DEB3EA /* RNNModalManagerTest.m */, 7B49FEC91E95098500DEB3EA /* RNNCommandsHandlerTest.m */, 7B49FECA1E95098500DEB3EA /* RNNNavigationStackManagerTest.m */, @@ -1077,6 +1085,7 @@ 5038A376216CF252009280BC /* UITabBarController+RNNOptionsTest.m */, 509B247F217873FF00C83C23 /* UINavigationController+RNNOptionsTest.m */, 50AB0B1E22562FA10039DAED /* UIViewController+LayoutProtocolTest.m */, + 505963F622676A0000EBB63C /* RNNLayoutManagerTest.m */, ); path = ReactNativeNavigationTests; sourceTree = ""; @@ -1122,8 +1131,8 @@ 7BA500741E2544B9001B9E1B /* ReactNativeNavigation.m */, 2DCD9193200014A900EDC75D /* RNNBridgeManager.h */, 2DCD9194200014A900EDC75D /* RNNBridgeManager.m */, - 268692801E5054F800E2C612 /* RNNStore.h */, - 268692811E5054F800E2C612 /* RNNStore.m */, + 5047E4F22267568500908DD3 /* RNNExternalComponentStore.h */, + 5047E4F32267568700908DD3 /* RNNExternalComponentStore.m */, 7B4928061E70415400555040 /* RNNCommandsHandler.h */, 7B4928071E70415400555040 /* RNNCommandsHandler.m */, 502CB43920CBCA140019B2FE /* RNNBridgeManagerDelegate.h */, @@ -1274,6 +1283,7 @@ 263905E61E4CAC950023D7D3 /* RNNSideMenuChildVC.h in Headers */, 263905C41E4C6F440023D7D3 /* SidebarFacebookAnimation.h in Headers */, 50F5DFC51F407AA0001A00BC /* RNNNavigationController.h in Headers */, + 5047E4F42267568800908DD3 /* RNNExternalComponentStore.h in Headers */, 21B85E5F1F44482A00B314B5 /* RNNNavigationButtons.h in Headers */, 7BEF0D181E437684003E96B0 /* RNNRootViewController.h in Headers */, 7B1126A61E2D2B6C00F9B03B /* RNNBridgeModule.h in Headers */, @@ -1291,7 +1301,6 @@ 5049593E216F5D73006D2B81 /* BoolParser.h in Headers */, 50C4A496206BDDBB00DB292E /* RNNSubtitleOptions.h in Headers */, 5039559B2174867000B0A663 /* DoubleParser.h in Headers */, - 268692821E5054F800E2C612 /* RNNStore.h in Headers */, E8AEDB3C1F55A1C2000F5A6A /* RNNElementView.h in Headers */, E8E518321F83B3E0000467AC /* RNNUtils.h in Headers */, 50E5F791223FA04C002AFEAD /* RNNAnimationConfigurationOptions.h in Headers */, @@ -1326,6 +1335,7 @@ 2DCD9195200014A900EDC75D /* RNNBridgeManager.h in Headers */, 7B1126A91E2D2B6C00F9B03B /* RNNControllerFactory.h in Headers */, 501E0217213E7EA3003365C5 /* RNNReactView.h in Headers */, + 5047E4F022674AD400908DD3 /* RNNLayoutManager.h in Headers */, 263905D61E4C94970023D7D3 /* RNNSideMenuController.h in Headers */, 503955972174864E00B0A663 /* NullDouble.h in Headers */, 263905C81E4C6F440023D7D3 /* SidebarFlipboardAnimation.h in Headers */, @@ -1444,6 +1454,7 @@ 504753782109C13C00FFFBE6 /* RNNOverlayManagerTest.m in Sources */, 502F0E182179C39900367CC3 /* RNNTabBarPresenterTest.m in Sources */, 506F630F216A5AD700AD0D0A /* RNNViewControllerPresenterTest.m in Sources */, + 505963F722676A0000EBB63C /* RNNLayoutManagerTest.m in Sources */, 7B49FECE1E95098500DEB3EA /* RNNCommandsHandlerTest.m in Sources */, 5038A379216D01F6009280BC /* RNNBottomTabOptionsTest.m in Sources */, E83BAD681F2734B500A9F3DD /* RNNNavigationOptionsTest.m in Sources */, @@ -1460,7 +1471,7 @@ E83BAD791F27416B00A9F3DD /* RNNRootViewControllerTest.m in Sources */, 50CE8503217C6C9B00084EBF /* RNNSideMenuPresenterTest.m in Sources */, E8DA243D1F973C1900CD552B /* RNNTransitionStateHolderTest.m in Sources */, - 7B49FECC1E95098500DEB3EA /* RNNStoreTest.m in Sources */, + 7B49FECC1E95098500DEB3EA /* RNNExternalComponentStoreTest.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1494,6 +1505,7 @@ E8DA24411F97459B00CD552B /* RNNElementFinder.m in Sources */, 50570B272061473D006A1B5C /* RNNTitleOptions.m in Sources */, 263905BF1E4C6F440023D7D3 /* RCCTheSideBarManagerViewController.m in Sources */, + 5047E4F122674AD400908DD3 /* RNNLayoutManager.m in Sources */, 5012241F217366D4000F5F98 /* ColorParser.m in Sources */, 651E1F8D21FD642100DFEA19 /* RNNSplitViewControllerPresenter.m in Sources */, 501E0218213E7EA3003365C5 /* RNNReactView.m in Sources */, @@ -1579,13 +1591,13 @@ 5038A3BE216E1490009280BC /* RNNTabBarItemCreator.m in Sources */, E8367B811F7A8A4700675C05 /* VICMAImageView.m in Sources */, 5049594B216F5FE6006D2B81 /* NullText.m in Sources */, + 5047E4F52267568800908DD3 /* RNNExternalComponentStore.m in Sources */, A7626C011FC5796200492FB8 /* RNNBottomTabsOptions.m in Sources */, 5012241721736667000F5F98 /* Color.m in Sources */, 263905AF1E4C6F440023D7D3 /* MMDrawerBarButtonItem.m in Sources */, E8AEDB4B1F5C0BAF000F5A6A /* RNNInteractivePopAnimator.m in Sources */, 7B4928091E70415400555040 /* RNNCommandsHandler.m in Sources */, 50887C1620ECC5C200D06111 /* RNNButtonOptions.m in Sources */, - 268692831E5054F800E2C612 /* RNNStore.m in Sources */, 7BC9346E1E26886E00EFA125 /* RNNControllerFactory.m in Sources */, 507F43F91FF525B500D9425B /* RNNSegmentedControl.m in Sources */, 5038A3B2216DF41B009280BC /* UIViewController+RNNOptions.m in Sources */, diff --git a/lib/ios/ReactNativeNavigationTests/RNNCommandsHandlerTest.m b/lib/ios/ReactNativeNavigationTests/RNNCommandsHandlerTest.m index f5a68706b77..a7cf983d415 100644 --- a/lib/ios/ReactNativeNavigationTests/RNNCommandsHandlerTest.m +++ b/lib/ios/ReactNativeNavigationTests/RNNCommandsHandlerTest.m @@ -7,6 +7,7 @@ #import "RNNNavigationController.h" #import "RNNErrorHandler.h" #import +#import "RNNLayoutManager.h" @interface MockUIApplication : NSObject @@ -40,7 +41,6 @@ @implementation MockUINavigationController @interface RNNCommandsHandlerTest : XCTestCase -@property (nonatomic, strong) id store; @property (nonatomic, strong) RNNCommandsHandler* uut; @property (nonatomic, strong) RNNRootViewController* vc1; @property (nonatomic, strong) RNNRootViewController* vc2; @@ -59,31 +59,26 @@ @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 store:self.store componentRegistry:nil andBridge:nil]]; - self.uut = [[RNNCommandsHandler alloc] initWithStore:self.store controllerFactory:self.controllerFactory eventEmitter:self.eventEmmiter stackManager:[RNNNavigationStackManager new] modalManager:[RNNModalManager new] overlayManager:self.overlayManager mainWindow:_mainWindow]; + self.controllerFactory = [OCMockObject partialMockForObject:[[RNNControllerFactory alloc] initWithRootViewCreator:nil eventEmitter:self.eventEmmiter store:nil componentRegistry:nil andBridge:nil]]; + self.uut = [[RNNCommandsHandler alloc] initWithControllerFactory:self.controllerFactory eventEmitter:self.eventEmmiter stackManager:[RNNNavigationStackManager new] modalManager:[RNNModalManager new] overlayManager:self.overlayManager mainWindow:_mainWindow]; self.vc1 = [RNNRootViewController new]; self.vc2 = [RNNRootViewController new]; self.vc3 = [RNNRootViewController new]; _nvc = [[MockUINavigationController alloc] init]; [_nvc setViewControllers:@[self.vc1, self.vc2, self.vc3]]; - [self.store setComponent:self.vc1 componentId:@"vc1"]; - [self.store setComponent:self.vc2 componentId:@"vc2"]; - [self.store setComponent:self.vc3 componentId:@"vc3"]; OCMStub([self.sharedApplication keyWindow]).andReturn(self.mainWindow); } - (void)testAssertReadyForEachMethodThrowsExceptoins { NSArray* methods = [self getPublicMethodNamesForObject:self.uut]; - [self.store setReadyToReceiveCommands:false]; + [self.uut setReadyToReceiveCommands:false]; for (NSString* methodName in methods) { SEL s = NSSelectorFromString(methodName); IMP imp = [self.uut methodForSelector:s]; void (*func)(id, SEL, id, id, id, id, id) = (void *)imp; - XCTAssertThrowsSpecificNamed(func(self.uut,s, nil, nil, nil, nil, nil), NSException, @"BridgeNotLoadedError"); } } @@ -91,9 +86,10 @@ - (void)testAssertReadyForEachMethodThrowsExceptoins { -(NSArray*) getPublicMethodNamesForObject:(NSObject*)obj{ NSMutableArray* skipMethods = [NSMutableArray new]; - [skipMethods addObject:@"initWithStore:controllerFactory:eventEmitter:stackManager:modalManager:overlayManager:mainWindow:"]; + [skipMethods addObject:@"initWithControllerFactory:eventEmitter:stackManager:modalManager:overlayManager:mainWindow:"]; [skipMethods addObject:@"assertReady"]; - [skipMethods addObject:@"removePopedViewControllers:"]; + [skipMethods addObject:@"setReadyToReceiveCommands:"]; + [skipMethods addObject:@"readyToReceiveCommands"]; [skipMethods addObject:@".cxx_destruct"]; [skipMethods addObject:@"dismissedModal:"]; [skipMethods addObject:@"dismissedMultipleModals:"]; @@ -132,8 +128,7 @@ -(void)testDynamicStylesMergeWithStaticStyles { [vc viewWillAppear:false]; XCTAssertTrue([vc.navigationItem.title isEqual:@"the title"]); - [self.store setReadyToReceiveCommands:true]; - [self.store setComponent:vc componentId:@"componentId"]; + [self.uut setReadyToReceiveCommands:true]; NSDictionary* dictFromJs = @{@"topBar": @{@"background" : @{@"color" : @(0xFFFF0000)}}}; UIColor* expectedColor = [UIColor colorWithRed:1 green:0 blue:0 alpha:1]; @@ -155,8 +150,7 @@ - (void)testMergeOptions_shouldOverrideOptions { [vc viewWillAppear:false]; XCTAssertTrue([vc.navigationItem.title isEqual:@"the title"]); - [self.store setReadyToReceiveCommands:true]; - [self.store setComponent:vc componentId:@"componentId"]; + [self.uut setReadyToReceiveCommands:true]; NSDictionary* dictFromJs = @{@"topBar": @{@"title" : @{@"text" : @"new title"}}}; @@ -166,7 +160,7 @@ - (void)testMergeOptions_shouldOverrideOptions { } - (void)testShowOverlay_createLayout { - [self.store setReadyToReceiveCommands:true]; + [self.uut setReadyToReceiveCommands:true]; OCMStub([self.overlayManager showOverlayWindow:[OCMArg any]]); NSDictionary* layout = @{}; @@ -176,7 +170,7 @@ - (void)testShowOverlay_createLayout { } - (void)testShowOverlay_saveToStore { - [self.store setReadyToReceiveCommands:true]; + [self.uut setReadyToReceiveCommands:true]; OCMStub([self.overlayManager showOverlayWindow:[OCMArg any]]); OCMStub([self.controllerFactory createLayout:[OCMArg any]]); @@ -186,7 +180,7 @@ - (void)testShowOverlay_saveToStore { } - (void)testShowOverlay_withCreatedLayout { - [self.store setReadyToReceiveCommands:true]; + [self.uut setReadyToReceiveCommands:true]; UIViewController* layoutVC = [RNNRootViewController new]; OCMStub([self.controllerFactory createLayout:[OCMArg any]]).andReturn(layoutVC); @@ -196,7 +190,7 @@ - (void)testShowOverlay_withCreatedLayout { } - (void)testShowOverlay_invokeNavigationCommandEventWithLayout { - [self.store setReadyToReceiveCommands:true]; + [self.uut setReadyToReceiveCommands:true]; OCMStub([self.overlayManager showOverlayWindow:[OCMArg any]]); id mockedVC = [OCMockObject partialMockForObject:self.vc1]; OCMStub([self.controllerFactory createLayout:[OCMArg any]]).andReturn(mockedVC); @@ -208,27 +202,30 @@ - (void)testShowOverlay_invokeNavigationCommandEventWithLayout { [self.eventEmmiter verify]; } -- (void)testDismissOverlay_findComponentFromStore { - [self.store setReadyToReceiveCommands:true]; +- (void)testDismissOverlay_findComponentFromLayoutManager { + [self.uut setReadyToReceiveCommands:true]; NSString* componentId = @"componentId"; - [[self.store expect] findComponentForId:componentId]; + id classMock = OCMClassMock([RNNLayoutManager class]); + [[classMock expect] findComponentForId:componentId]; [self.uut dismissOverlay:componentId commandId:@"" completion:^{} rejection:^(NSString *code, NSString *message, NSError *error) {}]; - [self.store verify]; + [classMock verify]; } - (void)testDismissOverlay_dismissReturnedViewController { - [self.store setReadyToReceiveCommands:true]; + [self.uut setReadyToReceiveCommands:true]; NSString* componentId = @"componentId"; UIViewController* returnedView = [UIViewController new]; - OCMStub([self.store findComponentForId:componentId]).andReturn(returnedView); - + + id classMock = OCMClassMock([RNNLayoutManager class]); + OCMStub(ClassMethod([classMock findComponentForId:componentId])).andReturn(returnedView); + [[self.overlayManager expect] dismissOverlay:returnedView]; [self.uut dismissOverlay:componentId commandId:@"" completion:^{} rejection:^(NSString *code, NSString *message, NSError *error) {}]; [self.overlayManager verify]; } - (void)testDismissOverlay_handleErrorIfNoOverlayExists { - [self.store setReadyToReceiveCommands:true]; + [self.uut setReadyToReceiveCommands:true]; NSString* componentId = @"componentId"; id errorHandlerMockClass = [OCMockObject mockForClass:[RNNErrorHandler class]]; @@ -238,9 +235,11 @@ - (void)testDismissOverlay_handleErrorIfNoOverlayExists { } - (void)testDismissOverlay_invokeNavigationCommandEvent { - [self.store setReadyToReceiveCommands:true]; + [self.uut setReadyToReceiveCommands:true]; NSString* componentId = @"componentId"; - OCMStub([self.store findComponentForId:componentId]).andReturn([UIViewController new]); + + id classMock = OCMClassMock([RNNLayoutManager class]); + OCMStub(ClassMethod([classMock findComponentForId:componentId])).andReturn([UIViewController new]); [[self.eventEmmiter expect] sendOnNavigationCommandCompletion:@"dismissOverlay" commandId:[OCMArg any] params:[OCMArg any]]; [self.uut dismissOverlay:componentId commandId:@"" completion:^{ @@ -251,7 +250,7 @@ - (void)testDismissOverlay_invokeNavigationCommandEvent { } - (void)testSetRoot_setRootViewControllerOnMainWindow { - [self.store setReadyToReceiveCommands:true]; + [self.uut setReadyToReceiveCommands:true]; OCMStub([self.controllerFactory createLayout:[OCMArg any]]).andReturn(self.vc1); [[self.mainWindow expect] setRootViewController:self.vc1]; @@ -261,20 +260,26 @@ - (void)testSetRoot_setRootViewControllerOnMainWindow { - (void)testSetStackRoot_resetStackWithSingleComponent { OCMStub([self.controllerFactory createChildrenLayout:[OCMArg any]]).andReturn(@[self.vc2]); - [self.store setReadyToReceiveCommands:true]; + [self.uut setReadyToReceiveCommands:true]; + id classMock = OCMClassMock([RNNLayoutManager class]); + OCMStub(ClassMethod([classMock findComponentForId:@"vc1"])).andReturn(_nvc); + [self.uut setStackRoot:@"vc1" commandId:@"" children:nil completion:^{ } rejection:^(NSString *code, NSString *message, NSError *error) { }]; + XCTAssertEqual(_nvc.viewControllers.firstObject, self.vc2); XCTAssertEqual(_nvc.viewControllers.count, 1); } - (void)testSetStackRoot_setMultipleChildren { NSArray* newViewControllers = @[_vc1, _vc3]; + id classMock = OCMClassMock([RNNLayoutManager class]); + OCMStub(ClassMethod([classMock findComponentForId:@"vc1"])).andReturn(_nvc); OCMStub([self.controllerFactory createChildrenLayout:[OCMArg any]]).andReturn(newViewControllers); - [self.store setReadyToReceiveCommands:true]; + [self.uut setReadyToReceiveCommands:true]; [self.uut setStackRoot:@"vc1" commandId:@"" children:nil completion:^{ } rejection:^(NSString *code, NSString *message, NSError *error) { @@ -284,7 +289,7 @@ - (void)testSetStackRoot_setMultipleChildren { } - (void)testSetRoot_waitForRenderTrue { - [self.store setReadyToReceiveCommands:true]; + [self.uut setReadyToReceiveCommands:true]; self.vc1.options = [[RNNNavigationOptions alloc] initEmptyOptions]; self.vc1.options.animations.setRoot.waitForRender = [[Bool alloc] initWithBOOL:YES]; @@ -297,7 +302,7 @@ - (void)testSetRoot_waitForRenderTrue { } - (void)testSetRoot_waitForRenderFalse { - [self.store setReadyToReceiveCommands:true]; + [self.uut setReadyToReceiveCommands:true]; self.vc1.options = [[RNNNavigationOptions alloc] initEmptyOptions]; self.vc1.options.animations.setRoot.waitForRender = [[Bool alloc] initWithBOOL:NO]; diff --git a/lib/ios/ReactNativeNavigationTests/RNNControllerFactoryTest.m b/lib/ios/ReactNativeNavigationTests/RNNControllerFactoryTest.m index a807ba30330..4a4f65181df 100644 --- a/lib/ios/ReactNativeNavigationTests/RNNControllerFactoryTest.m +++ b/lib/ios/ReactNativeNavigationTests/RNNControllerFactoryTest.m @@ -13,7 +13,7 @@ @interface RNNControllerFactoryTest : XCTestCase @property (nonatomic, strong) id creator; @property (nonatomic, strong) RNNControllerFactory *factory; -@property (nonatomic, strong) RNNStore *store; +@property (nonatomic, strong) RNNExternalComponentStore *store; @end @@ -22,7 +22,7 @@ @implementation RNNControllerFactoryTest - (void)setUp { [super setUp]; self.creator = nil; - self.store = [RNNStore new]; + self.store = [RNNExternalComponentStore new]; self.factory = [[RNNControllerFactory alloc] initWithRootViewCreator:self.creator eventEmitter:nil store:self.store componentRegistry:nil andBridge:nil]; } @@ -188,17 +188,4 @@ - (void)testCreateLayout_ComponentSideMenuLayoutCenterLeftRight { XCTAssertTrue([right.child isMemberOfClass:[RNNRootViewController class]]); } -- (void)testCreateLayout_addComponentToStore { - NSString *componentId = @"cntId"; - NSDictionary* layout = @{@"id": componentId, - @"type": @"Component", - @"data": @{}, - @"children": @[]}; - UIViewController *ans = [self.factory createLayout:layout]; - - UIViewController *storeAns = [self.store findComponentForId:componentId]; - XCTAssertEqualObjects(ans, storeAns); -} - - @end diff --git a/lib/ios/ReactNativeNavigationTests/RNNExternalComponentStoreTest.m b/lib/ios/ReactNativeNavigationTests/RNNExternalComponentStoreTest.m new file mode 100644 index 00000000000..ba4a3189b03 --- /dev/null +++ b/lib/ios/ReactNativeNavigationTests/RNNExternalComponentStoreTest.m @@ -0,0 +1,33 @@ + +#import +#import +#import "RNNExternalComponentStore.h" + +@interface RNNExternalComponentStoreTest : XCTestCase + +@property (nonatomic, strong) RNNExternalComponentStore *store; + +@end + +@implementation RNNExternalComponentStoreTest + +- (void)setUp { + [super setUp]; + + self.store = [RNNExternalComponentStore new]; +} + +- (void)testGetExternalComponentShouldRetrunSavedComponent { + UIViewController* testVC = [UIViewController new]; + RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] init]; + layoutInfo.name = @"extId1"; + [self.store registerExternalComponent:layoutInfo.name callback:^UIViewController *(NSDictionary *props, RCTBridge *bridge) { + return testVC; + }]; + + UIViewController* savedComponent = [self.store getExternalComponent:layoutInfo bridge:nil]; + XCTAssertEqual(testVC, savedComponent); +} + + +@end diff --git a/lib/ios/ReactNativeNavigationTests/RNNLayoutManagerTest.m b/lib/ios/ReactNativeNavigationTests/RNNLayoutManagerTest.m new file mode 100644 index 00000000000..6154b8bc6b3 --- /dev/null +++ b/lib/ios/ReactNativeNavigationTests/RNNLayoutManagerTest.m @@ -0,0 +1,88 @@ + +#import +#import +#import "RNNLayoutManager.h" +#import "UIViewController+LayoutProtocol.m" + +@interface RNNLayoutManagerTest : XCTestCase + +@property (nonatomic, strong) UIViewController* vc1; +@property (nonatomic, strong) UIViewController* vc2; +@property (nonatomic, strong) UIViewController* vc3; + +@property (nonatomic, strong) UIWindow* firstWindow; +@property (nonatomic, strong) UIWindow* secondWindow; + +@end + +@implementation RNNLayoutManagerTest + +- (void)setUp { + _vc1 = [self createMockViewControllerWithComponentId:@"vc1"]; + _vc2 = [self createMockViewControllerWithComponentId:@"vc2"]; + _vc3 = [self createMockViewControllerWithComponentId:@"vc3"]; + + _firstWindow = [[UIWindow alloc] init]; + _secondWindow = [[UIWindow alloc] init]; + NSArray* windows = @[_firstWindow, _secondWindow]; + + UIApplication* sharedApplication = [OCMockObject mockForClass:[UIApplication class]]; + id mockedApplicationClass = OCMClassMock([UIApplication class]); + OCMStub(ClassMethod([mockedApplicationClass sharedApplication])).andReturn(sharedApplication); + OCMStub([sharedApplication windows]).andReturn(windows); +} + +- (void)testFindComponentForIdShouldReturnVCInFirstWindowRoot { + _firstWindow.rootViewController = _vc1; + UIViewController *resultVC = [RNNLayoutManager findComponentForId:@"vc1"]; + XCTAssertEqual(resultVC, _vc1); +} + +- (void)testFindComponentForIdShouldReturnVCFromSecondWindowRoot { + _secondWindow.rootViewController = _vc1; + UIViewController *resultVC = [RNNLayoutManager findComponentForId:@"vc1"]; + XCTAssertEqual(resultVC, _vc1); +} + +- (void)testFindComponentShouldReturnModalFromFirstWindow { + UIViewController* modal = _vc1; + OCMStub([_vc2 presentedViewController]).andReturn(modal); + _firstWindow.rootViewController = _vc2; + UIViewController *resultVC = [RNNLayoutManager findComponentForId:@"vc1"]; + XCTAssertEqual(resultVC, modal); +} + +- (void)testFindComponentShouldReturnModalFromSecondWindow { + UIViewController* modal = _vc1; + OCMStub([_vc2 presentedViewController]).andReturn(modal); + _secondWindow.rootViewController = _vc2; + UIViewController *resultVC = [RNNLayoutManager findComponentForId:@"vc1"]; + XCTAssertEqual(resultVC, modal); +} + +- (void)testFindComponentShouldReturnNilForUndefindComponent { + _firstWindow.rootViewController = _vc1; + UIViewController *resultVC = [RNNLayoutManager findComponentForId:@"vvc"]; + XCTAssertNil(resultVC); +} + +- (void)testFindComponentShouldFindRootViewControllerChildViewController { + UINavigationController* nvc = [[UINavigationController alloc] init]; + [nvc setViewControllers:@[_vc1, _vc2, _vc3]]; + _secondWindow.rootViewController = nvc; + + UIViewController *resultVC = [RNNLayoutManager findComponentForId:@"vc3"]; + XCTAssertEqual(resultVC, _vc3); +} + +- (UIViewController *)createMockViewControllerWithComponentId:(NSString *)componentId { + RNNLayoutInfo* layoutInfo = [RNNLayoutInfo new]; + layoutInfo.componentId = componentId; + + UIViewController* vc = [OCMockObject partialMockForObject:[UIViewController new]]; + OCMStub([vc layoutInfo]).andReturn(layoutInfo); + + return vc; +} + +@end diff --git a/lib/ios/ReactNativeNavigationTests/RNNNavigationStackManagerTest.m b/lib/ios/ReactNativeNavigationTests/RNNNavigationStackManagerTest.m index 6b5b7366c6b..27149c9febc 100644 --- a/lib/ios/ReactNativeNavigationTests/RNNNavigationStackManagerTest.m +++ b/lib/ios/ReactNativeNavigationTests/RNNNavigationStackManagerTest.m @@ -1,5 +1,4 @@ #import -#import "RNNStore.h" #import "RNNNavigationStackManager.h" #import "RNNRootViewController.h" #import "RNNNavigationController.h" diff --git a/lib/ios/ReactNativeNavigationTests/RNNStoreTest.m b/lib/ios/ReactNativeNavigationTests/RNNStoreTest.m deleted file mode 100644 index 66690f4da4e..00000000000 --- a/lib/ios/ReactNativeNavigationTests/RNNStoreTest.m +++ /dev/null @@ -1,147 +0,0 @@ - -#import -#import -#import "RNNStore.h" - -@interface RNNStoreTest : XCTestCase - -@property (nonatomic, strong) RNNStore *store; - -@end - -@implementation RNNStoreTest - -- (void)setUp { - [super setUp]; - - self.store = [RNNStore new]; -} - - -- (void)testFindComponentForId_setAndGetsimpleComponentId { - NSString *componentId1 = @"cntId1"; - NSString *componentId2 = @"cntId2"; - - UIViewController *vc1 = [UIViewController new]; - UIViewController *vc2 = [UIViewController new]; - - [self.store setComponent:vc1 componentId:componentId1]; - [self.store setComponent:vc2 componentId:componentId2]; - - UIViewController *ans = [self.store findComponentForId:componentId1]; - - XCTAssertEqualObjects(vc1, ans); - XCTAssertNotEqualObjects(vc2, ans); -} - -- (void)testSetComponent_setNilComponentId { - NSString *componentId1 = nil; - UIViewController *vc1 = [UIViewController new]; - [self.store setComponent:vc1 componentId:componentId1]; - XCTAssertNil([self.store findComponentForId:componentId1]); - -} - -- (void)testSetComponent_setDoubleComponentId { - NSString *componentId1 = @"cntId1"; - - UIViewController *vc1 = [UIViewController new]; - UIViewController *vc2 = [UIViewController new]; - - [self.store setComponent:vc1 componentId:componentId1]; - - UIViewController *ans = [self.store findComponentForId:componentId1]; - XCTAssertEqualObjects(vc1, ans); - XCTAssertThrows([self.store setComponent:vc2 componentId:componentId1]); -} - -- (void)testRemoveComponent_removeExistComponent { - NSString *componentId1 = @"cntId1"; - UIViewController *vc1 = [UIViewController new]; - - [self.store setComponent:vc1 componentId:componentId1]; - - UIViewController *ans = [self.store findComponentForId:componentId1]; - XCTAssertEqualObjects(vc1, ans); - - [self.store removeComponent:componentId1]; - XCTAssertNil([self.store findComponentForId:componentId1]); -} - -- (void)testPopWillRemoveVcFromStore { - NSString *vcId = @"cnt_vc_2"; - - [self setComponentAndRelease:vcId]; - - - XCTAssertNil([self.store findComponentForId:vcId]); -} - -- (void)testRemoveAllComponentsFromWindowShouldRemoveComponentsInWindow { - UIViewController* overlayVC = [self createMockedViewControllerWithWindow:[UIWindow new]]; - - NSString* overlayId = @"overlayId"; - [self.store setComponent:overlayVC componentId:overlayId]; - [self.store removeAllComponentsFromWindow:overlayVC.view.window]; - XCTAssertNil([self.store findComponentForId:overlayId]); -} - -- (void)testRemoveAllComponentsFromWindowShouldNotRemoveComponentsInOtherWindows { - UIViewController* overlayVC = [self createMockedViewControllerWithWindow:[UIWindow new]]; - UIViewController* componentVC = [self createMockedViewControllerWithWindow:[UIWindow new]]; - - NSString* componentId = @"componentId"; - NSString* overlayId = @"overlayId"; - [self.store setComponent:overlayVC componentId:overlayId]; - [self.store setComponent:componentVC componentId:componentId]; - - [self.store removeAllComponentsFromWindow:componentVC.view.window]; - XCTAssertNil([self.store findComponentForId:componentId]); - XCTAssertNotNil([self.store findComponentForId:overlayId]); -} - -- (void)testGetExternalComponentShouldRetrunSavedComponent { - UIViewController* testVC = [UIViewController new]; - RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] init]; - layoutInfo.name = @"extId1"; - [self.store registerExternalComponent:layoutInfo.name callback:^UIViewController *(NSDictionary *props, RCTBridge *bridge) { - return testVC; - }]; - - UIViewController* savedComponent = [self.store getExternalComponent:layoutInfo bridge:nil]; - XCTAssertEqual(testVC, savedComponent); -} - -- (void)testComponentKeyForInstance_UknownComponentShouldReturnNil { - id result = [self.store componentKeyForInstance:[UIViewController new]]; - XCTAssertNil(result); -} - -- (void)testCleanStore { - [self.store clean]; - XCTAssertFalse(self.store.isReadyToReceiveCommands); -} - -#pragma mark - private - - --(void)setComponentAndRelease:(NSString*)vcId { - @autoreleasepool { - UIViewController *vc2 = [UIViewController new]; - [self.store setComponent:vc2 componentId:vcId]; - - XCTAssertNotNil([self.store findComponentForId:vcId]); - } -} - -- (UIViewController *)createMockedViewControllerWithWindow:(UIWindow *)window { - UIWindow* overlayWindow = [UIWindow new]; - id mockedViewController = [OCMockObject partialMockForObject:[UIViewController new]]; - id mockedView = [OCMockObject partialMockForObject:[UIView new]]; - OCMStub([mockedView window]).andReturn(overlayWindow); - OCMStub([mockedViewController view]).andReturn(mockedView); - return mockedViewController; -} - - -@end diff --git a/lib/ios/ReactNativeNavigationTests/UIViewController+LayoutProtocolTest.m b/lib/ios/ReactNativeNavigationTests/UIViewController+LayoutProtocolTest.m index 6381fc49945..a3023140cb0 100644 --- a/lib/ios/ReactNativeNavigationTests/UIViewController+LayoutProtocolTest.m +++ b/lib/ios/ReactNativeNavigationTests/UIViewController+LayoutProtocolTest.m @@ -17,19 +17,5 @@ - (void)setUp { self.uut.layoutInfo.componentId = @"componentId"; } -- (void)testSetStoreShouldSaveComponent { - RNNStore* store = [[RNNStore alloc] init]; - [self.uut setStore:store]; - XCTAssertNotNil([store findComponentForId:self.uut.layoutInfo.componentId]); -} - -- (void)testDeallocShouldRemoveComponentFromStore { - RNNStore* store = [[RNNStore alloc] init]; - [self.uut setStore:store]; - XCTAssertNotNil([store findComponentForId:self.uut.layoutInfo.componentId]); - self.uut = nil; - XCTAssertNil([store findComponentForId:self.uut.layoutInfo.componentId]); -} - @end diff --git a/lib/ios/UIViewController+LayoutProtocol.h b/lib/ios/UIViewController+LayoutProtocol.h index b51990b742c..1bc4cedcf1c 100644 --- a/lib/ios/UIViewController+LayoutProtocol.h +++ b/lib/ios/UIViewController+LayoutProtocol.h @@ -1,7 +1,6 @@ #import #import "RNNEventEmitter.h" #import "RNNLayoutProtocol.h" -#import "RNNStore.h" typedef void (^RNNReactViewReadyCompletionBlock)(void); @@ -24,7 +23,6 @@ typedef void (^RNNReactViewReadyCompletionBlock)(void); @property (nonatomic, strong) RNNNavigationOptions* options; @property (nonatomic, strong) RNNNavigationOptions* defaultOptions; @property (nonatomic, strong) RNNEventEmitter* eventEmitter; -@property (nonatomic, strong) RNNStore* store; @property (nonatomic) id creator; @end diff --git a/lib/ios/UIViewController+LayoutProtocol.m b/lib/ios/UIViewController+LayoutProtocol.m index 956e5e2dae2..ebaaaec25f1 100644 --- a/lib/ios/UIViewController+LayoutProtocol.m +++ b/lib/ios/UIViewController+LayoutProtocol.m @@ -24,11 +24,6 @@ - (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo return self; } -- (void)setStore:(RNNStore *)store { - objc_setAssociatedObject(self, @selector(store), store, OBJC_ASSOCIATION_RETAIN_NONATOMIC); - [self.store setComponent:self componentId:self.layoutInfo.componentId]; -} - - (RNNNavigationOptions *)resolveOptions { return [(RNNNavigationOptions *)[self.options mergeInOptions:self.getCurrentChild.resolveOptions.copy] withDefault:self.defaultOptions]; } @@ -81,11 +76,6 @@ - (void)willMoveToParentViewController:(UIViewController *)parent { } } -- (void)dealloc { - [self.store removeComponent:self.layoutInfo.componentId]; -} - - #pragma mark getters and setters to associated object - (RNNNavigationOptions *)options { @@ -128,10 +118,6 @@ - (void)setEventEmitter:(RNNEventEmitter *)eventEmitter { objc_setAssociatedObject(self, @selector(eventEmitter), eventEmitter, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } -- (RNNStore *)store { - return objc_getAssociatedObject(self, @selector(store)); -} - - (id)creator { return objc_getAssociatedObject(self, @selector(creator)); }