19

Greetings! Can anyone please kindly assist me finding a way around the following:

  • load an html into a UIWebView using loadHTMLString and include(using baseURL) the resources such as the CSS, image files from folders within user's Documents directory - and not from the MainBundle of the application.

I have seen tutorials on how to use baseURL to load within the application bundle/MainBundle which is straightforward but not with resources from the iPhone's Documents directories.

The structure of my documents folder is as follows:

dirX 
|---> file.xml 
|---> dirCSS 
      |---> style.css

I can retrieve the full path to the dir X(Users/......./dir X). However, when passing that path to the UIWebView's baseURL such that

[webView loadHTMLString:fileXMLString baseURL:pathToDirX]

... webView does not recognize the resources(eg style.css within dirCSS) as href'ed within the fileXMLString

<link href="dirCSS/style.css" rel="stylesheet" />

So currently my application can successfully load the html string but does not load the stylesheet as the link to the CSS within the html string are relative - eg. css/style.css

Any help is very much appreciated :)

oonoo
  • 618
  • 1
  • 9
  • 14

3 Answers3

25

After some googling I have finally found a fitting solution for the question I posed. Hopefully this would help those who face the same problem.

The trick is with the formatting of the string path when creating an NSURL object for baseURL of a UIWebView. Although usually I use the typical "Users/...../dir/file" in most cases, loading using UIWebView's loadHTMLString:baseURL needs a different approach.

As described in http://dblog.com.au/iphone-development/loading-local-files-into-uiwebview/, where I got the solution, string path to the resources just needs to have slashes to be replaced with double-slashes and spaces with %20:

NSString *imagePath = [[NSBundle mainBundle] resourcePath];
imagePath = [imagePath stringByReplacingOccurrencesOfString:@"/" withString:@"//"];
imagePath = [imagePath stringByReplacingOccurrencesOfString:@" " withString:@"%20"];

NSString *HTMLData = @"
<h1>Hello this is a test</h1>
<img src="sample.jpg" alt="" width="100" height="100" />";
[webView loadHTMLString:HTMLData baseURL:
           [NSURL URLWithString: 
           [NSString stringWithFormat:@"file:/%@//",imagePath]
           ]];

Do take note of the replacing of the strings and also the:

[NSString stringWithFormat:@"file:/%@//",imagePath]

Although the example code above is retrieving the path to the mainBundle of the application, it can also work in other folders, ie Documents(and its subfolders) as I did in mine.

Kind regards, oonoo

PS Thanks again Nic for the reply :)

oonoo
  • 618
  • 1
  • 9
  • 14
  • 1
    You can add percent escapes using stringByAddingPercentEscapesUsingEncoding: method of NSString. – ddnv Feb 03 '11 at 16:53
  • This posting helped me very much. Thank you for this! ;-) – andi1984 Jan 26 '12 at 11:25
  • This is loading from the app bundle, not from the Documents directory. The page you linked to is also talking about loading from the bundle. – Glenn Maynard Jun 26 '12 at 23:40
  • 1
    This is very hacky code. You should use [NSURL fileURLWithPath:] or -[NSBundle resourceURL] instead of manually hacking file urls and percent escapes. – Mike Weller Jul 20 '12 at 10:32
  • 1
    In my testing (iOS 6 SDK) `-[NSURL fileURLWithPath:]` doesn't work, nor does `-[NSURL fileURLWithPath:isDirectory:]` with `isDirectory:YES`. They seem to construct a URL including `localhost` which then fails to load. – Poulsbo Oct 05 '12 at 19:44
12

To get the path to the document directory:

NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask ,YES );
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"index.xml"];
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:path]]]

The easiest way to have everything working, is to simply load your index.html from the document directory instead of loading a string. Otherwise set the baseUrl to the document directory.

  • Thanks Nicolas for prompt response! I already tried using that documents directory path but UIWebView's baseURL doesn't seem to get it right and does not load the CSS/images from the documents directory. Actually I have two things – oonoo Dec 18 '09 at 03:44
  • Yup in fact I have no problems with loading the html directly with loadRequest because it easily puts up the images and css nicely but had trouble with its speed. Since I'm loading from within the iPhone documents folder the loadHTMLString seems ideal and actually load the html string easily except that.. yea, can't get the css and images loaded. – oonoo Dec 18 '09 at 04:09
1
 // call this method and set the directory , Currently it is cache directory . If you want document directory then change NSCacheDirectory to NSDocumentDirectory

-(NSString*)getBasePath
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory,
                                                     NSUserDomainMask, YES);
NSMutableString *cacheDirectory = [NSMutableString stringWithString:[paths objectAtIndex:0]];

[cacheDirectory appendString:@"/"];
NSRange renge= NSMakeRange(0, cacheDirectory.length);
[cacheDirectory replaceOccurrencesOfString:@"/" withString:@"//" options:NSCaseInsensitiveSearch range:renge];
renge= NSMakeRange(0, cacheDirectory.length);
[cacheDirectory replaceOccurrencesOfString:@" " withString:@"%20" options:NSCaseInsensitiveSearch range:renge];
[cacheDirectory insertString:@"file://" atIndex:0];
//file:////Users//hb//Library//Application%20Support//iPhone%20Simulator//6.0//Applications//3A141D33-390A-4DD2-8825-7DDC07D29894//Library//Caches//
return cacheDirectory;

}

iKushal
  • 2,689
  • 24
  • 20