Browse Source

commands error handling

yogevbd 6 years ago
parent
commit
9f693b22f5

+ 1
- 0
lib/ios/RCTHelpers.m View File

@@ -135,4 +135,5 @@
135 135
 	return [NSString stringWithFormat:@"%lld", milliseconds];
136 136
 }
137 137
 
138
+
138 139
 @end

+ 5
- 5
lib/ios/RNNBridgeModule.m View File

@@ -39,31 +39,31 @@ RCT_EXPORT_METHOD(setDefaultOptions:(NSDictionary*)options resolver:(RCTPromiseR
39 39
 RCT_EXPORT_METHOD(push:(NSString*)componentId layout:(NSDictionary*)layout resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
40 40
 	[_commandsHandler push:componentId layout:layout completion:^{
41 41
 		resolve(componentId);
42
-	}];
42
+	} rejection:reject];
43 43
 }
44 44
 
45 45
 RCT_EXPORT_METHOD(pop:(NSString*)componentId options:(NSDictionary*)options resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
46 46
 	[_commandsHandler pop:componentId options:(NSDictionary*)options completion:^{
47 47
 		resolve(componentId);
48
-	}];
48
+	} rejection:reject];
49 49
 }
50 50
 
51 51
 RCT_EXPORT_METHOD(setStackRoot:(NSString*)componentId layout:(NSDictionary*)layout resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
52 52
 	[_commandsHandler setStackRoot:componentId layout:layout completion:^{
53 53
 		resolve(componentId);
54
-	}];
54
+	} rejection:reject];
55 55
 }
56 56
 
57 57
 RCT_EXPORT_METHOD(popTo:(NSString*)componentId resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
58 58
 	[_commandsHandler popTo:componentId completion:^{
59 59
 		resolve(componentId);
60
-	}];
60
+	} rejection:reject];
61 61
 }
62 62
 
63 63
 RCT_EXPORT_METHOD(popToRoot:(NSString*)componentId resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
64 64
 	[_commandsHandler popToRoot:componentId completion:^{
65 65
 		resolve(componentId);
66
-	}];
66
+	} rejection:reject];
67 67
 }
68 68
 
69 69
 RCT_EXPORT_METHOD(showModal:(NSDictionary*)layout resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {

+ 12
- 12
lib/ios/RNNCommandsHandler.h View File

@@ -6,29 +6,29 @@
6 6
 
7 7
 @interface RNNCommandsHandler : NSObject
8 8
 
9
--(instancetype) initWithStore:(RNNStore*)store controllerFactory:(RNNControllerFactory*)controllerFactory eventEmitter:(RNNEventEmitter*)eventEmitter;
9
+-(instancetype)initWithStore:(RNNStore*)store controllerFactory:(RNNControllerFactory*)controllerFactory eventEmitter:(RNNEventEmitter*)eventEmitter;
10 10
 
11
--(void) setRoot:(NSDictionary*)layout completion:(RNNTransitionCompletionBlock)completion;
11
+-(void)setRoot:(NSDictionary*)layout completion:(RNNTransitionCompletionBlock)completion;
12 12
 
13
--(void) mergeOptions:(NSString*)componentId options:(NSDictionary*)options completion:(RNNTransitionCompletionBlock)completion;
13
+-(void)mergeOptions:(NSString*)componentId options:(NSDictionary*)options completion:(RNNTransitionCompletionBlock)completion;
14 14
 
15
--(void) setDefaultOptions:(NSDictionary*)options completion:(RNNTransitionCompletionBlock)completion;
15
+-(void)setDefaultOptions:(NSDictionary*)options completion:(RNNTransitionCompletionBlock)completion;
16 16
 
17
--(void) push:(NSString*)componentId layout:(NSDictionary*)layout completion:(RNNTransitionCompletionBlock)completion;
17
+-(void)push:(NSString*)componentId layout:(NSDictionary*)layout completion:(RNNTransitionCompletionBlock)completion rejection:(RCTPromiseRejectBlock)rejection;
18 18
 
19
--(void) pop:(NSString*)componentId options:(NSDictionary*)options completion:(RNNTransitionCompletionBlock)completion;
19
+-(void)pop:(NSString*)componentId options:(NSDictionary*)options completion:(RNNTransitionCompletionBlock)completion rejection:(RCTPromiseRejectBlock)rejection;
20 20
 
21
--(void) popTo:(NSString*)componentId completion:(RNNTransitionCompletionBlock)completion;
21
+-(void)popTo:(NSString*)componentId completion:(RNNTransitionCompletionBlock)completion rejection:(RCTPromiseRejectBlock)rejection;
22 22
 
23
--(void) popToRoot:(NSString*)componentId completion:(RNNTransitionCompletionBlock)completion;
23
+-(void)popToRoot:(NSString*)componentId completion:(RNNTransitionCompletionBlock)completion rejection:(RCTPromiseRejectBlock)rejection;
24 24
 
25
--(void)setStackRoot:(NSString*)componentId layout:(NSDictionary*)layout completion:(RNNTransitionCompletionBlock)completion;
25
+-(void)setStackRoot:(NSString*)componentId layout:(NSDictionary*)layout completion:(RNNTransitionCompletionBlock)completion rejection:(RCTPromiseRejectBlock)rejection;
26 26
 
27
--(void) showModal:(NSDictionary*)layout completion:(RNNTransitionCompletionBlock)completion;
27
+-(void)showModal:(NSDictionary*)layout completion:(RNNTransitionCompletionBlock)completion;
28 28
 
29
--(void) dismissModal:(NSString*)componentId completion:(RNNTransitionCompletionBlock)completion;
29
+-(void)dismissModal:(NSString*)componentId completion:(RNNTransitionCompletionBlock)completion;
30 30
 
31
--(void) dismissAllModalsWithCompletion:(RNNTransitionCompletionBlock)completion;
31
+-(void)dismissAllModalsWithCompletion:(RNNTransitionCompletionBlock)completion;
32 32
 
33 33
 -(void)showOverlay:(NSDictionary *)layout completion:(RNNTransitionCompletionBlock)completion;
34 34
 

+ 13
- 13
lib/ios/RNNCommandsHandler.m View File

@@ -78,26 +78,26 @@ static NSString* const setDefaultOptions	= @"setDefaultOptions";
78 78
 	[_controllerFactory setDefaultOptionsDict:optionsDict];
79 79
 }
80 80
 
81
--(void)push:(NSString*)componentId layout:(NSDictionary*)layout completion:(RNNTransitionCompletionBlock)completion {
81
+-(void)push:(NSString*)componentId layout:(NSDictionary*)layout completion:(RNNTransitionCompletionBlock)completion rejection:(RCTPromiseRejectBlock)rejection {
82 82
 	[self assertReady];
83 83
 	[_eventEmitter sendOnNavigationComment:push params:@{@"componentId": componentId}];
84 84
 	UIViewController<RNNRootViewProtocol> *newVc = [_controllerFactory createLayoutAndSaveToStore:layout];
85 85
 	[_navigationStackManager push:newVc onTop:componentId completion:^{
86 86
 		completion();
87
-	}];
87
+	} rejection:rejection];
88 88
 }
89 89
 
