Daniel Zlotin 7 years ago
parent
commit
cd95e7ef64

+ 12
- 7
ios/RNNBridgeModule.m View File

@@ -1,6 +1,7 @@
1 1
 #import "RNNBridgeModule.h"
2 2
 #import "RNNStore.h"
3
-#import "RCTRootView.h"
3
+
4
+#import "RNNControllerFactory.h"
4 5
 
5 6
 @implementation RNNBridgeModule
6 7
 
@@ -13,13 +14,17 @@ RCT_EXPORT_MODULE(NativeNavigation);
13 14
 
14 15
 RCT_EXPORT_METHOD(startApp:(NSDictionary*)layout)
15 16
 {
16
-    RCTRootView *reactView = [[RCTRootView alloc] initWithBridge:RNNStore.sharedInstance.bridge moduleName:@"com.example.WelcomeScreen" initialProperties:@[@{@"containerId": @"123"}]];
17
+    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
18
+        
19
+        RCTBridge* bridge = RNNStore.sharedInstance.bridge;
20
+        
21
+        RNNStore.appDelegate.window.rootViewController = [RNNControllerFactory createRootViewController:layout];
22
+        [RNNStore.appDelegate.window makeKeyAndVisible];
23
+    });
24
+    
25
+    
17 26
     
18
-    UIViewController* controller = [UIViewController new];
19
-    controller.view = reactView;
20
-
21
-    RNNStore.appDelegate.window.rootViewController = controller;
22
-    [RNNStore.appDelegate.window makeKeyAndVisible];
23 27
 }
24 28
 
25 29
 @end
30
+

+ 7
- 0
ios/RNNCommandsHandler.h View File

@@ -0,0 +1,7 @@
1
+
2
+#import <Foundation/Foundation.h>
3
+
4
+@interface RNNCommandsHandler : NSObject
5
+
6
+
7
+@end

+ 6
- 0
ios/RNNCommandsHandler.m View File

@@ -0,0 +1,6 @@
1
+
2
+#import "RNNCommandsHandler.h"
3
+
4
+@implementation RNNCommandsHandler
5
+
6
+@end

+ 9
- 0
ios/RNNControllerFactory.h View File

@@ -0,0 +1,9 @@
1
+
2
+#import <Foundation/Foundation.h>
3
+#import <UIKit/UIKit.h>
4
+
5
+@interface RNNControllerFactory : NSObject
6
+
7
++(UIViewController*)createRootViewController:(NSDictionary*)layout;
8
+
9
+@end

+ 21
- 0
ios/RNNControllerFactory.m View File

@@ -0,0 +1,21 @@
1
+
2
+#import "RNNControllerFactory.h"
3
+
4
+#import "RNNStore.h"
5
+#import "RCTRootView.h"
6
+
7
+@implementation RNNControllerFactory
8
+
9
++(UIViewController *)createRootViewController:(NSDictionary *)layout
10
+{
11
+    NSString* containerName = layout[@"container"][@"name"];
12
+    NSString* containerId = layout[@"container"][@"id"];
13
+    
14
+    RCTRootView *reactView = [[RCTRootView alloc] initWithBridge:RNNStore.sharedInstance.bridge moduleName:containerName initialProperties:@{@"containerId": containerId}];
15
+    
16
+    UIViewController* controller = [UIViewController new];
17
+    controller.view = reactView;
18
+    return controller;
19
+}
20
+
21
+@end

+ 1
- 1
ios/RNNSplashScreen.h View File

@@ -2,6 +2,6 @@
2 2
 
3 3
 @interface RNNSplashScreen : NSObject
4 4
 
5
--(void)showSplashScreen;
5
++(void)showSplashScreenWhileLoadingJS;
6 6
 
7 7
 @end

+ 1
- 2
ios/RNNSplashScreen.m View File

@@ -4,7 +4,7 @@
4 4
 
5 5
 @implementation RNNSplashScreen
6 6
 
7
--(void)showSplashScreen
7
++(void)showSplashScreenWhileLoadingJS
8 8
 {
9 9
     CGRect screenBounds = [UIScreen mainScreen].bounds;
10 10
     UIView *splashView = nil;
@@ -70,7 +70,6 @@
70 70
         appDelegate.window.rootViewController = splashVC;
71 71
         [appDelegate.window makeKeyAndVisible];
72 72
     }
73
-    
74 73
 }
75 74
 
76 75
 @end

+ 10
- 4
ios/ReactNativeNavigation.m View File

@@ -2,6 +2,8 @@
2 2
 #import "ReactNativeNavigation.h"
3 3
 #import "RNNStore.h"
4 4
 #import "RCTBridge.h"
5
+#import "RNNSplashScreen.h"
6
+#import "RCTRootView.h";
5 7
 
6 8
 @implementation ReactNativeNavigation
7 9
 
@@ -12,11 +14,15 @@
12 14
 
13 15
 +(void)bootstrap:(NSURL *)jsCodeLocation launchOptions:(NSDictionary *)launchOptions
14 16
 {
15
-    RNNStore.appDelegate.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
16
-    RNNStore.appDelegate.window.backgroundColor = [UIColor whiteColor];
17 17
     
18
-    RCTBridge* bridge = [[RCTBridge alloc] initWithBundleURL:jsCodeLocation moduleProvider:nil launchOptions:launchOptions];
19
-    RNNStore.sharedInstance.bridge = bridge;
18
+        RNNStore.appDelegate.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
19
+        RNNStore.appDelegate.window.backgroundColor = [UIColor whiteColor];
20
+        
21
+        [RNNSplashScreen showSplashScreenWhileLoadingJS];
22
+        
23
+        RNNStore.sharedInstance.bridge = [[RCTBridge alloc] initWithBundleURL:jsCodeLocation moduleProvider:nil launchOptions:launchOptions];
24
+        
25
+    
20 26
 }
21 27
 
22 28
 @end

+ 12
- 0
ios/ReactNativeNavigation.xcodeproj/project.pbxproj View File

@@ -17,6 +17,8 @@
17 17
 		7BA500781E254908001B9E1B /* RNNSplashScreen.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BA500771E254908001B9E1B /* RNNSplashScreen.m */; };
18 18
 		7BBFE5441E25330E002A6182 /* RNNBridgeModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BBFE5431E25330E002A6182 /* RNNBridgeModule.m */; };
19 19
 		7BBFE5611E253F97002A6182 /* RNNStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BBFE5601E253F97002A6182 /* RNNStore.m */; };
20
+		7BC9346B1E267BAD00EFA125 /* RNNCommandsHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BC9346A1E267BAD00EFA125 /* RNNCommandsHandler.m */; };
21
+		7BC9346E1E26886E00EFA125 /* RNNControllerFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BC9346D1E26886E00EFA125 /* RNNControllerFactory.m */; };
20 22
 		CC84A19E1C1A0C4E00B3A6A2 /* RCCManager.m in Sources */ = {isa = PBXBuildFile; fileRef = CC84A1941C1A0C4E00B3A6A2 /* RCCManager.m */; };
21 23
 		CC84A19F1C1A0C4E00B3A6A2 /* RCCManagerModule.m in Sources */ = {isa = PBXBuildFile; fileRef = CC84A1961C1A0C4E00B3A6A2 /* RCCManagerModule.m */; };
22 24
 		CC84A1A01C1A0C4E00B3A6A2 /* RCCNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC84A1981C1A0C4E00B3A6A2 /* RCCNavigationController.m */; };
@@ -76,6 +78,10 @@
76 78
 		7BBFE5431E25330E002A6182 /* RNNBridgeModule.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNNBridgeModule.m; sourceTree = "<group>"; };
77 79
 		7BBFE55F1E253F97002A6182 /* RNNStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNNStore.h; sourceTree = "<group>"; };
78 80
 		7BBFE5601E253F97002A6182 /* RNNStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNNStore.m; sourceTree = "<group>"; };
81
+		7BC934691E267BAD00EFA125 /* RNNCommandsHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNNCommandsHandler.h; sourceTree = "<group>"; };
82
+		7BC9346A1E267BAD00EFA125 /* RNNCommandsHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNNCommandsHandler.m; sourceTree = "<group>"; };
83
+		7BC9346C1E26886E00EFA125 /* RNNControllerFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNNControllerFactory.h; sourceTree = "<group>"; };
84
+		7BC9346D1E26886E00EFA125 /* RNNControllerFactory.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNNControllerFactory.m; sourceTree = "<group>"; };
79 85
 		CC84A1931C1A0C4E00B3A6A2 /* RCCManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCCManager.h; sourceTree = "<group>"; };
80 86
 		CC84A1941C1A0C4E00B3A6A2 /* RCCManager.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.objc; path = RCCManager.m; sourceTree = "<group>"; tabWidth = 2; };
81 87
 		CC84A1951C1A0C4E00B3A6A2 /* RCCManagerModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCCManagerModule.h; sourceTree = "<group>"; };
@@ -251,6 +257,10 @@
251 257
 		D8AFADB41BEE6F3F00A4592D = {
252 258
 			isa = PBXGroup;
253 259
 			children = (
260
+				7BC9346C1E26886E00EFA125 /* RNNControllerFactory.h */,
261
+				7BC9346D1E26886E00EFA125 /* RNNControllerFactory.m */,
262
+				7BC934691E267BAD00EFA125 /* RNNCommandsHandler.h */,
263
+				7BC9346A1E267BAD00EFA125 /* RNNCommandsHandler.m */,
254 264
 				7BA500731E2544B9001B9E1B /* ReactNativeNavigation.h */,
255 265
 				7BA500741E2544B9001B9E1B /* ReactNativeNavigation.m */,
256 266
 				7BA500761E254908001B9E1B /* RNNSplashScreen.h */,
@@ -355,6 +365,7 @@
355 365
 				D85082FC1CBCF8A800FDB961 /* MMDrawerBarButtonItem.m in Sources */,
356 366
 				D85083001CBCF8A800FDB961 /* UIViewController+MMDrawerController.m in Sources */,
357 367
 				D85082FF1CBCF8A800FDB961 /* MMExampleDrawerVisualStateManager.m in Sources */,
368
+				7BC9346B1E267BAD00EFA125 /* RNNCommandsHandler.m in Sources */,
358 369
 				D85082E61CBCF54200FDB961 /* SidebarFeedlyAnimation.m in Sources */,
359 370
 				CC84A1A11C1A0C4E00B3A6A2 /* RCCTabBarController.m in Sources */,
360 371
 				D85082E71CBCF54200FDB961 /* SidebarFlipboardAnimation.m in Sources */,
@@ -369,6 +380,7 @@
369 380
 				D85082FE1CBCF8A800FDB961 /* MMDrawerVisualState.m in Sources */,
370 381
 				7BBFE5611E253F97002A6182 /* RNNStore.m in Sources */,
371 382
 				D85082FD1CBCF8A800FDB961 /* MMDrawerController.m in Sources */,
383
+				7BC9346E1E26886E00EFA125 /* RNNControllerFactory.m in Sources */,
372 384
 				D85082E41CBCF54200FDB961 /* SidebarAnimation.m in Sources */,
373 385
 				D8E11C571CBD1F670018B644 /* RCCDrawerController.m in Sources */,
374 386
 				2636176F1E12722900D88A13 /* RNNTabBarController.m in Sources */,

+ 2
- 1
playground/e2e/app.test.js View File

@@ -3,7 +3,8 @@ describe('app', () => {
3 3
     global.simulator.relaunchApp(done);
4 4
   });
5 5
 
6
-  it('shows welcome screen', () => {
6
+  it('shows welcome screen', (done) => {
7 7
     expect(element(by.label('React Native Navigation!'))).toBeVisible();
8
+    done();
8 9
   });
9 10
 });

+ 28
- 24
playground/ios/playground.xcodeproj/project.pbxproj View File

@@ -7,24 +7,25 @@
7 7
 	objects = {
8 8
 
9 9
 /* Begin PBXBuildFile section */
10
-		00C302E51ABCBA2D00DB3ED1 /* ReferenceProxy in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; };
11
-		00C302E71ABCBA2D00DB3ED1 /* ReferenceProxy in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; };
12
-		00C302E81ABCBA2D00DB3ED1 /* ReferenceProxy in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */; };
13
-		00C302E91ABCBA2D00DB3ED1 /* ReferenceProxy in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */; };
14
-		00C302EA1ABCBA2D00DB3ED1 /* ReferenceProxy in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */; };
10
+		00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; };
11
+		00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; };
12
+		00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */; };
13
+		00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */; };
14
+		00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */; };
15 15
 		00E356F31AD99517003FC87E /* playgroundTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* playgroundTests.m */; };
16
-		133E29F31AD74F7200F7D852 /* ReferenceProxy in Frameworks */ = {isa = PBXBuildFile; fileRef = 78C398B91ACF4ADC00677621 /* libRCTLinking.a */; };
17
-		139105C61AF99C1200B5F7CC /* ReferenceProxy in Frameworks */ = {isa = PBXBuildFile; fileRef = 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */; };
18
-		139FDEF61B0652A700C62182 /* ReferenceProxy in Frameworks */ = {isa = PBXBuildFile; fileRef = 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */; };
16
+		133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 78C398B91ACF4ADC00677621 /* libRCTLinking.a */; };
17
+		139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */; };
18
+		139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */; };
19 19
 		13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
20 20
 		13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; };
21 21
 		13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
22 22
 		13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
23
-		146834051AC3E58100842450 /* ReferenceProxy in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; };
23
+		146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; };
24 24
 		2636F1CD1E11309B007ABB09 /* RNNViewControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2636F1CC1E11309B007ABB09 /* RNNViewControllerTests.m */; };
25
-		2647D65F1DB175C200B23722 /* ReferenceProxy in Frameworks */ = {isa = PBXBuildFile; fileRef = 2647D65E1DB175B300B23722 /* libReactNativeNavigation.a */; };
26
-		7B9B39861DEB4091004A6281 /* ReferenceProxy in Frameworks */ = {isa = PBXBuildFile; fileRef = 7B9B39631DEB4076004A6281 /* libRCTAnimation.a */; };
27
-		832341BD1AAA6AB300B99B32 /* ReferenceProxy in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; };
25
+		2647D65F1DB175C200B23722 /* libReactNativeNavigation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2647D65E1DB175B300B23722 /* libReactNativeNavigation.a */; };
26
+		7B9B39861DEB4091004A6281 /* libRCTAnimation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7B9B39631DEB4076004A6281 /* libRCTAnimation.a */; };
27
+		7BC934871E268CF600EFA125 /* RNNControllerFactoryTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BC934861E268CF600EFA125 /* RNNControllerFactoryTest.m */; };
28
+		832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; };
28 29
 /* End PBXBuildFile section */
29 30
 
30 31
 /* Begin PBXContainerItemProxy section */
@@ -200,6 +201,7 @@
200 201
 		2647D6591DB175B300B23722 /* ReactNativeNavigation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ReactNativeNavigation.xcodeproj; path = "../node_modules/react-native-navigation/ios/ReactNativeNavigation.xcodeproj"; sourceTree = "<group>"; };
201 202
 		78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = "<group>"; };
202 203
 		7B9B395C1DEB4076004A6281 /* RCTAnimation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTAnimation.xcodeproj; path = "../node_modules/react-native/Libraries/NativeAnimation/RCTAnimation.xcodeproj"; sourceTree = "<group>"; };
204
+		7BC934861E268CF600EFA125 /* RNNControllerFactoryTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNNControllerFactoryTest.m; sourceTree = "<group>"; };
203 205
 		832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = "<group>"; };
204 206
 /* End PBXFileReference section */
205 207
 
@@ -215,18 +217,18 @@
215 217
 			isa = PBXFrameworksBuildPhase;
216 218
 			buildActionMask = 2147483647;
217 219
 			files = (
218
-				7B9B39861DEB4091004A6281 /* ReferenceProxy in Frameworks */,
219
-				2647D65F1DB175C200B23722 /* ReferenceProxy in Frameworks */,
220
-				146834051AC3E58100842450 /* ReferenceProxy in Frameworks */,
221
-				00C302E51ABCBA2D00DB3ED1 /* ReferenceProxy in Frameworks */,
222
-				00C302E71ABCBA2D00DB3ED1 /* ReferenceProxy in Frameworks */,
223
-				00C302E81ABCBA2D00DB3ED1 /* ReferenceProxy in Frameworks */,
224
-				133E29F31AD74F7200F7D852 /* ReferenceProxy in Frameworks */,
225
-				00C302E91ABCBA2D00DB3ED1 /* ReferenceProxy in Frameworks */,
226
-				139105C61AF99C1200B5F7CC /* ReferenceProxy in Frameworks */,
227
-				832341BD1AAA6AB300B99B32 /* ReferenceProxy in Frameworks */,
228
-				00C302EA1ABCBA2D00DB3ED1 /* ReferenceProxy in Frameworks */,
229
-				139FDEF61B0652A700C62182 /* ReferenceProxy in Frameworks */,
220
+				7B9B39861DEB4091004A6281 /* libRCTAnimation.a in Frameworks */,
221
+				2647D65F1DB175C200B23722 /* libReactNativeNavigation.a in Frameworks */,
222
+				146834051AC3E58100842450 /* libReact.a in Frameworks */,
223
+				00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */,
224
+				00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */,
225
+				00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */,
226
+				133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */,
227
+				00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */,
228
+				139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */,
229
+				832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */,
230
+				00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */,
231
+				139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */,
230 232
 			);
231 233
 			runOnlyForDeploymentPostprocessing = 0;
232 234
 		};
@@ -280,6 +282,7 @@
280 282
 			children = (
281 283
 				00E356F21AD99517003FC87E /* playgroundTests.m */,
282 284
 				2636F1CC1E11309B007ABB09 /* RNNViewControllerTests.m */,
285
+				7BC934861E268CF600EFA125 /* RNNControllerFactoryTest.m */,
283 286
 				00E356F01AD99517003FC87E /* Supporting Files */,
284 287
 			);
285 288
 			path = playgroundTests;
@@ -735,6 +738,7 @@
735 738
 			files = (
736 739
 				00E356F31AD99517003FC87E /* playgroundTests.m in Sources */,
737 740
 				2636F1CD1E11309B007ABB09 /* RNNViewControllerTests.m in Sources */,
741
+				7BC934871E268CF600EFA125 /* RNNControllerFactoryTest.m in Sources */,
738 742
 			);
739 743
 			runOnlyForDeploymentPostprocessing = 0;
740 744
 		};

+ 32
- 0
playground/ios/playgroundTests/RNNControllerFactoryTest.m View File

@@ -0,0 +1,32 @@
1
+
2
+#import <XCTest/XCTest.h>
3
+#import "RNNControllerFactory.h"
4
+#import "RCTRootView.h"
5
+
6
+@interface RNNControllerFactoryTest : XCTestCase
7
+
8
+@end
9
+
10
+@implementation RNNControllerFactoryTest
11
+
12
+- (void)setUp {
13
+    [super setUp];
14
+    // Put setup code here. This method is called before the invocation of each test method in the class.
15
+}
16
+
17
+- (void)tearDown {
18
+    [super tearDown];
19
+}
20
+
21
+- (void)testExample {
22
+  NSDictionary* layout = @{
23
+                           @"container": @{
24
+                               @"name": @"myName",
25
+                               @"id": @"my-id"
26
+                               }
27
+                           };
28
+  UIViewController* rootViewController = [RNNControllerFactory createRootViewController:layout];
29
+  XCTAssert([((RCTRootView*)rootViewController.view).moduleName isEqualToString:@"myName"]);
30
+}
31
+
32
+@end

+ 112
- 112
playground/ios/playgroundTests/RNNViewControllerTests.m View File

@@ -1,114 +1,114 @@
1
+////
2
+////  RNNViewControllerTests.m
3
+////
4
+////  Created by Ran Greenberg on 26/12/2016.
5
+////  Copyright © 2016 Facebook. All rights reserved.
6
+////
1 7
 //
2
-//  RNNViewControllerTests.m
3
-//
4
-//  Created by Ran Greenberg on 26/12/2016.
5
-//  Copyright © 2016 Facebook. All rights reserved.
6
-//
7
-
8
-#import <XCTest/XCTest.h>
9
-#import "RCCManager.h"
10
-#import "RNNViewController.h"
11
-#import "MMDrawerController.h"
12
-
13
-#define COMMAND_SINGLE_SCREEN_APP               @"singleScreenApp"
14
-#define COMMAND_TAB_BASED_APP                   @"tabBasedApp"
15
-#define COMMAND_SINGLE_WITH_LEFT_SIDE_MENU      @"singleWithLeftSideMenu"
16
-#define COMMAND_SINGLE_WITH_RIGHT_SIDE_MENU     @"singleWithRightSideMenu"
17
-#define COMMAND_SINGLE_WITH_BOTH_SIDE_MENU      @"singleWithBothMenus"
18
-#define COMMAND_TAB_BASED_WITH_SIDE_MENT        @"tabBasedWithSideMenu"
19
-
20
-
21
-@interface RNNViewControllerTests : XCTestCase
22
-@property (nonatomic, strong) RCTBridge *bridge;
23
-@property (nonatomic, strong) NSDictionary *jsonCommands;
24
-@end
25
-
26
-@implementation RNNViewControllerTests
27
-
28
-- (void)setUp {
29
-  [super setUp];
30
-  // Put setup code here. This method is called before the invocation of each test method in the class.
31
-  self.bridge = [[RCCManager sharedInstance] getBridge];
32
-  self.jsonCommands = [self loadCommandsJsonAsDictionary];
33
-}
34
-
35
-- (void)tearDown {
36
-  // Put teardown code here. This method is called after the invocation of each test method in the class.
37
-  self.bridge = nil;
38
-  self.jsonCommands = nil;
39
-  [super tearDown];
40
-}
41
-
42
--(NSDictionary*)loadCommandsJsonAsDictionary {
43
-  NSString *filePath = [[NSBundle mainBundle] pathForResource:@"commands" ofType:@"json"];
44
-  NSData *data = [NSData dataWithContentsOfFile:filePath];
45
-  NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
46
-  return json;
47
-}
48
-
49
-- (void)testWrongSyntax {
50
-  
51
-  NSDictionary *layout = @{@"key": @"com.example.FirstTabScreen"};
52
-  id vc = [RNNViewController controllerWithLayout:layout bridge:self.bridge];
53
-  XCTAssertNil(vc);
54
-}
55
-
56
--(void)testSingleScreenApp {
57
-  id vc = [RNNViewController controllerWithLayout:self.jsonCommands[COMMAND_SINGLE_SCREEN_APP] bridge:self.bridge];
58
-  XCTAssertTrue([vc isKindOfClass:[UINavigationController class]]);
59
-}
60
-
61
--(void)testTabBasedApp {
62
-  id vc = [RNNViewController controllerWithLayout:self.jsonCommands[COMMAND_TAB_BASED_APP] bridge:self.bridge];
63
-  XCTAssertTrue([vc isKindOfClass:[UITabBarController class]]);
64
-  UITabBarController *tabsController = (UITabBarController*)vc;
65
-  for (id tab in tabsController.viewControllers) {
66
-    XCTAssertTrue([tab isKindOfClass:[UINavigationController class]]);
67
-  }
68
-}
69
-
70
--(void)testSingleWithLeftSideMenu {
71
-  id vc = [RNNViewController controllerWithLayout:self.jsonCommands[COMMAND_SINGLE_WITH_LEFT_SIDE_MENU] bridge:self.bridge];
72
-  XCTAssertTrue([vc isKindOfClass:[MMDrawerController class]]);
73
-  MMDrawerController *sideMenuLeft = (MMDrawerController*)vc;
74
-  XCTAssertNotNil(sideMenuLeft.leftDrawerViewController);
75
-  XCTAssertNotNil(sideMenuLeft.centerViewController);
76
-  XCTAssertNil(sideMenuLeft.rightDrawerViewController);
77
-}
78
-
79
--(void)testSingleWithRightSideMenu {
80
-  id vc = [RNNViewController controllerWithLayout:self.jsonCommands[COMMAND_SINGLE_WITH_RIGHT_SIDE_MENU] bridge:self.bridge];
81
-  XCTAssertTrue([vc isKindOfClass:[MMDrawerController class]]);
82
-  MMDrawerController *sideMenuRight = (MMDrawerController*)vc;
83
-  XCTAssertNil(sideMenuRight.leftDrawerViewController);
84
-  XCTAssertNotNil(sideMenuRight.centerViewController);
85
-  XCTAssertNotNil(sideMenuRight.rightDrawerViewController);
86
-
87
-}
88
-
89
--(void)testSingleWithBothSideMenu {
90
-  id vc = [RNNViewController controllerWithLayout:self.jsonCommands[COMMAND_SINGLE_WITH_BOTH_SIDE_MENU] bridge:self.bridge];
91
-  XCTAssertTrue([vc isKindOfClass:[MMDrawerController class]]);
92
-  MMDrawerController *sideMenuBoth = (MMDrawerController*)vc;
93
-  XCTAssertNotNil(sideMenuBoth.leftDrawerViewController);
94
-  XCTAssertNotNil(sideMenuBoth.centerViewController);
95
-  XCTAssertNotNil(sideMenuBoth.rightDrawerViewController);
96
-}
97
-
98
--(void)testTabBasedWithBothSideMenu {
99
-  id vc = [RNNViewController controllerWithLayout:self.jsonCommands[COMMAND_TAB_BASED_WITH_SIDE_MENT] bridge:self.bridge];
100
-  XCTAssertTrue([vc isKindOfClass:[MMDrawerController class]]);
101
-  MMDrawerController *sideMenuBothWithTabs = (MMDrawerController*)vc;
102
-  XCTAssertNotNil(sideMenuBothWithTabs.leftDrawerViewController);
103
-  XCTAssertNotNil(sideMenuBothWithTabs.centerViewController);
104
-  XCTAssertNotNil(sideMenuBothWithTabs.rightDrawerViewController);
105
-  XCTAssertTrue([sideMenuBothWithTabs.centerViewController isKindOfClass:[UITabBarController class]]);
106
-}
107
-//- (void)testPerformanceExample {
108
-//  // This is an example of a performance test case.
109
-//  [self measureBlock:^{
110
-//    // Put the code you want to measure the time of here.
111
-//  }];
8
+//#import <XCTest/XCTest.h>
9
+//#import "RCCManager.h"
10
+//#import "RNNViewController.h"
11
+//#import "MMDrawerController.h"
12
+//
13
+//#define COMMAND_SINGLE_SCREEN_APP               @"singleScreenApp"
14
+//#define COMMAND_TAB_BASED_APP                   @"tabBasedApp"
15
+//#define COMMAND_SINGLE_WITH_LEFT_SIDE_MENU      @"singleWithLeftSideMenu"
16
+//#define COMMAND_SINGLE_WITH_RIGHT_SIDE_MENU     @"singleWithRightSideMenu"
17
+//#define COMMAND_SINGLE_WITH_BOTH_SIDE_MENU      @"singleWithBothMenus"
18
+//#define COMMAND_TAB_BASED_WITH_SIDE_MENT        @"tabBasedWithSideMenu"
19
+//
20
+//
21
+//@interface RNNViewControllerTests : XCTestCase
22
+//@property (nonatomic, strong) RCTBridge *bridge;
23
+//@property (nonatomic, strong) NSDictionary *jsonCommands;
24
+//@end
25
+//
26
+//@implementation RNNViewControllerTests
27
+//
28
+//- (void)setUp {
29
+//  [super setUp];
30
+//  // Put setup code here. This method is called before the invocation of each test method in the class.
31
+//  self.bridge = [[RCCManager sharedInstance] getBridge];
32
+//  self.jsonCommands = [self loadCommandsJsonAsDictionary];
33
+//}
34
+//
35
+//- (void)tearDown {
36
+//  // Put teardown code here. This method is called after the invocation of each test method in the class.
37
+//  self.bridge = nil;
38
+//  self.jsonCommands = nil;
39
+//  [super tearDown];
40
+//}
41
+//
42
+//-(NSDictionary*)loadCommandsJsonAsDictionary {
43
+//  NSString *filePath = [[NSBundle mainBundle] pathForResource:@"commands" ofType:@"json"];
44
+//  NSData *data = [NSData dataWithContentsOfFile:filePath];
45
+//  NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
46
+//  return json;
47
+//}
48
+//
49
+//- (void)testWrongSyntax {
50
+//  
51
+//  NSDictionary *layout = @{@"key": @"com.example.FirstTabScreen"};
52
+//  id vc = [RNNViewController controllerWithLayout:layout bridge:self.bridge];
53
+//  XCTAssertNil(vc);
54
+//}
55
+//
56
+//-(void)testSingleScreenApp {
57
+//  id vc = [RNNViewController controllerWithLayout:self.jsonCommands[COMMAND_SINGLE_SCREEN_APP] bridge:self.bridge];
58
+//  XCTAssertTrue([vc isKindOfClass:[UINavigationController class]]);
112 59
 //}
113
-
114
-@end
60
+//
61
+//-(void)testTabBasedApp {
62
+//  id vc = [RNNViewController controllerWithLayout:self.jsonCommands[COMMAND_TAB_BASED_APP] bridge:self.bridge];
63
+//  XCTAssertTrue([vc isKindOfClass:[UITabBarController class]]);
64
+//  UITabBarController *tabsController = (UITabBarController*)vc;
65
+//  for (id tab in tabsController.viewControllers) {
66
+//    XCTAssertTrue([tab isKindOfClass:[UINavigationController class]]);
67
+//  }
68
+//}
69
+//
70
+//-(void)testSingleWithLeftSideMenu {
71
+//  id vc = [RNNViewController controllerWithLayout:self.jsonCommands[COMMAND_SINGLE_WITH_LEFT_SIDE_MENU] bridge:self.bridge];
72
+//  XCTAssertTrue([vc isKindOfClass:[MMDrawerController class]]);
73
+//  MMDrawerController *sideMenuLeft = (MMDrawerController*)vc;
74
+//  XCTAssertNotNil(sideMenuLeft.leftDrawerViewController);
75
+//  XCTAssertNotNil(sideMenuLeft.centerViewController);
76
+//  XCTAssertNil(sideMenuLeft.rightDrawerViewController);
77
+//}
78
+//
79
+//-(void)testSingleWithRightSideMenu {
80
+//  id vc = [RNNViewController controllerWithLayout:self.jsonCommands[COMMAND_SINGLE_WITH_RIGHT_SIDE_MENU] bridge:self.bridge];
81
+//  XCTAssertTrue([vc isKindOfClass:[MMDrawerController class]]);
82
+//  MMDrawerController *sideMenuRight = (MMDrawerController*)vc;
83
+//  XCTAssertNil(sideMenuRight.leftDrawerViewController);
84
+//  XCTAssertNotNil(sideMenuRight.centerViewController);
85
+//  XCTAssertNotNil(sideMenuRight.rightDrawerViewController);
86
+//
87
+//}
88
+//
89
+//-(void)testSingleWithBothSideMenu {
90
+//  id vc = [RNNViewController controllerWithLayout:self.jsonCommands[COMMAND_SINGLE_WITH_BOTH_SIDE_MENU] bridge:self.bridge];
91
+//  XCTAssertTrue([vc isKindOfClass:[MMDrawerController class]]);
92
+//  MMDrawerController *sideMenuBoth = (MMDrawerController*)vc;
93
+//  XCTAssertNotNil(sideMenuBoth.leftDrawerViewController);
94
+//  XCTAssertNotNil(sideMenuBoth.centerViewController);
95
+//  XCTAssertNotNil(sideMenuBoth.rightDrawerViewController);
96
+//}
97
+//
98
+//-(void)testTabBasedWithBothSideMenu {
99
+//  id vc = [RNNViewController controllerWithLayout:self.jsonCommands[COMMAND_TAB_BASED_WITH_SIDE_MENT] bridge:self.bridge];
100
+//  XCTAssertTrue([vc isKindOfClass:[MMDrawerController class]]);
101
+//  MMDrawerController *sideMenuBothWithTabs = (MMDrawerController*)vc;
102
+//  XCTAssertNotNil(sideMenuBothWithTabs.leftDrawerViewController);
103
+//  XCTAssertNotNil(sideMenuBothWithTabs.centerViewController);
104
+//  XCTAssertNotNil(sideMenuBothWithTabs.rightDrawerViewController);
105
+//  XCTAssertTrue([sideMenuBothWithTabs.centerViewController isKindOfClass:[UITabBarController class]]);
106
+//}
107
+////- (void)testPerformanceExample {
108
+////  // This is an example of a performance test case.
109
+////  [self measureBlock:^{
110
+////    // Put the code you want to measure the time of here.
111
+////  }];
112
+////}
113
+//
114
+//@end

+ 1
- 1
playground/package.json View File

@@ -24,7 +24,7 @@
24 24
       "sessionId": "playground"
25 25
     },
26 26
     "ios-simulator": {
27
-      "app": "ios/DerivedData/playground/Build/Products/Release_Detox-iphonesimulator/playground.app",
27
+      "app": "ios/DerivedData/playground/Build/Products/Debug_Detox-iphonesimulator/playground.app",
28 28
       "device": "iPhone 7, iOS 10.2"
29 29
     }
30 30
   },

+ 5
- 4
playground/scripts/e2e.ios.js View File

