Browse Source

refactored custom component to use creator (#2887)

yogevbd 6 years ago
parent
commit
4dfb43e9ce
No account linked to committer's email address

+ 2
- 0
lib/ios/RNNBridgeManager.h View File

@@ -5,6 +5,8 @@
5 5
 
6 6
 - (instancetype)initWithJsCodeLocation:(NSURL *)jsCodeLocation launchOptions:(NSDictionary *)launchOptions;
7 7
 
8
+- (void)registerExternalComponent:(NSString *)name callback:(UIViewController *(^)(void))callback;
9
+
8 10
 @property (readonly, nonatomic, strong) RCTBridge *bridge;
9 11
 
10 12
 @end

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

@@ -49,6 +49,10 @@
49 49
 	return self;
50 50
 }
51 51
 
52
+- (void)registerExternalComponent:(NSString *)name callback:(RNNExternalViewCreator)callback {
53
+	[_store registerExternalComponent:name callback:callback];
54
+}
55
+
52 56
 # pragma mark - RCTBridgeDelegate
53 57
 
54 58
 - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge {

+ 23
- 4
lib/ios/RNNControllerFactory.m View File

@@ -44,7 +44,7 @@
44 44
 	UIViewController<RNNRootViewProtocol> *result;
45 45
 	
46 46
 	if (node.isComponent) {
47
-		result = [self createComponent:node nativeComponent:NO];
47
+		result = [self createComponent:node];
48 48
 	}
49 49
 	
50 50
 	else if (node.isStack)	{
@@ -76,7 +76,7 @@
76 76
 	}
77 77
 	
78 78
 	else if (node.isExternalComponent) {
79
-		result = [self createComponent:node nativeComponent:YES];
79
+		result = [self createExternalComponent:node];
80 80
 	}
81 81
 	
82 82
 	if (!result) {
@@ -88,13 +88,13 @@
88 88
 	return result;
89 89
 }
90 90
 
91
-- (UIViewController<RNNRootViewProtocol> *)createComponent:(RNNLayoutNode*)node nativeComponent:(BOOL)nativeComponent {
91
+- (UIViewController<RNNRootViewProtocol> *)createComponent:(RNNLayoutNode*)node {
92 92
 	NSString* name = node.data[@"name"];
93 93
 	RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:_defaultOptionsDict];
94 94
 	[options mergeWith:node.data[@"options"]];
95 95
 
96 96
 	NSString* componentId = node.nodeId;
97
-	RNNRootViewController* component = [[RNNRootViewController alloc] initWithName:name withOptions:options withComponentId:componentId rootViewCreator:_creator eventEmitter:_eventEmitter isExternalComponent:nativeComponent];
97
+	RNNRootViewController* component = [[RNNRootViewController alloc] initWithName:name withOptions:options withComponentId:componentId rootViewCreator:_creator eventEmitter:_eventEmitter isExternalComponent:NO];
98 98
 	if (!component.isCustomViewController) {
99 99
 		CGSize availableSize = UIApplication.sharedApplication.delegate.window.bounds.size;
100 100
 		[_bridge.uiManager setAvailableSize:availableSize forRootView:component.view];
@@ -102,6 +102,25 @@
102 102
 	return component;
103 103
 }
104 104
 
105
+- (UIViewController<RNNRootViewProtocol> *)createExternalComponent:(RNNLayoutNode*)node {
106
+	NSString* name = node.data[@"name"];
107
+	
108
+	UIViewController* externalVC = [_store getExternalComponent:name];
109
+	RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:_defaultOptionsDict];
110
+	[options mergeWith:node.data[@"options"]];
111
+	
112
+	NSString* componentId = node.nodeId;
113
+	RNNRootViewController* component = [[RNNRootViewController alloc] initWithName:name withOptions:options withComponentId:componentId rootViewCreator:_creator eventEmitter:_eventEmitter isExternalComponent:YES];
114
+	
115
+	[component addChildViewController:externalVC];
116
+	component.view = [[UIView alloc] init];
117
+	component.view.backgroundColor = [UIColor whiteColor];
118
+	[component.view addSubview:externalVC.view];
119
+	
120
+	return component;
121
+}
122
+
123
+
105 124
 - (UIViewController<RNNRootViewProtocol> *)createStack:(RNNLayoutNode*)node {
106 125
 	RNNNavigationController* vc = [[RNNNavigationController alloc] init];
107 126
 	NSDictionary* options = node.data[@"options"];

+ 1
- 24
lib/ios/RNNRootViewController.m View File

@@ -28,9 +28,7 @@
28 28
 	self.creator = creator;
29 29
 	self.isExternalComponent = isExternalComponent;
30 30
 	
31
-	if (self.isExternalComponent) {
32
-		[self addExternalVC:name];
33
-	} else {
31
+	if (!self.isExternalComponent) {
34 32
 		self.view = [creator createRootView:self.componentName rootViewId:self.componentId];
35 33
 	}
36 34
 	
@@ -164,27 +162,6 @@
164 162
 	[self.options.topTab applyOn:self];
165 163
 }
166 164
 
167
--(void)addExternalVC:(NSString*)className {
168
-	if (className != nil) {
169
-		Class class = NSClassFromString(className);
170
-		if (class != NULL) {
171
-			id obj = [[class alloc] init];
172
-			if (obj != nil && [obj isKindOfClass:[UIViewController class]]) {
173
-				UIViewController *viewController = (UIViewController*)obj;
174
-				[self addChildViewController:viewController];
175
-				self.view = [[UIView alloc] init];
176
-				self.view.backgroundColor = [UIColor whiteColor];
177
-				[self.view addSubview:viewController.view];
178
-			}
179
-			else {
180
-				NSLog(@"addExternalVC: could not create instance. Make sure that your class is a UIViewController whihc confirms to RCCExternalViewControllerProtocol");
181
-			}
182
-		}
183
-		else {
184
-			NSLog(@"addExternalVC: could not create class from string. Check that the proper class name wass passed in ExternalNativeScreenClass");
185
-		}
186
-	}
187
-}
188 165
 
189 166
 /**
190 167
  *	fix for #877, #878

+ 4
- 0
lib/ios/RNNStore.h View File

@@ -4,6 +4,7 @@
4 4
 #import "RNNRootViewController.h"
5 5
 
6 6
 typedef void (^RNNTransitionCompletionBlock)(void);
7
+typedef UIViewController * (^RNNExternalViewCreator)(void);
7 8
 
8 9
 @interface RNNStore : NSObject
9 10
 
@@ -12,6 +13,9 @@ typedef void (^RNNTransitionCompletionBlock)(void);
12 13
 -(void) removeComponent:(NSString*)componentId;
13 14
 -(void) removeComponentByViewControllerInstance:(UIViewController*)componentInstance;
14 15
 
16
+- (void)registerExternalComponent:(NSString *)name callback:(RNNExternalViewCreator)callback;
17
+- (UIViewController *)getExternalComponent:(NSString *)name;
18
+
15 19
 -(NSString*)componentKeyForInstance:(UIViewController*)instance;
16 20
 
17 21
 -(void) setReadyToReceiveCommands:(BOOL)isReady;

+ 11
- 0
lib/ios/RNNStore.m View File

@@ -8,6 +8,7 @@
8 8
 @implementation RNNStore {
9 9
 	NSMapTable* _componentStore;
10 10
 	NSMutableArray* _pendingModalIdsToDismiss;
11
+	NSMutableDictionary* _externalComponentCreators;
11 12
 	BOOL _isReadyToReceiveCommands;
12 13
 }
13 14
 
@@ -16,6 +17,7 @@
16 17
 	_isReadyToReceiveCommands = false;
17 18
 	_componentStore = [NSMapTable strongToWeakObjectsMapTable];
18 19
 	_pendingModalIdsToDismiss = [NSMutableArray new];
20
+	_externalComponentCreators = [NSMutableDictionary new];
19 21
 	return self;
20 22
 }
21 23
 
@@ -71,4 +73,13 @@
71 73
 	return nil;
72 74
 }
73 75
 
76
+- (void)registerExternalComponent:(NSString *)name callback:(RNNExternalViewCreator)callback {
77
+	[_externalComponentCreators setObject:[callback copy] forKey:name];
78
+}
79
+
80
+- (UIViewController *)getExternalComponent:(NSString *)name {
81
+	RNNExternalViewCreator creator = [_externalComponentCreators objectForKey:name];
82
+	return creator();
83
+}
84
+
74 85
 @end

+ 5
- 0
lib/ios/ReactNativeNavigation.h View File

@@ -1,7 +1,12 @@
1 1
 #import <Foundation/Foundation.h>
2
+#import <UIKit/UIKit.h>
3
+
4
+typedef UIViewController * (^RNNExternalViewCreator)(void);
2 5
 
3 6
 @interface ReactNativeNavigation : NSObject
4 7
 
5 8
 +(void)bootstrap:(NSURL*)jsCodeLocation launchOptions:(NSDictionary *)launchOptions;
6 9
 
10
++ (void)registerExternalComponent:(NSString *)name callback:(RNNExternalViewCreator)callback;
11
+
7 12
 @end

+ 4
- 1
lib/ios/ReactNativeNavigation.m View File

@@ -1,6 +1,5 @@
1 1
 #import "ReactNativeNavigation.h"
2 2
 
3
-#import <UIKit/UIKit.h>
4 3
 #import <React/RCTBridge.h>
5 4
 #import <React/RCTUIManager.h>
6 5
 
@@ -21,6 +20,10 @@
21 20
 	[[ReactNativeNavigation sharedInstance] bootstrap:jsCodeLocation launchOptions:launchOptions];
22 21
 }
23 22
 
23
++ (void)registerExternalComponent:(NSString *)name callback:(RNNExternalViewCreator)callback {
24
+	[[ReactNativeNavigation sharedInstance].bridgeManager registerExternalComponent:name callback:callback];
25
+}
26
+
24 27
 # pragma mark - instance
25 28
 
26 29
 + (instancetype) sharedInstance {

+ 5
- 0
playground/ios/playground/AppDelegate.m View File

@@ -1,4 +1,5 @@
1 1
 #import "AppDelegate.h"
2
+#import "RNNCustomViewController.h"
2 3
 
3 4
 // **********************************************
4 5
 // *** DON'T MISS: THE NEXT LINE IS IMPORTANT ***
@@ -21,6 +22,10 @@
21 22
 	NSURL *jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];
22 23
 	[ReactNativeNavigation bootstrap:jsCodeLocation launchOptions:launchOptions];
23 24
 	
25
+	[ReactNativeNavigation registerExternalComponent:@"RNNCustomComponent" callback:^UIViewController *{
26
+		return [[RNNCustomViewController alloc] init];
27
+	}];
28
+	
24 29
 	/*
25 30
 	// original RN bootstrap - remove this part
26 31
 	RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation