44 Comments

Updating PhoneGap’s ChildBrowser Plugin to Handle Local Files

Recently, I have been working on an iPad sales tool application with Shawn Crowley and Marissa Christy. We are using a framework called PhoneGap to build the application. PhoneGap allows us to write the majority of the app using HTML and JavaScript.

HTML and JavaScript have been excellent for 95% of the application, but these two features are more cleanly implemented using the built-in iOS widgets.

  1. Email Support
  2. PDF Display Support

It turns out that our needs for this functionality are not uncommon.

Matt Kane created a github project called phonegap-plugins that solves both of these problems.

https://github.com/phonegap/phonegap-plugins.git

Thanks for the plugins Matt, they have been a great help.

We used the EmailComposer plugin to solve the email support feature and the ChildBrower plugin to solve the pdf display support feature. The EmailComposer plugin solved our need with no additional changes. The ChildBrowser plugin, however, needed to be slightly modified to fit our use-case.

The ChildBrowser plugin allows external webpages to be displayed within a PhoneGap application. This is exactly the functionality we wanted to render our pdf files, but the ChildBrower plugin was designed to load external files not local files that are distributed with the app.

We made the following additions to the ChildBrower plugin to allow it load local pdf files.

Client JavaScript Code:

// load the child browser with the full path of our pdf relative to the root of our xcode project
window.plugins.childBrowser.showWebPage("www/assets/folder/file.pdf");

Updated ChildBrowserCommand.m:


- (void) showWebPage:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options // args: url
{  
  if(childBrowser == NULL)
  {
    childBrowser = [[ ChildBrowserViewController alloc ] initWithScale:FALSE ];
    childBrowser.delegate = self;
  }
  
  /* // TODO: Work in progress
  NSString* strOrientations = [ options objectForKey:@"supportedOrientations"];
  NSArray* supportedOrientations = [strOrientations componentsSeparatedByString:@","];
  */

  PhoneGapViewController* cont = (PhoneGapViewController*)[ super appViewController ];
  childBrowser.supportedOrientations = cont.supportedOrientations;
  [ cont presentModalViewController:childBrowser animated:YES ];
  
  NSString *path = (NSString*) [arguments objectAtIndex:0];
  
  // ADDED Code
  // This breaks apart the path and uses the pathForResource method to correctly find the resource
  // in the bundle.
  NSString *ofType = [path pathExtension];
  NSString *pathForResource = [[[path lastPathComponent] componentsSeparatedByString:@"."] objectAtIndex:0];
  NSString *inDirectory = [path stringByDeletingLastPathComponent];
  
  NSString *url = [[NSBundle mainBundle] pathForResource:pathForResource 
                          ofType:ofType 
                          inDirectory:inDirectory];
    
  [childBrowser loadURL:url];

}

Updated ChildBrowserViewController.m


- (void)loadURL:(NSString*)url
{
  NSLog(@"Opening Url : %@",url);

  imageURL = @"";
  isImage = NO;
  // ADDED Code
  // use fileURLWithPath method instead
  NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL fileURLWithPath:url]];
  [webView loadRequest:request];

  webView.hidden = NO;
}