18

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>
Isaac Waller
  • 32,709
  • 29
  • 96
  • 107
  • 3
    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 Jun 08 '10 at 01:52

10 Answers10

26

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!

Joe D'Andrea
  • 5,141
  • 6
  • 49
  • 67
  • works awesome thanks for posting... this should be the right answer – samiq May 13 '10 at 07:06
  • 1
    Y'know … now that I look at what I wrote again, I wonder if I made a faux pas by using "file:/%@//" instead of "file://%@/" ? That might be the inadvertent source of the / to // requirement, in which case it's only a matter of handling spaces, which is standard-issue S/G/HTML stuff. Thoughts? (It has been a while, so if I'm forgetting my own logic here, feel free to correct me - ha!) – Joe D'Andrea May 17 '10 at 17:59
  • 1
    Had the same problem just now in iOS 4.2. Local images were not displayed. Then I ended up formatting my URL like this (quadruple slashes!) and it works: "file:////Users//iDeveloper//Library//Application%20Support//iPhone%20Simulator//4.2//Applications//9706B7FE-4FAC-4FB0-9DA4-C07F322D4AC1//TestBrowser.app//Data//HTML//English//". Using the "correct" syntax with one slash in the path and two slashes for "file://" does NOT work. Thank You a lot! – Krumelur Apr 20 '11 at 12:34
14

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.

August
  • 12,139
  • 3
  • 29
  • 30
7

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

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

Thank you!

Isaac Waller
  • 32,709
  • 29
  • 96
  • 107
3

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]
Chris Lundie
  • 6,023
  • 2
  • 27
  • 28
2

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];
Michael Gaylord
  • 7,282
  • 8
  • 50
  • 47
1

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">
Ed Marty
  • 39,590
  • 19
  • 103
  • 156
0

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 :)

Community
  • 1
  • 1
Howard Pautz
  • 415
  • 7
  • 21
0

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.

ceejayoz
  • 176,543
  • 40
  • 303
  • 368
0

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.....?

Isaac Waller
  • 32,709
  • 29
  • 96
  • 107
0

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

kolyuchiy
  • 5,465
  • 2
  • 23
  • 31