PhoneGap + ChildBrowser – Opening all non-app links in ChildBrowser
I’ve been working on a PhoneGap project with iPad as the target. Most of the app runs from an external site so after presenting local files to handle the login form and authentication the main webview then shifts to an external site where the rest of the code runs.
We are using ChildBrowser to handle showing images and PDF files from the external site so that we can don’t have to include a navigation bar in our app. The ChildBrowser plugin helps us view those files without getting locked out of the original app. That’s just the background. Now we have a new problem. Many pages in this app link to external sites that are not part of the main application. We needed ChildBrowser to handle all non-app site requests automatically so that external sites would open in the popup and not replace the view in the main UIWebView of PhoneGap. Here is how we solved it:
We started with the PhoneGap.plist preferences file. In the ExternalHosts array within that plist we added all the possible host combinations that our app considers as local to the app. This app has about seven url host variants that could be used within the app so all of those should open in the main WebView. Any host not listed in ExternalHosts should open in the ChildBrowser. Keep in mind that to allow all external sites to open we still had to put * as an entry in ExternalHosts but this doesn’t affect the logic below.
In AppDelegate.m didFinishLaunchingWithOptions method I added this logic to load the PhoneGap.plist into a Dictionary and read the ExternalHosts into an array. If anyone can tell me this is already loaded somewhere and I could have skipped this step let me know in the comments:
NSDictionary *phoneGapPrefs = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"PhoneGap" ofType:@"plist"]];
self.internalUrls = [[NSArray alloc] initWithArray:[phoneGapPrefs objectForKey:@"ExternalHosts"]];
I’m assuming you know how to create the internalUrls variable as an instance variable in AppDelegate.h. Now I have an array of all my internal host names so that any requests that don’t match that are loaded in ChildBrowser. Now we proceed down to the shouldStartLoadWithRequest method where I add this logic to check if we’re loading an external site (starts with http) and check if that site is part of our internalUrls array.
if ([[url scheme] isEqualToString:@"http"] || [[url scheme] isEqualToString:@"https"]) {
//This code will open any url that is not in the PhoneGap whitelist in Child Browser
if (![m3Urls containsObject:[url host]])
{
[theWebView sizeToFit];
ChildBrowserViewController* childBrowser = [ [ ChildBrowserViewController alloc ] initWithScale:FALSE ];
childBrowser.modalPresentationStyle = UIModalPresentationFormSheet;
childBrowser.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[super.viewController presentModalViewController:childBrowser animated:YES ];
NSString* urlString=[NSString stringWithFormat:@"%@",[url absoluteString]];
[childBrowser loadURL:urlString];
[childBrowser release];
return NO;
}
return YES;
}
Now all urls that start with http or https as the scheme and are not in the ExternalHosts I’ve listed are considered external to our app and are loaded in ChildBrowser. At this point you might tell me that since I’m listing * as a valid ExternalHost I don’t need to list all the site-specific urls and you’d be correct as far as avoiding the whitelist. During initial development I didn’t even anticipate opening non-site urls so all I wanted to list were the site-specific urls for this app. Later on I added the * for allowing any url, but realize that listing all my internal app urls provided an easy way to accomplish my need to determine which urls were for my app and which were references to non-app sites.

August 23rd, 2012 at 8:04 am
Thanks for the great guide! I just have one question, where did you put the code-part “..open every link in childbrowser”?
I want my application to open EVERY external url in the childbrowser.
Thanks in advance,
Stefan
September 15th, 2012 at 2:43 pm
Hello davidethell,
Thanks for sharing good info,
i am working on ios project using 1.8.1CDV and childbrowser / jquery mobile /
on Device ready load all the links from local www/ index.html
i have 8 https links that i want to connect using your method i don’t want to use Child browser
my question is if i used internal links how to handle back the button to local www/index.html (ios)
currently i used childbrowser ExternalHosts (*) to handle but i like your solution
could you please share with me some more example code that could be great help i am very new in to C#
Thanks in advance
Abdul H
September 24th, 2012 at 1:01 pm
[...] PhoneGap + ChildBrowser – Opening all non-app links in ChildBrowser [...]
October 15th, 2012 at 4:54 pm
Would you be willing to post how to create the internalUrls variable as an instance variable in AppDelegate.h?
Thanks