18
votes

I have a webview in my iPhone application, and I also have some html files inside my Resources folder. When my app loads, I load in a page from my resources into my webview. But , I need to make links inside my webview that point to some other resources (For example, images, or other html files). Just doing a relative link doesn't work:

<a href="OtherPage.html">Doesn't work</a>
10
Do you mind giving a full example of the code that works? Reading this page thoroughly, I'm still a bit confused about how to put it all together properly. Thanks.mwt

10 Answers

26
votes

Apparently there's a bit of a gotcha according to the iPhone SDK Release Notes for iPhone OS 3.0:

Issue: UIWebView can't load local resources in apps built against 3.0.

When using [UIWebView loadHTMLString:baseURL:], the HTML string should not refer to local resources with the file:// scheme. Instead, pass in NULL or a file:// URL for baseURL:, or include the resources directly in the HTML with <style> and <script> tags.

Fair enough. But passing in a standard-issue file:// URL for baseURL doesn't quite work. However ... it turns out that, if you change / to // and spaces to %20, you will be set! (Using %20 makes a lot of sense, but the double-slash part caught me by surprise.)

Let's say you already have NSString *markup set up. Here's all you do. (I've wrapped the code here for readability. You may wish to refactor/adjust to taste.)

 NSString *resourcePath = [[[[NSBundle mainBundle] resourcePath]
     stringByReplacingOccurrencesOfString:@"/" withString:@"//"]
     stringByReplacingOccurrencesOfString:@" " withString:@"%20"];
 [webView loadHTMLString:markup baseURL:[NSURL URLWithString:
     [NSString stringWithFormat:@"file:/%@//", resourcePath]]];

So long as your CSS, JavaScript and images are referred to by filename alone, this should do the trick in iPhone OS 3.0 where loadHTMLString:baseURL: is concerned!

14
votes

When you load those resources, you need to set the base URL. You can do this using the method:

- (void)loadHTMLString:(NSString *)string baseURL:(NSURL *)baseURL

...where baseURL would be the file URL of your resources folder.

7
votes

I fixed it: I used this for the BaseURL like August said:

NSString *path = [[NSBundle mainBundle] bundlePath];
NSURL *baseURL = [NSURL fileURLWithPath:path];

Thank you!

3
votes

This code would return a string with the URL of a file named "OtherPage.html" in your bundle's resources directory.

[[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"OtherPage" ofType:@"html"]] absoluteString]
2
votes

This worked for me. My HTML files were in sub-folders (not groups) in my project. My html page is called page01 and the sub-folder is html:

NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
NSString *pathToHtml = @"html";
NSURL *baseURL = [[NSURL alloc] initFileURLWithPath:pathToHtml isDirectory:YES];

NSString *html = [NSString stringWithContentsOfFile:[[NSBundle mainBundle]    
                             pathForResource:@"page01" ofType:@"html"                                                               
                             inDirectory:@"html"] 
                         encoding:NSUTF8StringEncoding error:nil];
[webview loadHTMLString:html baseURL:baseURL];
1
votes

Try loading OtherPage.html first. If you can't then it's not there, and you've missed some part of adding it to the project. If you can, then there may just be a typo in the link, or the baseURL could be incorrect, as stated by August. When I created an html file with images in it that were in the resource file, it worked fine just using

<img src="file.png">
0
votes

Take a look at how Phonegap does it. Here's their tutorial on local resources on the iPhone. Step 11 might be what you're neglecting.

0
votes

Maybe it does have something to do with the baseurl: when I load the resources, I use this line:

[webView loadData:htmlData MIMEType:@"text/html" textEncodingName:@"UTF-8" baseURL:[NSURL URLWithString:@""]];

see at the end, it says baseURL: "". If I take this out, it doesn't work (crashes), but I don't know the path to my resources. If somebody does.....?

0
votes

For me the problem was that js files were not included in the bundle. Be sure to check that.

0
votes

OK, here 3.5 years later :) ... tried Michael Gaylord's suggestion above exactly, but it didn't work in sims for 5.0, 5.1, 6.0, 6.1 - nor in real devices running same. However this SO clarification on where resources are bundled ( Where is build output going? ) helped make it work for me like this:

  1. create a Finder folder in the project ( as Michael suggests - and I also did NOT try 'group')
  2. put your html in that folder using Finder
  3. in Xcode use file -> add files to project
  4. Make sure the project recognizes that it should be in the bundle by:

    1. Right click on main project target in Navigator window,
    2. make sure TARGETS is selected, the Build Phases tab,
    3. Click the Copy Bundle Resources triangle thingy |>
    4. And - here's what's different from Michael's - It should already show your html file AND the path. (Perhaps the XCoders have improved the add files AI :)

So all I had to do was copy - paste Michael's code above verbatum and change this one line:

                     inDirectory:@"html"] 

to:

                     inDirectory:nil]

and Shaazam ! it worked :)