Skip to content

Commit

Permalink
Handle adding and removing components from registry manually by prese…
Browse files Browse the repository at this point in the history
…nters (#4942)
  • Loading branch information
yogevbd authored Apr 3, 2019
1 parent 283f226 commit ac60d2f
Show file tree
Hide file tree
Showing 16 changed files with 96 additions and 34 deletions.
2 changes: 2 additions & 0 deletions lib/ios/RNNBasePresenter.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

@property (nonatomic, weak) id bindedViewController;

@property (nonatomic, strong) NSString* bindedComponentId;

- (void)bindViewController:(UIViewController *)bindedViewController;

- (void)applyOptionsOnInit:(RNNNavigationOptions *)initialOptions;
Expand Down
5 changes: 3 additions & 2 deletions lib/ios/RNNBasePresenter.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@ @interface RNNBasePresenter ()

@implementation RNNBasePresenter

- (instancetype)initWithcomponentRegistry:(RNNReactComponentRegistry *)componentRegistry {
- (instancetype)initWithComponentRegistry:(RNNReactComponentRegistry *)componentRegistry {
self = [super init];
self.componentRegistry = componentRegistry;
return self;
}

- (void)bindViewController:(UIViewController *)bindedViewController {
- (void)bindViewController:(UIViewController<RNNLayoutProtocol> *)bindedViewController {
self.bindedComponentId = bindedViewController.layoutInfo.componentId;
_bindedViewController = bindedViewController;
}

Expand Down
2 changes: 1 addition & 1 deletion lib/ios/RNNBridgeManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge {

- (void)onJavaScriptWillLoad {
[_store clean];
[_componentRegistry clean];
[_componentRegistry clear];
}

- (void)onJavaScriptLoaded {
Expand Down
4 changes: 2 additions & 2 deletions lib/ios/RNNControllerFactory.m
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ - (instancetype)initWithRootViewCreator:(id <RNNRootViewCreator>)creator
- (UIViewController<RNNParentProtocol> *)createComponent:(RNNLayoutNode*)node {
RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] initWithNode:node];
RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:node.data[@"options"]];;
RNNViewControllerPresenter* presenter = [[RNNViewControllerPresenter alloc] initWithcomponentRegistry:_componentRegistry];
RNNViewControllerPresenter* presenter = [[RNNViewControllerPresenter alloc] initWithComponentRegistry:_componentRegistry];

RNNRootViewController* component = [[RNNRootViewController alloc] initWithLayoutInfo:layoutInfo rootViewCreator:_creator eventEmitter:_eventEmitter presenter:presenter options:options defaultOptions:_defaultOptions];

Expand All @@ -137,7 +137,7 @@ - (instancetype)initWithRootViewCreator:(id <RNNRootViewCreator>)creator


- (UIViewController<RNNParentProtocol> *)createStack:(RNNLayoutNode*)node {
RNNNavigationControllerPresenter* presenter = [[RNNNavigationControllerPresenter alloc] initWithcomponentRegistry:_componentRegistry];
RNNNavigationControllerPresenter* presenter = [[RNNNavigationControllerPresenter alloc] initWithComponentRegistry:_componentRegistry];
RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] initWithNode:node];
RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:node.data[@"options"]];;

Expand Down
2 changes: 1 addition & 1 deletion lib/ios/RNNNavigationControllerPresenter.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

@property (nonatomic, strong) InteractivePopGestureDelegate *interactivePopGestureDelegate;

- (instancetype)initWithcomponentRegistry:(RNNReactComponentRegistry *)componentRegistry;
- (instancetype)initWithComponentRegistry:(RNNReactComponentRegistry *)componentRegistry;

- (void)applyOptionsBeforePopping:(RNNNavigationOptions *)options;

Expand Down
21 changes: 11 additions & 10 deletions lib/ios/RNNNavigationControllerPresenter.m
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,12 @@ @interface RNNNavigationControllerPresenter() {
@end
@implementation RNNNavigationControllerPresenter

- (instancetype)initWithcomponentRegistry:(RNNReactComponentRegistry *)componentRegistry {
- (instancetype)initWithComponentRegistry:(RNNReactComponentRegistry *)componentRegistry {
self = [super init];
_componentRegistry = componentRegistry;
return self;
}

- (void)bindViewController:(UIViewController *)bindedViewController {
self.bindedViewController = bindedViewController;
}

- (void)applyOptions:(RNNNavigationOptions *)options {
[super applyOptions:options];

Expand Down Expand Up @@ -179,7 +175,8 @@ - (void)setCustomNavigationBarView:(RNNNavigationOptions *)options perform:(RNNR
readyBlock = nil;
}
if (options.topBar.component.name.hasValue) {
RCTRootView *reactView = [_componentRegistry createComponentIfNotExists:options.topBar.component parentComponentId:navigationController.layoutInfo.componentId reactViewReadyBlock:readyBlock];
NSString* currentChildComponentId = [navigationController getCurrentChild].layoutInfo.componentId;
RCTRootView *reactView = [_componentRegistry createComponentIfNotExists:options.topBar.component parentComponentId:currentChildComponentId reactViewReadyBlock:readyBlock];

if (_customTopBar) {
[_customTopBar removeFromSuperview];
Expand All @@ -190,6 +187,7 @@ - (void)setCustomNavigationBarView:(RNNNavigationOptions *)options perform:(RNNR
[navigationController.navigationBar addSubview:_customTopBar];
} else {
[_customTopBar removeFromSuperview];
_customTopBar = nil;
if (readyBlock) {
readyBlock();
}
Expand All @@ -203,24 +201,27 @@ - (void)setCustomNavigationComponentBackground:(RNNNavigationOptions *)options p
readyBlock = nil;
}
if (options.topBar.background.component.name.hasValue) {
RCTRootView *reactView = [_componentRegistry createComponentIfNotExists:options.topBar.background.component parentComponentId:navigationController.layoutInfo.componentId reactViewReadyBlock:readyBlock];
NSString* currentChildComponentId = [navigationController getCurrentChild].layoutInfo.componentId;
RCTRootView *reactView = [_componentRegistry createComponentIfNotExists:options.topBar.background.component parentComponentId:currentChildComponentId reactViewReadyBlock:readyBlock];

if (_customTopBarBackground) {
[_customTopBarBackground removeFromSuperview];
}
_customTopBarBackground = [[RNNCustomTitleView alloc] initWithFrame:navigationController.navigationBar.bounds subView:reactView alignment:@"fill"];
RNNCustomTitleView* customTopBarBackground = [[RNNCustomTitleView alloc] initWithFrame:navigationController.navigationBar.bounds subView:reactView alignment:@"fill"];
_customTopBarBackground = customTopBarBackground;

[navigationController.navigationBar insertSubview:_customTopBarBackground atIndex:1];
} else {
[_customTopBarBackground removeFromSuperview];
_customTopBarBackground = nil;
if (readyBlock) {
readyBlock();
}
}
}

- (void)dealloc {
RNNNavigationController* navigationController = self.bindedViewController;
[_componentRegistry removeComponent:navigationController.layoutInfo.componentId];
[_componentRegistry removeComponent:self.bindedComponentId];
}

@end
4 changes: 3 additions & 1 deletion lib/ios/RNNReactComponentRegistry.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

- (void)removeComponent:(NSString *)componentId;

- (void)clean;
- (void)clearComponentsForParentId:(NSString *)parentComponentId;

- (void)clear;

@end
8 changes: 6 additions & 2 deletions lib/ios/RNNReactComponentRegistry.m
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ @implementation RNNReactComponentRegistry
- (instancetype)initWithCreator:(id<RNNRootViewCreator>)creator {
self = [super init];
_creator = creator;
_componentStore = [NSMapTable strongToWeakObjectsMapTable];
_componentStore = [NSMapTable new];
return self;
}

Expand All @@ -38,13 +38,17 @@ - (NSMutableDictionary *)componentsForParentId:(NSString *)parentComponentId {
return [_componentStore objectForKey:parentComponentId];;
}

- (void)clearComponentsForParentId:(NSString *)parentComponentId {
[_componentStore removeObjectForKey:parentComponentId];;
}

- (void)removeComponent:(NSString *)componentId {
if ([_componentStore objectForKey:componentId]) {
[_componentStore removeObjectForKey:componentId];
}
}

- (void)clean {
- (void)clear {
[_componentStore removeAllObjects];
}

Expand Down
4 changes: 2 additions & 2 deletions lib/ios/RNNReactView.m
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ - (void)contentDidAppear:(NSNotification *)notification {
}

- (void)setRootViewDidChangeIntrinsicSize:(void (^)(CGSize))rootViewDidChangeIntrinsicSize {
_rootViewDidChangeIntrinsicSize = rootViewDidChangeIntrinsicSize;
self.delegate = self;
_rootViewDidChangeIntrinsicSize = rootViewDidChangeIntrinsicSize;
self.delegate = self;
}

- (void)rootViewDidChangeIntrinsicSize:(RCTRootView *)rootView {
Expand Down
4 changes: 0 additions & 4 deletions lib/ios/RNNSplitViewControllerPresenter.m
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@

@implementation RNNSplitViewControllerPresenter

- (void)bindViewController:(UISplitViewController *)bindedViewController viewCreator:(id<RNNRootViewCreator>)creator {
self.bindedViewController = bindedViewController;
}

- (void)applyOptions:(RNNNavigationOptions *)options {
[super applyOptions:options];

Expand Down
1 change: 1 addition & 0 deletions lib/ios/RNNTopBarOptions.m
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ - (instancetype)initWithDict:(NSDictionary *)dict {
self.backButton = [[RNNBackButtonOptions alloc] initWithDict:dict[@"backButton"]];
self.leftButtonStyle = [[RNNButtonOptions alloc] initWithDict:dict[@"leftButtonStyle"]];
self.rightButtonStyle = [[RNNButtonOptions alloc] initWithDict:dict[@"rightButtonStyle"]];
self.component = [[RNNComponentOptions alloc] initWithDict:dict[@"component"]];

if (self.leftButtonColor.hasValue) {
self.leftButtonStyle.color = self.leftButtonColor;
Expand Down
2 changes: 1 addition & 1 deletion lib/ios/RNNViewControllerPresenter.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

@interface RNNViewControllerPresenter : RNNBasePresenter

- (instancetype)initWithcomponentRegistry:(RNNReactComponentRegistry *)componentRegistry;
- (instancetype)initWithComponentRegistry:(RNNReactComponentRegistry *)componentRegistry;

- (void)renderComponents:(RNNNavigationOptions *)options perform:(RNNReactViewReadyCompletionBlock)readyBlock;

Expand Down
13 changes: 9 additions & 4 deletions lib/ios/RNNViewControllerPresenter.m
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ - (instancetype)init {
return self;
}

- (instancetype)initWithcomponentRegistry:(RNNReactComponentRegistry *)componentRegistry {
- (instancetype)initWithComponentRegistry:(RNNReactComponentRegistry *)componentRegistry {
self = [self init];
_componentRegistry = componentRegistry;
return self;
}

- (void)bindViewController:(UIViewController *)bindedViewController {
self.bindedViewController = bindedViewController;
- (void)bindViewController:(UIViewController<RNNLayoutProtocol> *)bindedViewController {
[super bindViewController:bindedViewController];
_navigationButtons = [[RNNNavigationButtons alloc] initWithViewController:self.bindedViewController componentRegistry:_componentRegistry];
}

Expand Down Expand Up @@ -175,12 +175,13 @@ - (void)setCustomNavigationTitleView:(RNNNavigationOptions *)options perform:(RN
if (options.topBar.title.component.name.hasValue) {
_customTitleView = (RNNReactView*)[_componentRegistry createComponentIfNotExists:options.topBar.title.component parentComponentId:viewController.layoutInfo.componentId reactViewReadyBlock:readyBlock];
_customTitleView.backgroundColor = UIColor.clearColor;

NSString* alignment = [options.topBar.title.component.alignment getWithDefaultValue:@""];
[_customTitleView setAlignment:alignment];

BOOL isCenter = [alignment isEqualToString:@"center"];
__weak RNNReactView *weakTitleView = _customTitleView;
CGRect frame = viewController.navigationController.navigationBar.bounds;
[_customTitleView setFrame:frame];
[_customTitleView setRootViewDidChangeIntrinsicSize:^(CGSize intrinsicContentSize) {
if (isCenter) {
[weakTitleView setFrame:CGRectMake(0, 0, intrinsicContentSize.width, intrinsicContentSize.height)];
Expand Down Expand Up @@ -214,6 +215,10 @@ - (void)setTitleViewWithSubtitle:(RNNNavigationOptions *)options {
}
}

- (void)dealloc {
[_componentRegistry clearComponentsForParentId:self.bindedComponentId];
}

- (void)cleanReactLeftovers {
_customTitleView = nil;
}
Expand Down
5 changes: 3 additions & 2 deletions lib/ios/ReactNativeNavigationTests/RNNBasePresenterTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
#import "RNNBasePresenter.h"
#import <OCMock/OCMock.h>
#import "UIViewController+RNNOptions.h"
#import "RNNRootViewController.h"

@interface RNNBottomTabPresenterTest : XCTestCase

@property (nonatomic, strong) RNNBasePresenter *uut;
@property (nonatomic, strong) RNNNavigationOptions *options;
@property (nonatomic, strong) UIViewController* bindedViewController;
@property (nonatomic, strong) RNNRootViewController* bindedViewController;
@property (nonatomic, strong) id mockBindedViewController;

@end
Expand All @@ -17,7 +18,7 @@ @implementation RNNBottomTabPresenterTest
- (void)setUp {
[super setUp];
self.uut = [[RNNBasePresenter alloc] init];
self.bindedViewController = [UIViewController new];
self.bindedViewController = [RNNRootViewController new];
self.mockBindedViewController = [OCMockObject partialMockForObject:self.bindedViewController];
[self.uut bindViewController:self.mockBindedViewController];
self.options = [[RNNNavigationOptions alloc] initEmptyOptions];
Expand Down
3 changes: 2 additions & 1 deletion lib/ios/ReactNativeNavigationTests/RNNTabBarPresenterTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#import <OCMock/OCMock.h>
#import "RNNTabBarPresenter.h"
#import "UITabBarController+RNNOptions.h"
#import "RNNTabBarController.h"

@interface RNNTabBarPresenterTest : XCTestCase

Expand All @@ -16,7 +17,7 @@ @implementation RNNTabBarPresenterTest
- (void)setUp {
[super setUp];
self.uut = [[RNNTabBarPresenter alloc] init];
self.bindedViewController = [OCMockObject partialMockForObject:[UITabBarController new]];
self.bindedViewController = [OCMockObject partialMockForObject:[RNNTabBarController new]];
[self.uut bindViewController:self.bindedViewController];
self.options = [[RNNNavigationOptions alloc] initEmptyOptions];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@ @interface RNNViewControllerPresenterTest : XCTestCase
@property (nonatomic, strong) RNNViewControllerPresenter *uut;
@property (nonatomic, strong) RNNNavigationOptions *options;
@property (nonatomic, strong) UIViewController *bindedViewController;
@property (nonatomic, strong) RNNReactComponentRegistry *componentRegistry;

@end

@implementation RNNViewControllerPresenterTest

- (void)setUp {
[super setUp];
self.uut = [[RNNViewControllerPresenter alloc] init];
self.componentRegistry = [OCMockObject partialMockForObject:[RNNReactComponentRegistry new]];
self.uut = [[RNNViewControllerPresenter alloc] initWithComponentRegistry:self.componentRegistry];
self.bindedViewController = [OCMockObject partialMockForObject:[RNNRootViewController new]];
[self.uut bindViewController:self.bindedViewController];
self.options = [[RNNNavigationOptions alloc] initEmptyOptions];
Expand Down Expand Up @@ -132,5 +134,51 @@ -(void)testApplyOptionsOnInit_BottomTabsDrawUnder_false {
[(id)self.bindedViewController verify];
}

- (void)testReactViewShouldBeReleasedOnDealloc {
RNNRootViewController* bindViewController = [RNNRootViewController new];
bindViewController.layoutInfo = [self createLayoutInfoWithComponentId:@"componentId"];
[self.uut bindViewController:bindViewController];

self.options.topBar.title.component = [[RNNComponentOptions alloc] initWithDict:@{@"name": @"componentName"}];

[[(id)self.componentRegistry expect] clearComponentsForParentId:self.uut.bindedComponentId];
self.uut = nil;
[(id)self.componentRegistry verify];
}

- (void)testBindViewControllerShouldSetBindedComponentId {
RNNRootViewController* bindViewController = [RNNRootViewController new];
RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] init];
layoutInfo.componentId = @"componentId";
bindViewController.layoutInfo = layoutInfo;

[self.uut bindViewController:bindViewController];
XCTAssertEqual(self.uut.bindedComponentId, @"componentId");
}

- (void)testRenderComponentsCreateReactViewWithBindedComponentId {
RNNRootViewController* bindedViewController = [RNNRootViewController new];
RNNLayoutInfo* layoutInfo = [self createLayoutInfoWithComponentId:@"componentId"];
bindedViewController.layoutInfo = layoutInfo;

[self.uut bindViewController:bindedViewController];

self.options.topBar.title.component = [[RNNComponentOptions alloc] initWithDict:@{@"name": @"titleComponent"}];

[[(id)self.componentRegistry expect] createComponentIfNotExists:self.options.topBar.title.component parentComponentId:self.uut.bindedComponentId reactViewReadyBlock:[OCMArg any]];
[self.uut renderComponents:self.options perform:nil];
[(id)self.componentRegistry verify];


XCTAssertEqual(self.uut.bindedComponentId, @"componentId");
}



- (RNNLayoutInfo *)createLayoutInfoWithComponentId:(NSString *)componentId {
RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] init];
layoutInfo.componentId = @"componentId";
return layoutInfo;
}

@end

0 comments on commit ac60d2f

Please sign in to comment.