[ios] Load resources from relative path using local html in uiwebview

I have a very simple iOS app with a uiwebview loading a very simple test page (test.html):

<html>
<body>
<img src="img/myimage.png" />
</body>
</html>

I load this test.html file into my web view:

NSURL *url = [[NSBundle mainBundle] URLForResource:@"test" withExtension:@"html"];
NSString *html = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
NSURL *baseUrl = [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]];
[webView loadHTMLString:html baseURL:baseUrl];

This works fine if I reference the image without the relative path and put the referenced image in the root path under Targets -> Copy Bundle Resources within XCode, however I can't get it to work with the relative path as shown in my html file. There must be a way to do this, I have lots of images, css, javascript files that I want to load into the webview and I would like not to have to have everything in the root and have to change all the references in my web app.

This question is related to ios uiwebview

The answer is


In Swift 3.01 using WKWebView:

let localURL = URL.init(fileURLWithPath: Bundle.main.path(forResource: "index", ofType: "html", inDirectory: "CWP")!)
myWebView.load(NSURLRequest.init(url: localURL) as URLRequest)

This adjusts for some of the finer syntax changes in 3.01 and keeps the directory structure in place so you can embed related HTML files.


I crammed everything into one line (bad I know) and had no troubles with it:

[webView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"test" 
                                                                                                         ofType:@"html"]
                                                             isDirectory:NO]]];         

I've gone back and tested and re-tested this, it appears that the only way I can get it to work (since I have some files in the img folder and some in js/css, etc...) is not to use a relative path to my image in the html and have everything referenced to the bundle folder. What a shame :(.

<img src="myimage.png" />

Swift answer 2.

The UIWebView Class Reference advises against using webView.loadRequest(request):

Don’t use this method to load local HTML files; instead, use loadHTMLString:baseURL:.

In this solution, the html is read into a string. The html's url is used to work out the path, and passes that as a base url.

let url = bundle.URLForResource("index", withExtension: "html", subdirectory: "htmlFileFolder")
let html = try String(contentsOfURL: url)
let base = url.URLByDeletingLastPathComponent
webView.loadHTMLString(html, baseURL: base)

@sdbrain's answer in Swift 3:

    let url = URL.init(fileURLWithPath: Bundle.main.path(forResource: "index", ofType: "html", inDirectory: "www")!)
    webView.loadRequest(NSURLRequest.init(url: url) as URLRequest)

I simply do this:

    UIWebView *webView = [[[UIWebView alloc] init] autorelease];

    NSURL *url = [[NSBundle mainBundle] URLForResource:@"index" withExtension:@"html"];
    NSURLRequest* request = [NSURLRequest requestWithURL:url];
    [webView loadRequest:request];

Where "index.html" relatively references images, CSS, javascript, etc.


In Swift:

 func pathForResource(  name: String?, 
                        ofType ext: String?, 
                        inDirectory subpath: String?) -> String?  {

  // **name:** Name of Hmtl
  // **ofType ext:** extension for type of file. In this case "html"
  // **inDirectory subpath:** the folder where are the file. 
  //    In this case the file is in root folder

    let path = NSBundle.mainBundle().pathForResource(             "dados",
                                                     ofType:      "html", 
                                                     inDirectory: "root")
    var requestURL = NSURL(string:path!)
    var request = NSURLRequest(URL:requestURL)

    webView.loadRequest(request)
}