90
--(void)setStackRoot:(NSString*)componentId layout:(NSDictionary*)layout completion:(RNNTransitionCompletionBlock)completion {
90
+-(void)setStackRoot:(NSString*)componentId layout:(NSDictionary*)layout completion:(RNNTransitionCompletionBlock)completion rejection:(RCTPromiseRejectBlock)rejection {
91 91
 	[self assertReady];
92 92
 	[_eventEmitter sendOnNavigationComment:setStackRoot params:@{@"componentId": componentId}];
93 93
 
94 94
 	UIViewController<RNNRootViewProtocol> *newVc = [_controllerFactory createLayoutAndSaveToStore:layout];
95
-	[_navigationStackManager setRoot:newVc fromComponent:componentId completion:^{
95
+	[_navigationStackManager setStackRoot:newVc fromComponent:componentId completion:^{
96 96
 		completion();
97
-	}];
97
+	} rejection:rejection];
98 98
 }
99 99
 
100
--(void)pop:(NSString*)componentId options:(NSDictionary*)options completion:(RNNTransitionCompletionBlock)completion {
100
+-(void)pop:(NSString*)componentId options:(NSDictionary*)options completion:(RNNTransitionCompletionBlock)completion rejection:(RCTPromiseRejectBlock)rejection {
101 101
 	[self assertReady];
102 102
 	[_eventEmitter sendOnNavigationComment:pop params:@{@"componentId": componentId}];
103 103
 	[CATransaction begin];
@@ -109,14 +109,14 @@ static NSString* const setDefaultOptions	= @"setDefaultOptions";
109 109
 	RNNAnimationOptions* transitionOptions = [[RNNAnimationOptions alloc] initWithDict:animationData];
110 110
 	
111 111
 	if (transitionOptions.animations){
112
-		[_navigationStackManager pop:componentId withTransitionOptions:transitionOptions];
112
+		[_navigationStackManager pop:componentId withTransitionOptions:transitionOptions rejection:rejection];
113 113
 	} else {
114
-		[_navigationStackManager pop:componentId withTransitionOptions:nil];
114
+		[_navigationStackManager pop:componentId withTransitionOptions:nil rejection:rejection];
115 115
 	}
116 116
 	[CATransaction commit];
117 117
 }
118 118
 
119
--(void) popTo:(NSString*)componentId completion:(RNNTransitionCompletionBlock)completion {
119
+-(void) popTo:(NSString*)componentId completion:(RNNTransitionCompletionBlock)completion rejection:(RCTPromiseRejectBlock)rejection {
120 120
 	[self assertReady];
121 121
 	[_eventEmitter sendOnNavigationComment:popTo params:@{@"componentId": componentId}];
122 122
 	[CATransaction begin];
@@ -124,12 +124,12 @@ static NSString* const setDefaultOptions	= @"setDefaultOptions";
124 124
 		completion();
125 125
 	}];
126 126
 	
127
-	[_navigationStackManager popTo:componentId];
127
+	[_navigationStackManager popTo:componentId rejection:rejection];
128 128
 	
129 129
 	[CATransaction commit];
130 130
 }
131 131
 
132
--(void) popToRoot:(NSString*)componentId completion:(RNNTransitionCompletionBlock)completion {
132
+-(void) popToRoot:(NSString*)componentId completion:(RNNTransitionCompletionBlock)completion rejection:(RCTPromiseRejectBlock)rejection {
133 133
 	[self assertReady];
134 134
 	[_eventEmitter sendOnNavigationComment:popToRoot params:@{@"componentId": componentId}];
135 135
 	[CATransaction begin];
@@ -137,7 +137,7 @@ static NSString* const setDefaultOptions	= @"setDefaultOptions";
137 137
 		completion();
138 138
 	}];
139 139
 	
140
-	[_navigationStackManager popToRoot:componentId];
140
+	[_navigationStackManager popToRoot:componentId rejection:rejection];
141 141
 	
142 142
 	[CATransaction commit];
143 143
 }
@@ -166,7 +166,7 @@ static NSString* const setDefaultOptions	= @"setDefaultOptions";
166 166
 
