Daniel Zlotin 6 years ago
parent
commit
d8056195aa

+ 1
- 1
docs/README.md View File

1
 [![npm (tag)](https://img.shields.io/npm/v/react-native-navigation/alpha.svg)](https://github.com/wix/react-native-navigation/tree/v2#react-native-navigation-v2-wip)
1
 [![npm (tag)](https://img.shields.io/npm/v/react-native-navigation/alpha.svg)](https://github.com/wix/react-native-navigation/tree/v2#react-native-navigation-v2-wip)
2
 [![Build Status](https://travis-ci.org/wix/react-native-navigation.svg?branch=v2)](https://travis-ci.org/wix/react-native-navigation)
2
 [![Build Status](https://travis-ci.org/wix/react-native-navigation.svg?branch=v2)](https://travis-ci.org/wix/react-native-navigation)
3
-[![Build Status Jenkins](http://34.201.210.182/job/react-native-navigation/job/v2/badge/icon)](http://34.201.210.182/job/react-native-navigation/job/v2)
3
+[![Build Status](http://34.201.210.182/buildStatus/icon?job=react-native-navigation-merge)](http://34.201.210.182/job/react-native-navigation-merge/)
4
 [![Join us on Discord](https://img.shields.io/badge/discord-react--native--navigation-738bd7.svg?style=flat)](https://discord.gg/DhkZjq2)
4
 [![Join us on Discord](https://img.shields.io/badge/discord-react--native--navigation-738bd7.svg?style=flat)](https://discord.gg/DhkZjq2)
5
 [![StackExchange](https://img.shields.io/stackexchange/stackoverflow/t/react-native-navigation.svg)](https://stackoverflow.com/questions/tagged/react-native-navigation)
5
 [![StackExchange](https://img.shields.io/stackexchange/stackoverflow/t/react-native-navigation.svg)](https://stackoverflow.com/questions/tagged/react-native-navigation)
6
 
6
 

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

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

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

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

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

44
 	UIViewController<RNNRootViewProtocol> *result;
44
 	UIViewController<RNNRootViewProtocol> *result;
45
 	
45
 	
46
 	if (node.isComponent) {
46
 	if (node.isComponent) {
47
-		result = [self createComponent:node nativeComponent:NO];
47
+		result = [self createComponent:node];
48
 	}
48
 	}
49
 	
49
 	
50
 	else if (node.isStack)	{
50
 	else if (node.isStack)	{
76
 	}
76
 	}
77
 	
77
 	
78
 	else if (node.isExternalComponent) {
78
 	else if (node.isExternalComponent) {
79
-		result = [self createComponent:node nativeComponent:YES];
79
+		result = [self createExternalComponent:node];
80
 	}
80
 	}
81
 	
81
 	
82
 	if (!result) {
82
 	if (!result) {
88
 	return result;
88
 	return result;
89
 }
89
 }
90
 
90
 
91
-- (UIViewController<RNNRootViewProtocol> *)createComponent:(RNNLayoutNode*)node nativeComponent:(BOOL)nativeComponent {
91
+- (UIViewController<RNNRootViewProtocol> *)createComponent:(RNNLayoutNode*)node {
92
 	NSString* name = node.data[@"name"];
92
 	NSString* name = node.data[@"name"];
93
 	RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:_defaultOptionsDict];
93
 	RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:_defaultOptionsDict];
94
 	[options mergeWith:node.data[@"options"]];
94
 	[options mergeWith:node.data[@"options"]];
95
 
95
 
96
 	NSString* componentId = node.nodeId;
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
 	if (!component.isCustomViewController) {
98
 	if (!component.isCustomViewController) {
99
 		CGSize availableSize = UIApplication.sharedApplication.delegate.window.bounds.size;
99
 		CGSize availableSize = UIApplication.sharedApplication.delegate.window.bounds.size;
100
 		[_bridge.uiManager setAvailableSize:availableSize forRootView:component.view];
100
 		[_bridge.uiManager setAvailableSize:availableSize forRootView:component.view];
102
 	return component;
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
 - (UIViewController<RNNRootViewProtocol> *)createStack:(RNNLayoutNode*)node {
124
 - (UIViewController<RNNRootViewProtocol> *)createStack:(RNNLayoutNode*)node {
106
 	RNNNavigationController* vc = [[RNNNavigationController alloc] init];
125
 	RNNNavigationController* vc = [[RNNNavigationController alloc] init];
107
 	NSDictionary* options = node.data[@"options"];
126
 	NSDictionary* options = node.data[@"options"];

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

28
 	self.creator = creator;
28
 	self.creator = creator;
29
 	self.isExternalComponent = isExternalComponent;
29
 	self.isExternalComponent = isExternalComponent;
30
 	
30
 	
31
-	if (self.isExternalComponent) {
32
-		[self addExternalVC:name];
33
-	} else {
31
+	if (!self.isExternalComponent) {
34
 		self.view = [creator createRootView:self.componentName rootViewId:self.componentId];
32
 		self.view = [creator createRootView:self.componentName rootViewId:self.componentId];
35
 	}
33
 	}
36
 	
34
 	
164
 	[self.options.topTab applyOn:self];
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
  *	fix for #877, #878
167
  *	fix for #877, #878

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

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

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

8
 @implementation RNNStore {
8
 @implementation RNNStore {
9
 	NSMapTable* _componentStore;
9
 	NSMapTable* _componentStore;
10
 	NSMutableArray* _pendingModalIdsToDismiss;
10
 	NSMutableArray* _pendingModalIdsToDismiss;
11
+	NSMutableDictionary* _externalComponentCreators;
11
 	BOOL _isReadyToReceiveCommands;
12
 	BOOL _isReadyToReceiveCommands;
12
 }
13
 }
13
 
14
 
16
 	_isReadyToReceiveCommands = false;
17
 	_isReadyToReceiveCommands = false;
17
 	_componentStore = [NSMapTable strongToWeakObjectsMapTable];
18
 	_componentStore = [NSMapTable strongToWeakObjectsMapTable];
18
 	_pendingModalIdsToDismiss = [NSMutableArray new];
19
 	_pendingModalIdsToDismiss = [NSMutableArray new];
20
+	_externalComponentCreators = [NSMutableDictionary new];
19
 	return self;
21
 	return self;
20
 }
22
 }
21
 
23
 
71
 	return nil;
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
 @end
85
 @end

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

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

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

1
 #import "ReactNativeNavigation.h"
1
 #import "ReactNativeNavigation.h"
2
 
2
 
3
-#import <UIKit/UIKit.h>
4
 #import <React/RCTBridge.h>
3
 #import <React/RCTBridge.h>
5
 #import <React/RCTUIManager.h>
4
 #import <React/RCTUIManager.h>
6
 
5
 
21
 	[[ReactNativeNavigation sharedInstance] bootstrap:jsCodeLocation launchOptions:launchOptions];
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
 # pragma mark - instance
27
 # pragma mark - instance
25
 
28
 
26
 + (instancetype) sharedInstance {
29
 + (instancetype) sharedInstance {

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

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