@@ -15,10 +15,11 @@ function kill(process) {
15 15
 function buildProjForDetox() {
16 16
   exec(`RCT_NO_LAUNCH_PACKAGER=true \
17 17
           cd ios && xcodebuild \
18
-            -scheme playground_release_Detox build \
18
+            -scheme playground_Detox build \
19 19
             -project playground.xcodeproj \
20 20
             -sdk iphonesimulator \
21
-            -derivedDataPath ./DerivedData/playground`);
21
+            -derivedDataPath ./DerivedData/playground \
22
+            GCC_PREPROCESSOR_DEFINITIONS="DEBUG=1 RCT_DEBUG=1 RCT_DEV=1 RCT_NSASSERT=1"`);
22 23
 }
23 24
 
24 25
 function e2e() {
@@ -28,8 +29,8 @@ function e2e() {
28 29
     exec(`BABEL_ENV=test ./node_modules/mocha/bin/mocha e2e --recursive --compilers js:babel-register`);
29 30
   } finally {
30 31
     kill(`detox-server`);
31
-    kill(`Simulator`);
32
-    kill(`CoreSimulator`);
32
+    //kill(`Simulator`);
33
+    //kill(`CoreSimulator`);
33 34
     exec(`cat ./detox-server.log`);
34 35
     exec(`rm -f ./detox-server.log`);
35 36
     exec(`sleep 5`);

+ 1
- 1
playground/src/app.js View File

@@ -31,7 +31,7 @@ export function start() {
31 31
   Navigation.registerContainer(`com.example.WelcomeScreen`, () => WelcomeScreen);
32 32
   Navigation.startApp({
33 33
     container: {
34
-      key: 'com.example.WelcomeScreen'
34
+      name: 'com.example.WelcomeScreen'
35 35
     }
36 36
   });
37 37
 }

+ 2
- 2
src/Navigation.js View File

@@ -1,8 +1,8 @@
1 1
 import * as ContainerRegistry from './containers/ContainerRegistry';
2 2
 import * as Commands from './commands/Commands';
3 3
 
4
-export function registerContainer(containerKey, getContainerFunc) {
5
-  ContainerRegistry.registerContainer(containerKey, getContainerFunc);
4
+export function registerContainer(containerName, getContainerFunc) {
5
+  ContainerRegistry.registerContainer(containerName, getContainerFunc);
6 6
 }
7 7
 
8 8
 export function startApp(params) {

+ 2
- 2
src/Navigation.test.js View File

@@ -33,9 +33,9 @@ describe('Navigation', () => {
33 33
   it('registerContainer delegates to ContainerRegistry', () => {
34 34
     expect(ContainerRegistry.registerContainer).not.toHaveBeenCalled();
35 35
     const fn = jest.fn();
36
-    Navigation.registerContainer('key', fn);
36
+    Navigation.registerContainer('name', fn);
37 37
     expect(ContainerRegistry.registerContainer).toHaveBeenCalledTimes(1);
38
-    expect(ContainerRegistry.registerContainer).toHaveBeenCalledWith('key', fn);
38
+    expect(ContainerRegistry.registerContainer).toHaveBeenCalledWith('name', fn);
39 39
   });
40 40
 
41 41
   it('startApp delegates to Commands', () => {

+ 1
- 1
src/commands/Commands.test.js View File

@@ -14,7 +14,7 @@ describe('Commands', () => {
14 14
     it('sends startApp to native', () => {
15 15
       uut.startApp({
16 16
         container: {
17
-          key: 'com.example.MyScreen'
17
+          name: 'com.example.MyScreen'
18 18
         }
19 19
       });
20 20
       expect(mockNativeNavigation.startApp).toHaveBeenCalledTimes(1);

+ 18
- 18
src/commands/LayoutBuilder.test.js View File

@@ -16,11 +16,11 @@ describe('LayoutBuilder', () => {
16 16
     it('adds uniqueId to passed container', () => {
17 17
       expect(LayoutBuilder.parse({
18 18
         container: {
19
-          key: 'com.example.MyScreen'
19
+          name: 'com.example.MyScreen'
20 20
         }
21 21
       })).toEqual({
22 22
         container: {
23
-          key: 'com.example.MyScreen',
23
+          name: 'com.example.MyScreen',
24 24
           id: 'containerUNIQUE'
25 25
         }
26 26
       });
@@ -29,28 +29,28 @@ describe('LayoutBuilder', () => {
29 29
     it('adds uniqueId to passed sideMenu', () => {
30 30
       expect(LayoutBuilder.parse({
31 31
         container: {
32
-          key: 'com.example.MyScreen'
32
+          name: 'com.example.MyScreen'
33 33
         },
34 34
         sideMenu: {
35 35
           left: {
36
-            key: 'com.example.SideMenu1'
36
+            name: 'com.example.SideMenu1'
37 37
           },
38 38
           right: {
39
-            key: 'com.example.SideMenu2'
39
+            name: 'com.example.SideMenu2'
40 40
           }
41 41
         }
42 42
       })).toEqual({
43 43
         container: {
44
-          key: 'com.example.MyScreen',
44
+          name: 'com.example.MyScreen',
45 45
           id: 'containerUNIQUE'
46 46
         },
47 47
         sideMenu: {
48 48
           left: {
49
-            key: 'com.example.SideMenu1',
49
+            name: 'com.example.SideMenu1',
50 50
             id: 'containerUNIQUE'
51 51
           },
52 52
           right: {
53
-            key: 'com.example.SideMenu2',
53
+            name: 'com.example.SideMenu2',
54 54
             id: 'containerUNIQUE'
55 55
           }
56 56
         }
@@ -62,56 +62,56 @@ describe('LayoutBuilder', () => {
62 62
         tabs: [
63 63
           {
64 64
             container: {
65
-              key: 'com.example.FirstTab'
65
+              name: 'com.example.FirstTab'
66 66
             }
67 67
           },
68 68
           {
69 69
             container: {
70
-              key: 'com.example.SecondTab'
70
+              name: 'com.example.SecondTab'
71 71
             }
72 72
           },
73 73
           {
74 74
             container: {
75
-              key: 'com.example.FirstTab'
75
+              name: 'com.example.FirstTab'
76 76
             }
77 77
           }
78 78
         ],
79 79
         sideMenu: {
80 80
           left: {
81
-            key: 'com.example.Menu1'
81
+            name: 'com.example.Menu1'
82 82
           },
83 83
           right: {
84
-            key: 'com.example.Menu2'
84
+            name: 'com.example.Menu2'
85 85
           }
86 86
         }
87 87
       })).toEqual({
88 88
         tabs: [
89 89
           {
90 90
             container: {
91
-              key: 'com.example.FirstTab',
91
+              name: 'com.example.FirstTab',
92 92
               id: 'containerUNIQUE'
93 93
             }
94 94
           },
95 95
           {
96 96
             container: {
97
-              key: 'com.example.SecondTab',
97
+              name: 'com.example.SecondTab',
98 98
               id: 'containerUNIQUE'
99 99
             }
100 100
           },
101 101
           {
102 102
             container: {
103
-              key: 'com.example.FirstTab',
103
+              name: 'com.example.FirstTab',
104 104
               id: 'containerUNIQUE'
105 105
             }
106 106
           }
107 107
         ],
108 108
         sideMenu: {
109 109
           left: {
110
-            key: 'com.example.Menu1',
110
+            name: 'com.example.Menu1',
111 111
             id: 'containerUNIQUE'
112 112
           },
113 113
           right: {
114
-            key: 'com.example.Menu2',
114
+            name: 'com.example.Menu2',
115 115
             id: 'containerUNIQUE'
116 116
           }
117 117
         }

+ 18
- 16
src/commands/ValidCommands.js View File

@@ -1,6 +1,6 @@
1 1
 export const singleScreenApp = {
2 2
   container: {
3
-    key: 'com.example.MyScreen'
3
+    name: 'com.example.MyScreen'
4 4
   }
5 5
 };
6 6
 
@@ -8,17 +8,17 @@ export const tabBasedApp = {
8 8
   tabs: [
9 9
     {
10 10
       container: {
11
-        key: 'com.example.FirstTab'
11
+        name: 'com.example.FirstTab'
12 12
       }
13 13
     },
14 14
     {
15 15
       container: {
16
-        key: 'com.example.SecondTab'
16
+        name: 'com.example.SecondTab'
17 17
       }
18 18
     },
19 19
     {
20 20
       container: {
21
-        key: 'com.example.FirstTab'
21
+        name: 'com.example.FirstTab'
22 22
       }
23 23
     }
24 24
   ]
@@ -26,36 +26,38 @@ export const tabBasedApp = {
26 26
 
27 27
 export const singleWithSideMenu = {
28 28
   container: {
29
-    key: 'com.example.MyScreen'
29
+    name: 'com.example.MyScreen'
30 30
   },
31 31
   sideMenu: {
32 32
     left: {
33
-      key: 'com.example.Menu'
33
+      container: {
34
+        name: 'com.example.MyScreen'
35
+      }
34 36
     }
35 37
   }
36 38
 };
37 39
 
38 40
 export const singleWithRightSideMenu = {
39 41
   container: {
40
-    key: 'com.example.MyScreen'
42
+    name: 'com.example.MyScreen'
41 43
   },
42 44
   sideMenu: {
43 45
     right: {
44
-      key: 'com.example.Menu'
46
+      name: 'com.example.Menu'
45 47
     }
46 48
   }
47 49
 };
48 50
 
49 51
 export const singleWithBothMenus = {
50 52
   container: {
51
-    key: 'com.example.MyScreen'
53
+    name: 'com.example.MyScreen'
52 54
   },
53 55
   sideMenu: {
54 56
     left: {
55
-      key: 'com.example.Menu1'
57
+      name: 'com.example.Menu1'
56 58
     },
57 59
     right: {
58
-      key: 'com.example.Menu2'
60
+      name: 'com.example.Menu2'
59 61
     }
60 62
   }
61 63
 };
@@ -64,26 +66,26 @@ export const tabBasedWithSideMenu = {
64 66
   tabs: [
65 67
     {
66 68
       container: {
67
-        key: 'com.example.FirstTab'
69
+        name: 'com.example.FirstTab'
68 70
       }
69 71
     },
70 72
     {
71 73
       container: {
72
-        key: 'com.example.SecondTab'
74
+        name: 'com.example.SecondTab'
73 75
       }
74 76
     },
75 77
     {
76 78
       container: {
77
-        key: 'com.example.FirstTab'
79
+        name: 'com.example.FirstTab'
78 80
       }
79 81
     }
80 82
   ],
81 83
   sideMenu: {
82 84
     left: {
83
-      key: 'com.example.Menu1'
85
+      name: 'com.example.Menu1'
84 86
     },
85 87
     right: {
86
-      key: 'com.example.Menu2'
88
+      name: 'com.example.Menu2'
87 89
     }
88 90
   }
89 91
 };

+ 6
- 6
src/containers/ContainerRegistry.js View File

@@ -2,19 +2,19 @@ import React, {Component} from 'react';
2 2
 import {AppRegistry} from 'react-native';
3 3
 import * as Store from './Store';
4 4
 
5
-export function registerContainer(containerKey, getContainerFunc) {
5
+export function registerContainer(containerName, getContainerFunc) {
6 6
   const OriginalContainer = getContainerFunc();
7
-  const NavigationContainer = wrapContainer(containerKey, OriginalContainer);
8
-  Store.setContainerClass(containerKey, NavigationContainer);
9
-  AppRegistry.registerComponent(containerKey, () => NavigationContainer);
7
+  const NavigationContainer = wrapContainer(containerName, OriginalContainer);
8
+  Store.setContainerClass(containerName, NavigationContainer);
9
+  AppRegistry.registerComponent(containerName, () => NavigationContainer);
10 10
 }
11 11
 
12
-function wrapContainer(containerKey, OriginalContainer) {
12
+function wrapContainer(containerName, OriginalContainer) {
13 13
   return class extends Component {
14 14
     constructor(props) {
15 15
       super(props);
16 16
       if (!props.containerId) {
17
-        throw new Error(`Container ${containerKey} does not have a containerId!`);
17
+        throw new Error(`Container ${containerName} does not have a containerId!`);
18 18
       }
19 19
       this.state = {
20 20
         containerId: props.containerId,

+ 13
- 13
src/containers/ContainerRegistry.test.js View File

@@ -45,15 +45,15 @@ describe('ContainerRegistry', () => {
45 45
       AppRegistry.registerComponent = jest.fn(AppRegistry.registerComponent);
46 46
     });
47 47
 
48
-    it('registers container component by containerKey into AppRegistry', () => {
48
+    it('registers container component by containerName into AppRegistry', () => {
49 49
       expect(AppRegistry.registerComponent).not.toHaveBeenCalled();
50
-      uut.registerContainer('example.MyContainer.key', () => MyContainer);
50
+      uut.registerContainer('example.MyContainer.name', () => MyContainer);
51 51
       expect(AppRegistry.registerComponent).toHaveBeenCalledTimes(1);
52
-      expect(AppRegistry.registerComponent.mock.calls[0][0]).toEqual('example.MyContainer.key');
52
+      expect(AppRegistry.registerComponent.mock.calls[0][0]).toEqual('example.MyContainer.name');
53 53
     });
54 54
 
55 55
     it('resulting in a normal component', () => {
56
-      uut.registerContainer('example.MyContainer.key', () => MyContainer);
56
+      uut.registerContainer('example.MyContainer.name', () => MyContainer);
57 57
       const Container = AppRegistry.registerComponent.mock.calls[0][1]();
58 58
       const tree = renderer.create(<Container containerId="123"/>);
59 59
       expect(tree.toJSON().children).toEqual(['Hello, World!']);
@@ -61,21 +61,21 @@ describe('ContainerRegistry', () => {
61 61
   });
62 62
 
63 63
   describe('NavigationContainer wrapping passed container', () => {
64
-    const containerKey = 'example.MyContainer';
64
+    const containerName = 'example.MyContainer';
65 65
 
66 66
     beforeEach(() => {
67
-      uut.registerContainer(containerKey, () => MyContainer);
67
+      uut.registerContainer(containerName, () => MyContainer);
68 68
     });
69 69
 
70 70
     it('must have containerId as prop', () => {
71
-      const NavigationContainer = store.getContainerClass(containerKey);
71
+      const NavigationContainer = store.getContainerClass(containerName);
72 72
       expect(() => {
73 73
         renderer.create(<NavigationContainer/>);
74 74
       }).toThrow(new Error('Container example.MyContainer does not have a containerId!'));
75 75
     });
76 76
 
77 77
     it('wraps the container and saves to store', () => {
78
-      const NavigationContainer = store.getContainerClass(containerKey);
78
+      const NavigationContainer = store.getContainerClass(containerName);
79 79
       expect(NavigationContainer).not.toBeInstanceOf(MyContainer);
80 80
       const tree = renderer.create(<NavigationContainer containerId={'container1'}/>);
81 81
       expect(tree.toJSON().children).toEqual(['Hello, World!']);
@@ -83,13 +83,13 @@ describe('ContainerRegistry', () => {
83 83
     });
84 84
 
85 85
     it('injects props from wrapper into original container', () => {
86
-      const NavigationContainer = store.getContainerClass(containerKey);
86
+      const NavigationContainer = store.getContainerClass(containerName);
87 87
       renderer.create(<NavigationContainer containerId={'container1'} myProp={'yo'}/>);
88 88
       expect(myContainerRef.props.myProp).toEqual('yo');
89 89
     });
90 90
 
91 91
     it('updates props from wrapper into original container', () => {
92
-      const NavigationContainer = store.getContainerClass(containerKey);
92
+      const NavigationContainer = store.getContainerClass(containerName);
93 93
       renderer.create(<TestParent ChildClass={NavigationContainer}/>);
94 94
       expect(myContainerRef.props.foo).toEqual(undefined);
95 95
       testParentRef.setState({propsFromState: {foo: 'yo'}});
@@ -98,13 +98,13 @@ describe('ContainerRegistry', () => {
98 98
 
99 99
     it('pulls props from the PropsStore and injects them into the inner container', () => {
100 100
       store.setPropsForContainerId('container123', {numberProp: 1, stringProp: 'hello', objectProp: {a: 2}});
101
-      const NavigationContainer = store.getContainerClass(containerKey);
101
+      const NavigationContainer = store.getContainerClass(containerName);
102 102
       renderer.create(<NavigationContainer containerId={'container123'}/>);
103 103
       expect(myContainerRef.props).toEqual({containerId: 'container123', numberProp: 1, stringProp: 'hello', objectProp: {a: 2}});
104 104
     });
105 105
 
106 106
     it('updates props from PropsStore into inner container', () => {
107
-      const NavigationContainer = store.getContainerClass(containerKey);
107
+      const NavigationContainer = store.getContainerClass(containerName);
108 108
       renderer.create(<TestParent ChildClass={NavigationContainer}/>);
109 109
       store.setPropsForContainerId('container1', {myProp: 'hello'});
110 110
       expect(myContainerRef.props.foo).toEqual(undefined);
@@ -115,7 +115,7 @@ describe('ContainerRegistry', () => {
115 115
     });
116 116
 
117 117
     it('protects containerId from change', () => {
118
-      const NavigationContainer = store.getContainerClass(containerKey);
118
+      const NavigationContainer = store.getContainerClass(containerName);
119 119
       renderer.create(<TestParent ChildClass={NavigationContainer}/>);
120 120
       expect(myContainerRef.props.containerId).toEqual('container1');
121 121
       testParentRef.setState({propsFromState: {containerId: 'ERROR'}});

+ 5
- 5
src/containers/Store.js View File

@@ -2,7 +2,7 @@ import _ from 'lodash';
2 2
 
3 3
 const state = {
4 4
   propsByContainerId: {},
5
-  containersByKey: {}
5
+  containersByName: {}
6 6
 };
7 7
 
8 8
 export function setPropsForContainerId(containerId, props) {
@@ -13,10 +13,10 @@ export function getPropsForContainerId(containerId) {
13 13
   return _.get(state.propsByContainerId, containerId, {});
14 14
 }
15 15
 
16
-export function setContainerClass(containerKey, ContainerClass) {
17
-  state.containersByKey[containerKey] = ContainerClass;
16
+export function setContainerClass(containerName, ContainerClass) {
17
+  state.containersByName[containerName] = ContainerClass;
18 18
 }
19 19
 
20
-export function getContainerClass(containerKey) {
21
-  return state.containersByKey[containerKey];
20
+export function getContainerClass(containerName) {
21
+  return state.containersByName[containerName];
22 22
 }

+ 3
- 3
src/containers/Store.test.js View File

@@ -20,12 +20,12 @@ describe('Store', () => {
20 20
     expect(uut.getPropsForContainerId('container1')).toEqual({});
21 21
   });
22 22
 
23
-  it('holds containers classes by containerKey', () => {
23
+  it('holds containers classes by containerName', () => {
24 24
     const MyComponent = class {
25 25
       //
26 26
     };
27
-    uut.setContainerClass('example.mykey', MyComponent);
28
-    expect(uut.getContainerClass('example.mykey')).toEqual(MyComponent);
27
+    uut.setContainerClass('example.mycontainer', MyComponent);
28
+    expect(uut.getContainerClass('example.mycontainer')).toEqual(MyComponent);
29 29
   });
30 30
 });
31 31
 

+ 3
- 3
src/index.js View File

@@ -1,4 +1,4 @@
1
-import * as _Navigation from './Navigation';
1
+import * as Navigation from './Navigation';
2 2
 
3
-export default _Navigation;
4
-export const Navigation = _Navigation;
3
+module.exports = Navigation;
4
+module.exports.default = Navigation;

+ 2
- 4
src/index.test.js View File

@@ -1,16 +1,14 @@
1 1
 import Navigation from './index';
2
-import {Navigation as inner} from './index';
3 2
 
4 3
 describe('index', () => {
5 4
   let uut;
6 5
 
7 6
   beforeEach(() => {
8
-    uut = require('./index').default;
7
+    uut = require('./index');
9 8
   });
10 9
 
11
-  it('exposes Navigation as default or as object', () => {
10
+  it('exposes Navigation', () => {
12 11
     expect(uut.startApp).toBeInstanceOf(Function);
13 12
     expect(Navigation.startApp).toBeInstanceOf(Function);
14
-    expect(inner.startApp).toBeInstanceOf(Function);
15 13
   });
16 14
 });