167 167
 -(void) dismissAllModalsWithCompletion:(RNNTransitionCompletionBlock)completion {
168 168
 	[self assertReady];
169
-	[_eventEmitter sendOnNavigationComment:dismissAllModals params:nil];
169
+	[_eventEmitter sendOnNavigationComment:dismissAllModals params:@{}];
170 170
 	[CATransaction begin];
171 171
 	[CATransaction setCompletionBlock:^{
172 172
 		completion();

+ 13
- 0
lib/ios/RNNErrorHandler.h View File

@@ -0,0 +1,13 @@
1
+#import <Foundation/Foundation.h>
2
+#import <React/RCTBridgeModule.h>
3
+
4
+typedef enum RNNCommandsErrorCodes {
5
+	RNNCommandErrorCodeNoStack = 0
6
+} RNNCommandsErrorCodes;
7
+
8
+@interface RNNErrorHandler : NSObject
9
+
10
++ (void)reject:(RCTPromiseRejectBlock)reject withErrorCode:(NSInteger)errorCode errorDescription:(NSString*)errorDescription;
11
++ (NSString *)getCallerFunctionName;
12
+
13
+@end

+ 22
- 0
lib/ios/RNNErrorHandler.m View File

@@ -0,0 +1,22 @@
1
+#import "RNNErrorHandler.h"
2
+
3
+static NSString* const domain = @"com.reactnativenavigation";
4
+
5
+@implementation RNNErrorHandler
6
+
7
++ (void)reject:(RCTPromiseRejectBlock)reject withErrorCode:(NSInteger)errorCode errorDescription:(NSString*)errorDescription {
8
+	NSError *error = [NSError errorWithDomain:domain code:errorCode userInfo:@{NSLocalizedFailureReasonErrorKey: errorDescription}];
9
+	if (reject) {
10
+		reject([NSString stringWithFormat:@"%ld", (long)errorCode], errorDescription, error);
11
+	}
12
+}
13
+
14
++ (NSString *)getCallerFunctionName {
15
+	NSString *sourceString = [[NSThread callStackSymbols] objectAtIndex:2];
16
+	NSCharacterSet *separatorSet = [NSCharacterSet characterSetWithCharactersInString:@" -[]+?.,"];
17
+	NSMutableArray *array = [NSMutableArray arrayWithArray:[sourceString  componentsSeparatedByCharactersInSet:separatorSet]];
18
+	[array removeObject:@""];
19
+	return [[[array objectAtIndex:4] componentsSeparatedByString:@":"] objectAtIndex:0];
20
+}
21
+
22
+@end

+ 5
- 5
lib/ios/RNNNavigationStackManager.h View File

@@ -10,10 +10,10 @@
10 10
 -(instancetype)initWithStore:(RNNStore*)store;
11 11
 
12 12
 
13
--(void)push:(UIViewController<RNNRootViewProtocol>*)newTop onTop:(NSString*)componentId completion:(RNNTransitionCompletionBlock)completion;
14
--(void)pop:(NSString*)componentId withTransitionOptions:(RNNAnimationOptions*)transitionOptions;
15
--(void)popTo:(NSString*)componentId;
16
--(void)popToRoot:(NSString*)componentId;
17
--(void)setRoot:(UIViewController<RNNRootViewProtocol> *)newRoot fromComponent:(NSString *)componentId completion:(RNNTransitionCompletionBlock)completion;
13
+-(void)push:(UIViewController<RNNRootViewProtocol>*)newTop onTop:(NSString*)componentId completion:(RNNTransitionCompletionBlock)completion rejection:(RCTPromiseRejectBlock)rejection;
14
+-(void)pop:(NSString*)componentId withTransitionOptions:(RNNAnimationOptions*)transitionOptions rejection:(RCTPromiseRejectBlock)rejection;
15
+-(void)popTo:(NSString*)componentId rejection:(RCTPromiseRejectBlock)rejection;
16
+-(void)popToRoot:(NSString*)componentId rejection:(RCTPromiseRejectBlock)rejection;
17
+-(void)setStackRoot:(UIViewController<RNNRootViewProtocol> *)newRoot fromComponent:(NSString *)componentId completion:(RNNTransitionCompletionBlock)completion rejection:(RCTPromiseRejectBlock)rejection;
18 18
 
19 19
 @end

+ 18
- 10
lib/ios/RNNNavigationStackManager.m View File

@@ -1,6 +1,7 @@
1 1
 #import "RNNNavigationStackManager.h"
2 2
 #import "RNNRootViewController.h"
3 3
 #import "RNNAnimator.h"
4
+#import "RNNErrorHandler.h"
4 5
 
5 6
 
6 7
 dispatch_queue_t RCTGetUIManagerQueue(void);
@@ -15,9 +16,10 @@ dispatch_queue_t RCTGetUIManagerQueue(void);
15 16
 	return self;
16 17
 }
17 18
 
18
--(void)push:(UIViewController<RNNRootViewProtocol> *)newTop onTop:(NSString *)componentId completion:(RNNTransitionCompletionBlock)completion {
19
+-(void)push:(UIViewController<RNNRootViewProtocol> *)newTop onTop:(NSString *)componentId completion:(RNNTransitionCompletionBlock)completion rejection:(RCTPromiseRejectBlock)rejection {
19 20
 	UIViewController *vc = [_store findComponentForId:componentId];
20 21
 	[self preparePush:newTop onTopVC:vc completion:completion];
22
+	[self assertNavigationControllerExist:vc reject:rejection];
21 23
 	if ([newTop isCustomViewController]) {
22 24
 		[self pushAfterLoad:nil];
23 25
 	} else {
@@ -65,8 +67,9 @@ dispatch_queue_t RCTGetUIManagerQueue(void);
65 67
 	self.fromVC = nil;
66 68
 }
67 69
 
68
--(void)pop:(NSString *)componentId withTransitionOptions:(RNNAnimationOptions *)transitionOptions {
70
+-(void)pop:(NSString *)componentId withTransitionOptions:(RNNAnimationOptions *)transitionOptions rejection:(RCTPromiseRejectBlock)rejection {
69 71
 	RNNRootViewController* vc = (RNNRootViewController*)[_store findComponentForId:componentId];
72
+	[self assertNavigationControllerExist:vc reject:rejection];
70 73
 	UINavigationController* nvc = [vc navigationController];
71 74
 	if ([nvc topViewController] == vc) {
72 75
 		if (vc.options.animations.pop) {
@@ -84,9 +87,9 @@ dispatch_queue_t RCTGetUIManagerQueue(void);
84 87
 	[_store removeComponent:componentId];
85 88
 }
86 89
 
87
--(void)popTo:(NSString*)componentId {
90
+-(void)popTo:(NSString*)componentId rejection:(RCTPromiseRejectBlock)rejection {
88 91
 	RNNRootViewController *vc = (RNNRootViewController*)[_store findComponentForId:componentId];
89
-	
92
+	[self assertNavigationControllerExist:vc reject:rejection];
90 93
 	if (vc) {
91 94
 		UINavigationController *nvc = [vc navigationController];
92 95
 		if(nvc) {
@@ -96,21 +99,19 @@ dispatch_queue_t RCTGetUIManagerQueue(void);
96 99
 	}
97 100
 }
98 101
 
99
--(void)popToRoot:(NSString*)componentId {
102
+-(void)popToRoot:(NSString*)componentId rejection:(RCTPromiseRejectBlock)rejection {
100 103
 	RNNRootViewController *vc = (RNNRootViewController*)[_store findComponentForId:componentId];
104
+	[self assertNavigationControllerExist:vc reject:rejection];
101 105
 	UINavigationController* nvc = [vc navigationController];
102 106
 	NSArray* poppedVCs = [nvc popToRootViewControllerAnimated:vc.options.animations.pop.enable];
103 107
 	[self removePopedViewControllers:poppedVCs];
104 108
 }
105 109
 
106
--(void)setRoot:(UIViewController<RNNRootViewProtocol> *)newRoot fromComponent:(NSString *)componentId completion:(RNNTransitionCompletionBlock)completion {
110
+-(void)setStackRoot:(UIViewController<RNNRootViewProtocol> *)newRoot fromComponent:(NSString *)componentId completion:(RNNTransitionCompletionBlock)completion rejection:(RCTPromiseRejectBlock)rejection {
107 111
 	UIViewController* vc = [_store findComponentForId:componentId];
112
+	[self assertNavigationControllerExist:vc reject:rejection];
108 113
 	UINavigationController* nvc = [vc navigationController];
109 114
 	
110
-	if (!nvc) {
111
-		@throw [NSException exceptionWithName:@"StackNotFound" reason:@"Missing stack, setRoot should contain stack layout" userInfo:nil];
112
-	}
113
-	
114 115
 	[CATransaction begin];
115 116
 	[CATransaction setCompletionBlock:^{
116 117
 		if (completion) {
@@ -123,6 +124,13 @@ dispatch_queue_t RCTGetUIManagerQueue(void);
123 124
 	[CATransaction commit];
124 125
 }
125 126
 
127
+- (void)assertNavigationControllerExist:(UIViewController *)viewController reject:(RCTPromiseRejectBlock)reject {
128
+	if (!viewController.navigationController) {
129
+		_completionBlock = nil;
130
+		[RNNErrorHandler reject:reject withErrorCode:RNNCommandErrorCodeNoStack errorDescription:[NSString stringWithFormat:@"%@ should be called from a stack child component", [RNNErrorHandler getCallerFunctionName]]];
131
+	}
132
+}
133
+
126 134
 -(void)removePopedViewControllers:(NSArray*)viewControllers {
127 135
 	for (UIViewController *popedVC in viewControllers) {
128 136
 		[_store removeComponentByViewControllerInstance:popedVC];

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

@@ -5,6 +5,7 @@
5 5
 #import "ReactNativeNavigation.h"
6 6
 
7 7
 typedef void (^RNNTransitionCompletionBlock)(void);
8
+//typedef void (^RNNTransitionRejectionBlock)(NSString *code, NSString *message, NSError *error);
8 9
 
9 10
 @interface RNNStore : NSObject
10 11
 

+ 3
- 0
lib/ios/RNNUtils.m View File

@@ -8,6 +8,7 @@
8 8
 		return defaultResult;
9 9
 	}
10 10
 }
11
+
11 12
 +(BOOL)getBoolOrKey:(NSDictionary*)dict withKey:(NSString*)key withDefault:(BOOL)defaultResult {
12 13
 	if ([dict objectForKey:key]) {
13 14
 		return [dict[key] boolValue];
@@ -15,6 +16,7 @@
15 16
 		return defaultResult;
16 17
 	}
17 18
 }
19
+
18 20
 +(id)getObjectOrKey:(NSDictionary*)dict withKey:(NSString*)key withDefault:(id)defaultResult {
19 21
 	if ([dict objectForKey:key]) {
20 22
 		return dict[key];
@@ -22,4 +24,5 @@
22 24
 		return defaultResult;
23 25
 	}
24 26
 }
27
+
25 28
 @end

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

@@ -83,6 +83,8 @@
83 83
 		50570B272061473D006A1B5C /* RNNTitleOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 50570B252061473D006A1B5C /* RNNTitleOptions.m */; };
84 84
 		50570BEA2063E09B006A1B5C /* RNNTitleViewHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 50570BE82063E09B006A1B5C /* RNNTitleViewHelper.h */; };
85 85
 		50570BEB2063E09B006A1B5C /* RNNTitleViewHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 50570BE92063E09B006A1B5C /* RNNTitleViewHelper.m */; };
86
+		506A2B1420973DFD00F43A95 /* RNNErrorHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 506A2B1220973DFD00F43A95 /* RNNErrorHandler.h */; };
87
+		506A2B1520973DFD00F43A95 /* RNNErrorHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 506A2B1320973DFD00F43A95 /* RNNErrorHandler.m */; };
86 88
 		50762D08205E96C200E3D18A /* RNNModalAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 50762D06205E96C200E3D18A /* RNNModalAnimation.h */; };
87 89
 		50762D09205E96C200E3D18A /* RNNModalAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 50762D07205E96C200E3D18A /* RNNModalAnimation.m */; };
88 90
 		507E7D57201DDD3000444E6C /* RNNAnimationOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 507E7D55201DDD3000444E6C /* RNNAnimationOptions.h */; };
@@ -276,6 +278,8 @@
276 278
 		50570B252061473D006A1B5C /* RNNTitleOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNTitleOptions.m; sourceTree = "<group>"; };
277 279
 		50570BE82063E09B006A1B5C /* RNNTitleViewHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNTitleViewHelper.h; sourceTree = "<group>"; };
278 280
 		50570BE92063E09B006A1B5C /* RNNTitleViewHelper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNTitleViewHelper.m; sourceTree = "<group>"; };
281
+		506A2B1220973DFD00F43A95 /* RNNErrorHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNErrorHandler.h; sourceTree = "<group>"; };
282
+		506A2B1320973DFD00F43A95 /* RNNErrorHandler.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNErrorHandler.m; sourceTree = "<group>"; };
279 283
 		50762D06205E96C200E3D18A /* RNNModalAnimation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNModalAnimation.h; sourceTree = "<group>"; };
280 284
 		50762D07205E96C200E3D18A /* RNNModalAnimation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNModalAnimation.m; sourceTree = "<group>"; };
281 285
 		507E7D55201DDD3000444E6C /* RNNAnimationOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNAnimationOptions.h; sourceTree = "<group>"; };
@@ -419,6 +423,8 @@
419 423
 				214545291F4DC85F006E8DA1 /* RCTHelpers.m */,
420 424
 				390AD475200F499D00A8250D /* RNNSwizzles.h */,
421 425
 				390AD476200F499D00A8250D /* RNNSwizzles.m */,
426
+				506A2B1220973DFD00F43A95 /* RNNErrorHandler.h */,
427
+				506A2B1320973DFD00F43A95 /* RNNErrorHandler.m */,
422 428
 			);
423 429
 			name = Helpers;
424 430
 			sourceTree = "<group>";
@@ -735,6 +741,7 @@
735 741
 				504AFE761FFFF1E00076E904 /* RNNNavigationOptions.h in Headers */,
736 742
 				504AFE771FFFF1E20076E904 /* RNNTopBarOptions.h in Headers */,
737 743
 				26916C981E4B9E7700D13680 /* RNNReactRootViewCreator.h in Headers */,
744
+				506A2B1420973DFD00F43A95 /* RNNErrorHandler.h in Headers */,
738 745
 				263905B01E4C6F440023D7D3 /* MMDrawerController+Subclass.h in Headers */,
739 746
 				E8AEDB4A1F5C0BAF000F5A6A /* RNNInteractivePopAnimator.h in Headers */,
740 747
 				7B1126A41E2D2B6C00F9B03B /* ReactNativeNavigation.h in Headers */,
@@ -936,6 +943,7 @@
936 943
 				263905B21E4C6F440023D7D3 /* MMDrawerController.m in Sources */,
937 944
 				E8AEDB3D1F55A1C2000F5A6A /* RNNElementView.m in Sources */,
938 945
 				E83BAD6B1F27363A00A9F3DD /* RNNNavigationOptions.m in Sources */,
946
+				506A2B1520973DFD00F43A95 /* RNNErrorHandler.m in Sources */,
939 947
 				7BBFE5441E25330E002A6182 /* RNNBridgeModule.m in Sources */,
940 948
 				261F0E651E6EC94900989DE2 /* RNNModalManager.m in Sources */,
941 949
 				E8A5CD631F49114F00E89D0D /* RNNElement.m in Sources */,

+ 4
- 11
lib/ios/ReactNativeNavigationTests/RNNNavigationStackManagerTest.m View File

@@ -53,7 +53,7 @@
53 53
 
54 54
 
55 55
 - (void)testPop_removeTopVCFromStore {
56
-	[self.uut pop:@"vc3" withTransitionOptions:nil];
56
+	[self.uut pop:@"vc3" withTransitionOptions:nil rejection:nil];
57 57
 	XCTAssertNil([self.store findComponentForId:@"vc3"]);
58 58
 	XCTAssertNotNil([self.store findComponentForId:@"vc2"]);
59 59
 	XCTAssertNotNil([self.store findComponentForId:@"vc1"]);
@@ -61,7 +61,7 @@
61 61
 
62 62
 - (void)testPopToSpecificVC_removeAllPopedVCFromStore {
63 63
 	self.nvc.willReturnVCs = @[self.vc2, self.vc3];
64
-	[self.uut popTo:@"vc1"];
64
+	[self.uut popTo:@"vc1" rejection:nil];
65 65
 	
66 66
 	XCTAssertNil([self.store findComponentForId:@"vc2"]);
67 67
 	XCTAssertNil([self.store findComponentForId:@"vc3"]);
@@ -71,7 +71,7 @@
71 71
 
72 72
 - (void)testPopToRoot_removeAllTopVCsFromStore {
73 73
 	self.nvc.willReturnVCs = @[self.vc2, self.vc3];
74
-	[self.uut popToRoot:@"vc3"];
74
+	[self.uut popToRoot:@"vc3" rejection:nil];
75 75
 	
76 76
 	XCTAssertNil([self.store findComponentForId:@"vc2"]);
77 77
 	XCTAssertNil([self.store findComponentForId:@"vc3"]);
@@ -79,17 +79,10 @@
79 79
 
80 80
 }
81 81
 
82
-- (void)testStackRoot_navigationControllerNilShouldThrow {
83
-	[self.nvc setViewControllers:@[self.vc1]];
84
-	self.nvc.willReturnVCs = @[self.vc1];
85
-	
86
-	XCTAssertThrowsSpecificNamed([self.uut setRoot:self.vc2 fromComponent:nil completion:nil], NSException, @"StackNotFound");
87
-}
88
-
89 82
 - (void)testStackRoot_shouldUpdateNavigationControllerChildrenViewControllers {
90 83
 	self.nvc.willReturnVCs = @[self.vc1, self.vc2, self.vc3];
91 84
 	
92
-	[self.uut setRoot:self.vc2 fromComponent:@"vc1" completion:nil];
85
+	[self.uut setStackRoot:self.vc2 fromComponent:@"vc1" completion:nil rejection:nil];
93 86
 	
94 87
 	XCTAssertEqual(self.nvc.viewControllers.lastObject, self.vc2);
95 88
 	XCTAssertEqual(self.nvc.viewControllers.count, 1);

+ 4
- 4
playground/ios/playground.xcodeproj/xcshareddata/xcschemes/playground.xcscheme View File

@@ -75,10 +75,10 @@
75 75
             skipped = "NO">
76 76
             <BuildableReference
77 77
                BuildableIdentifier = "primary"
78
-               BlueprintIdentifier = "00E356ED1AD99517003FC87E"
79
-               BuildableName = "playgroundTests.xctest"
80
-               BlueprintName = "playgroundTests"
81
-               ReferencedContainer = "container:playground.xcodeproj">
78
+               BlueprintIdentifier = "7B49FEBA1E95090800DEB3EA"
79
+               BuildableName = "ReactNativeNavigationTests.xctest"
80
+               BlueprintName = "ReactNativeNavigationTests"
81
+               ReferencedContainer = "container:../../lib/ios/ReactNativeNavigation.xcodeproj">
82 82
             </BuildableReference>
83 83
          </TestableReference>
84 84
       </Testables>

+ 22
- 0
playground/ios/playgroundTests/Info.plist View File

@@ -0,0 +1,22 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+<dict>
5
+	<key>CFBundleDevelopmentRegion</key>
6
+	<string>$(DEVELOPMENT_LANGUAGE)</string>
7
+	<key>CFBundleExecutable</key>
8
+	<string>$(EXECUTABLE_NAME)</string>
9
+	<key>CFBundleIdentifier</key>
10
+	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
11
+	<key>CFBundleInfoDictionaryVersion</key>
12
+	<string>6.0</string>
13
+	<key>CFBundleName</key>
14
+	<string>$(PRODUCT_NAME)</string>
15
+	<key>CFBundlePackageType</key>
16
+	<string>BNDL</string>
17
+	<key>CFBundleShortVersionString</key>
18
+	<string>1.0</string>
19
+	<key>CFBundleVersion</key>
20
+	<string>1</string>
21
+</dict>
22
+</plist>

+ 39
- 0
playground/ios/playgroundTests/playgroundTests.m View File

@@ -0,0 +1,39 @@
1
+//
2
+//  playgroundTests.m
3
+//  playgroundTests
4
+//
5
+//  Created by Yogev Ben David on 30/04/2018.
6
+//  Copyright © 2018 Wix. All rights reserved.
7
+//
8
+
9
+#import <XCTest/XCTest.h>
10
+
11
+@interface playgroundTests : XCTestCase
12
+
13
+@end
14
+
15
+@implementation playgroundTests
16
+
17
+- (void)setUp {
18
+    [super setUp];
19
+    // Put setup code here. This method is called before the invocation of each test method in the class.
20
+}
21
+
22
+- (void)tearDown {
23
+    // Put teardown code here. This method is called after the invocation of each test method in the class.
24
+    [super tearDown];
25
+}
26
+
27
+- (void)testExample {
28
+    // This is an example of a functional test case.
29
+    // Use XCTAssert and related functions to verify your tests produce the correct results.
30
+}
31
+
32
+- (void)testPerformanceExample {
33
+    // This is an example of a performance test case.
34
+    [self measureBlock:^{
35
+        // Put the code you want to measure the time of here.
36
+    }];
37
+}
38
+
39
+@end