Skip to content

Commit a9b461b

Browse files
Adelmo Freitasmfdeveloper
authored andcommitted
fix push to viewController when it doesn't have a navigation controller
1 parent 28c1c1f commit a9b461b

File tree

1 file changed

+84
-77
lines changed

1 file changed

+84
-77
lines changed

src/ios/CDVNativeView.m

Lines changed: 84 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -45,59 +45,59 @@ - (instancetype)init
4545
return self;
4646
}
4747
- (void)show:(CDVInvokedUrlCommand*)command {
48-
48+
4949
CDVPluginResult *pluginResult;
50-
50+
5151
@try {
52-
52+
5353
NSString *viewControllerName;
5454
NSString *storyboardName;
5555
NSString *uri;
5656
NSString *message;
5757
NSString *firstParam;
58-
58+
5959
NSMutableDictionary* config = [command.arguments objectAtIndex:0];
60-
60+
6161
if ([config isKindOfClass:[NSMutableDictionary class]]) {
62-
62+
6363
viewControllerName = [config objectForKey:@"viewControllerName"];
6464
storyboardName = [config objectForKey:@"storyboardName"];
6565
uri = [config objectForKey:@"uri"];
66-
66+
6767
} else if ([config isKindOfClass:[NSString class]]) {
68-
68+
6969
if ([command.arguments count] == 1) {
70-
70+
7171
firstParam = [command argumentAtIndex: 0];
72-
72+
7373
if ([self isValidURI: firstParam]) {
7474
// Open app with valid uri name
7575
[self openAPP:firstParam withCommand: command];
76-
76+
7777
} else if ([firstParam containsString:@"Storyboard"]) {
7878
// Init viewController from Storyboard with initial view Controller or user defined viewControllerName
7979
[self instantiateViewController:nil fromStoryboard:firstParam];
80-
80+
8181
} else if ([firstParam containsString:@"Controller"]) {
8282
// Init viewController with or without xib
8383
[self instantiateViewController:firstParam];
84-
84+
8585
} else {
8686
message = [[NSString alloc] initWithFormat:@"%@ invalid. Must contain a Storyboard / Controller / URI valid in name", firstParam];
8787
@throw [[NSException alloc] initWithName:@"IoException" reason:message userInfo:nil];
8888
}
89-
89+
9090
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
9191
return;
92-
92+
9393
}else if ([command.arguments count] == 2) {
94-
94+
9595
// first param is Storyboard
9696
storyboardName = [command argumentAtIndex: 0];
97-
97+
9898
// second param is ViewController and/or storyboardId
9999
viewControllerName = [command argumentAtIndex: 1];
100-
100+
101101
}else{
102102
message = [[NSString alloc] initWithFormat:@"An UIViewController name or Storyboard name or URI valid name is required at least. Please, pass in the first param in JS, like this: 'NativeView.show('MyViewController') or NativeView.show('MyStoryboard') or NativeView.show('MyStoryboard', 'MyViewController') or NativeView.show('instagram://')"];
103103
@throw [[NSException alloc] initWithName:@"NotFoundException" reason:message userInfo:nil];
@@ -106,84 +106,84 @@ - (void)show:(CDVInvokedUrlCommand*)command {
106106
}else{
107107
@throw [[NSException alloc] initWithName:@"ParamsTypeException" reason:@"The params of show() method needs be a string or a json" userInfo:nil];
108108
}
109-
109+
110110
if ([self isValidURI: uri]) {
111111
// Open app with valid uri name
112112
[self openAPP:uri withCommand: command];
113-
113+
114114
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
115115
} else if (viewControllerName != nil || storyboardName != nil) {
116116
// Init viewController from Storyboard with initial view Controlleror or user defined viewControllerName
117117
[self instantiateViewController:viewControllerName fromStoryboard:storyboardName];
118-
118+
119119
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
120120
}
121-
121+
122122
} @catch (NSException *e) {
123123
NSLog(@"[%@]: %@", e.name, e.reason);
124-
124+
125125
typedef CDVCommandStatus (^CaseBlock)(void);
126-
126+
127127
CaseBlock c = self.resultExceptions[e.name];
128-
128+
129129
CDVCommandStatus exceptionType = c ? c() : CDVCommandStatus_ERROR;
130130
NSDictionary* error = @{
131131
@"success": @NO,
132132
@"name": e.name,
133133
@"message": e.reason
134134
};
135-
135+
136136
pluginResult = [CDVPluginResult resultWithStatus:exceptionType messageAsDictionary:error];
137137
}
138-
138+
139139
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
140140
}
141141

142142
- (void)showMarket:(CDVInvokedUrlCommand*)command {
143-
143+
144144
NSMutableDictionary* config = [command.arguments objectAtIndex:0];
145-
145+
146146
dispatch_async(dispatch_get_main_queue(), ^{
147-
147+
148148
CDVPluginResult *pluginResult;
149149
NSString *appId;
150-
150+
151151
if ([config isKindOfClass:[NSMutableDictionary class]]) {
152152
appId = [config objectForKey:@"marketId"];
153153
}else if([config isKindOfClass:[NSString class]]) {
154154
appId = (NSString *) config;
155155
}
156-
156+
157157
if (appId && [appId isKindOfClass:[NSString class]] && [appId length] > 0) {
158-
NSString *url = [NSString stringWithFormat:@"itms-apps://itunes.apple.com/app/%@", appId];
159-
158+
NSString *url = [NSString stringWithFormat:@"itms://itunes.apple.com/app/%@", appId];
159+
160160
[self openAPP:url withCommand: command];
161161

162-
return;
162+
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
163163
} else {
164164
NSDictionary* error = @{
165165
@"success": @NO,
166166
@"name": @"ParamInvalidException",
167167
@"message": @"Invalid application id: the parameter 'marketId' is invalid"
168168
};
169-
169+
170170
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_INVALID_ACTION messageAsDictionary:error];
171171
}
172-
172+
173173
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
174174
});
175175
}
176176

177177
- (void)checkIfAppInstalled:(CDVInvokedUrlCommand*)command {
178178
CDVPluginResult *pluginResult;
179179
NSString *uri;
180-
180+
181181
@try {
182182
NSMutableDictionary* config = [command.arguments objectAtIndex:0];
183-
183+
184184
if ([config isKindOfClass:[NSMutableDictionary class]]) {
185185
uri = [config objectForKey:@"uri"];
186-
186+
187187
if (uri == nil) {
188188
@throw [[NSException alloc] initWithName:@"ParamsTypeException" reason:@"The 'uri' key is required" userInfo:nil];
189189
}
@@ -192,15 +192,15 @@ - (void)checkIfAppInstalled:(CDVInvokedUrlCommand*)command {
192192
}else{
193193
@throw [[NSException alloc] initWithName:@"ParamsTypeException" reason:@"The params of checkIfAppInstalled() method needs be a string or a json" userInfo:nil];
194194
}
195-
195+
196196
if (![self isValidURI: uri]) {
197197
NSString *message = [[NSString alloc] initWithFormat:@"uri param invalid: %@", uri];
198198
NSDictionary* error = @{
199199
@"success": @NO,
200200
@"name": @"ParamInvalidException",
201201
@"message": message
202202
};
203-
203+
204204
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:error];
205205
} else {
206206
if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:uri]]) {
@@ -213,17 +213,17 @@ - (void)checkIfAppInstalled:(CDVInvokedUrlCommand*)command {
213213
@"name": @"NotFoundException",
214214
@"message": message
215215
};
216-
216+
217217
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_CLASS_NOT_FOUND_EXCEPTION messageAsDictionary:error];
218218
}
219219
}
220220
} @catch (NSException *e) {
221221
NSLog(@"[%@]: %@", e.name, e.reason);
222-
222+
223223
typedef CDVCommandStatus (^CaseBlock)(void);
224-
224+
225225
CaseBlock c = self.resultExceptions[e.name];
226-
226+
227227
CDVCommandStatus exceptionType = c ? c() : CDVCommandStatus_ERROR;
228228
NSDictionary* error = @{
229229
@"success": @NO,
@@ -239,23 +239,23 @@ - (void)checkIfAppInstalled:(CDVInvokedUrlCommand*)command {
239239
}
240240

241241
- (void) instantiateViewController:(NSString *)viewControllerName {
242-
242+
243243
NSString *message;
244-
244+
245245
if (viewControllerName && viewControllerName.length > 0) {
246-
246+
247247
UIViewController *destinyViewController = nil;
248-
248+
249249
// Call preInitializeViewControllerWithName if exists in self.viewController
250250
SEL selector = NSSelectorFromString(@"preInitializeViewControllerWithName:");
251-
251+
252252
if ([self.viewController respondsToSelector:selector]) {
253-
253+
254254
SuppressPerformSelectorLeakWarning(
255255
destinyViewController = [self.viewController performSelector:selector withObject:viewControllerName];
256256
);
257257
}
258-
258+
259259
// if not performSelector, call automatically the viewController
260260
if (!destinyViewController) {
261261
@try {
@@ -273,10 +273,15 @@ - (void) instantiateViewController:(NSString *)viewControllerName {
273273
@throw [[NSException alloc] initWithName:@"NotFoundException" reason:message userInfo:nil];
274274
}
275275
}
276-
276+
277277
// Call destinyViewController from current viewController
278-
[self.viewController.navigationController pushViewController:destinyViewController animated:YES];
279-
278+
if (self.viewController.navigationController) {
279+
[self.viewController.navigationController pushViewController:destinyViewController animated:YES];
280+
} else {
281+
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:destinyViewController];
282+
self.viewController.view.window.rootViewController = nav;
283+
}
284+
280285
} else {
281286
message = [[NSString alloc] initWithFormat:@"UIViewController with name %@ was not found", viewControllerName];
282287
@throw [[NSException alloc] initWithName:@"ParamInvalidException" reason:message userInfo:nil];
@@ -287,29 +292,29 @@ - (void) instantiateViewController:(NSString *)viewControllerName {
287292
}
288293

289294
- (void) instantiateViewController:(NSString *)viewControllerName fromStoryboard:(NSString *)storyboardName {
290-
295+
291296
NSString *message;
292-
297+
293298
if (storyboardName && storyboardName.length > 0) {
294-
299+
295300
UIViewController *destinyViewController = nil;
296-
301+
297302
// Call preInitializeViewControllerWithName:fromStoryBoardName if exists in self.viewController
298303
SEL selector = NSSelectorFromString(@"preInitializeViewControllerWithName:fromStoryBoardName:");
299-
304+
300305
if ([self.viewController respondsToSelector:selector]) {
301-
306+
302307
SuppressPerformSelectorLeakWarning(
303308
destinyViewController = [self.viewController performSelector:selector withObject:viewControllerName withObject:storyboardName];
304309
);
305310
}
306-
311+
307312
// if not performSelector, call automatically the viewController from storyboard
308313
if (!destinyViewController) {
309314
// initialize a storyboard automatically from viewControllerName or default initialViewController property
310315
@try {
311316
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle:[NSBundle mainBundle]];
312-
317+
313318
if (viewControllerName && viewControllerName.length > 0) {
314319
message = [[NSString alloc] initWithFormat:@"Identity -> Storyboard ID: %@ not found in storyboard %@", viewControllerName, storyboardName];
315320
// if pass a viewControllerName, initializate the storyboard with viewControllerName initial
@@ -324,10 +329,15 @@ - (void) instantiateViewController:(NSString *)viewControllerName fromStoryboard
324329
@throw [[NSException alloc] initWithName:@"NotFoundException" reason:detailMessage userInfo:nil];
325330
}
326331
}
327-
332+
328333
// Call destinyViewController from current viewController
329-
[self.viewController.navigationController pushViewController:destinyViewController animated:YES];
330-
334+
if (self.viewController.navigationController) {
335+
[self.viewController.navigationController pushViewController:destinyViewController animated:YES];
336+
} else {
337+
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:destinyViewController];
338+
self.viewController.view.window.rootViewController = nav;
339+
}
340+
331341
} else {
332342
message = [[NSString alloc] initWithFormat:@"Storyboard %@ was not found", storyboardName];
333343
@throw [[NSException alloc] initWithName:@"ParamInvalidException" reason:message userInfo:nil];
@@ -342,33 +352,30 @@ - (bool) isValidURI:(NSString *)uri {
342352
}
343353

344354
- (void) openAPP:(NSString *)uriValue withCommand:(CDVInvokedUrlCommand*) command {
345-
355+
346356
if ([[UIApplication sharedApplication] respondsToSelector:@selector(openURL:options:completionHandler:)]) { // ios >= 10
347357
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:uriValue] options:@{} completionHandler:^(BOOL opened) {
348-
358+
349359
CDVPluginResult *pluginResult;
350-
360+
351361
if (!opened) {
352-
353362
NSString* message = @"APP with uri %@ not found.";
354363
NSLog(message, uriValue);
355-
364+
356365
NSDictionary* error = @{
357366
@"success": @NO,
358-
@"name": @"NotFoundException",
367+
@"name": @"InstantiationException",
359368
@"message": [[NSString alloc] initWithFormat:message, uriValue]
360369
};
361-
362-
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_INSTANTIATION_EXCEPTION messageAsDictionary:error];
363370

371+
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_INSTANTIATION_EXCEPTION messageAsDictionary:error];
364372
} else {
365373
NSString* message = @"APP with uri %@ opened.";
366374
NSLog(message, uriValue);
367-
375+
368376
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:[[NSString alloc] initWithFormat:message, uriValue]];
369377
}
370378

371-
[pluginResult setKeepCallbackAsBool:YES];
372379
[self.commandDelegate sendPluginResult:pluginResult callbackId: command.callbackId];
373380
}];
374381
} else { // ios < 10 (Will be depreciated)

0 commit comments

Comments
 (0)