Skip to content

Commit 5c05191

Browse files
committed
Add iOS support for postMessage API.
Fix iOS crashes due to UIWebView delegate not being released on closing the IAB
1 parent a543f59 commit 5c05191

File tree

1 file changed

+32
-6
lines changed

1 file changed

+32
-6
lines changed

src/ios/CDVThemeableBrowser.m

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,19 @@ - (void)openInSystem:(NSURL*)url
369369
}
370370
}
371371

372+
-(void)createIframeBridge
373+
{
374+
if (!_injectedIframeBridge) {
375+
_injectedIframeBridge = YES;
376+
// Create an iframe bridge in the new document to communicate with the CDVThemeableBrowserViewController
377+
NSString* jsIframeBridge = @"var e = _cdvIframeBridge = d.createElement('iframe');e.style.display='none';d.body.appendChild(e);";
378+
// Add the postMessage API
379+
NSString* jspostMessageApi = @"window.webkit={messageHandlers:{cordova_iab:{postMessage:function(message){_cdvIframeBridge.src='gap-iab://message/'+encodeURIComponent(message);}}}}";
380+
// Inject the JS to the webview
381+
[self.themeableBrowserViewController.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"(function(d){%@%@})(document)", jsIframeBridge, jspostMessageApi]];
382+
}
383+
}
384+
372385
// This is a helper method for the inject{Script|Style}{Code|File} API calls, which
373386
// provides a consistent method for injecting JavaScript code into the document.
374387
//
@@ -380,12 +393,6 @@ - (void)openInSystem:(NSURL*)url
380393

381394
- (void)injectDeferredObject:(NSString*)source withWrapper:(NSString*)jsWrapper
382395
{
383-
if (!_injectedIframeBridge) {
384-
_injectedIframeBridge = YES;
385-
// Create an iframe bridge in the new document to communicate with the CDVThemeableBrowserViewController
386-
[self.themeableBrowserViewController.webView stringByEvaluatingJavaScriptFromString:@"(function(d){var e = _cdvIframeBridge = d.createElement('iframe');e.style.display='none';d.body.appendChild(e);})(document)"];
387-
}
388-
389396
if (jsWrapper != nil) {
390397
NSData* jsonData = [NSJSONSerialization dataWithJSONObject:@[source] options:0 error:nil];
391398
NSString* sourceArrayString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
@@ -506,6 +513,22 @@ - (BOOL)webView:(UIWebView*)theWebView shouldStartLoadWithRequest:(NSURLRequest*
506513
}
507514
[self.commandDelegate sendPluginResult:pluginResult callbackId:scriptCallbackId];
508515
return NO;
516+
}else if ([scriptCallbackId isEqualToString:@"message"] && (self.callbackId != nil)) {
517+
// Send a message event
518+
NSString* scriptResult = [url path];
519+
if ((scriptResult != nil) && ([scriptResult length] > 1)) {
520+
scriptResult = [scriptResult substringFromIndex:1];
521+
NSError* __autoreleasing error = nil;
522+
NSData* decodedResult = [NSJSONSerialization JSONObjectWithData:[scriptResult dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:&error];
523+
if (error == nil) {
524+
NSMutableDictionary* dResult = [NSMutableDictionary new];
525+
[dResult setValue:@"message" forKey:@"type"];
526+
[dResult setObject:decodedResult forKey:@"data"];
527+
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dResult];
528+
[pluginResult setKeepCallback:[NSNumber numberWithBool:YES]];
529+
[self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
530+
}
531+
}
509532
}
510533
} else if ([self isSystemUrl:url]) {
511534
// Do not allow iTunes store links from ThemeableBrowser as they do not work
@@ -561,6 +584,7 @@ - (void)webViewDidStartLoad:(UIWebView*)theWebView
561584

562585
- (void)webViewDidFinishLoad:(UIWebView*)theWebView
563586
{
587+
[self createIframeBridge];
564588
if (self.callbackId != nil) {
565589
// TODO: It would be more useful to return the URL the page is actually on (e.g. if it's been redirected).
566590
NSString* url = [self.themeableBrowserViewController.currentURL absoluteString];
@@ -1167,6 +1191,7 @@ - (void)viewDidLoad
11671191
- (void)viewDidUnload
11681192
{
11691193
[self.webView loadHTMLString:nil baseURL:nil];
1194+
self.webView.delegate = nil;
11701195
[CDVUserAgentUtil releaseLock:&_userAgentLockToken];
11711196
[super viewDidUnload];
11721197
}
@@ -1182,6 +1207,7 @@ - (void)close
11821207

11831208
[CDVUserAgentUtil releaseLock:&_userAgentLockToken];
11841209
self.currentURL = nil;
1210+
self.webView.delegate = nil;
11851211

11861212
if ((self.navigationDelegate != nil) && [self.navigationDelegate respondsToSelector:@selector(browserExit)]) {
11871213
[self.navigationDelegate browserExit];

0 commit comments

Comments
 (0)