Among the most popular posts on this blog have been those about UIWebView. (The fact that it’s the #1 search result on Google for the term UIWebView might help. 🙂
Here’s I’d like to revisit the problem of displaying local images in a UIWebView. In this post I presented a little hack to embed small images into the HTML. While this may work in some cases, it’s far from an optimal solution. For example it does not address other types of external files you might want to refer to from your HTML.
Using relative paths or file: paths to refer to images does not work with UIWebView. Instead you have to load the HTML into the view with the correct baseURL:
NSString *path = [[NSBundle mainBundle] bundlePath]; NSURL *baseURL = [NSURL fileURLWithPath:path]; [webView loadHTMLString:htmlString baseURL:baseURL];
You can then refer to your images like this:
<img src="myimage.png">
Or from within CSS like this:
background-image: url(loading.gif)
It’s important to note that images inside your application bundle are at the root of the bundle, even if you place them in an Images directory in your project.
January 28th, 2009 at 06:03
If this works the way I think it does, it’s just what I’m looking for. The only question I have is where does the code go? I am a super beginner with Xcode, and I don’t know my way around it too well.
Where should this be going? In one of the Classes files?
NSString *path = [[NSBundle mainBundle] bundlePath];
NSURL *baseURL = [NSURL fileURLWithPath:path];
[webView loadHTMLString:htmlString baseURL:baseURL];
January 29th, 2009 at 22:35
@Jon: I typically place this code in viewWillAppear in the ViewController that has the UIWebView.
March 22nd, 2009 at 20:13
Thanks that’s working perfect 🙂
March 26th, 2009 at 07:42
Thanks so much for posting this. I thought I was going to have to do the ugly image data encoding solution instead, but this works much better!
May 4th, 2009 at 18:30
Hey, this trick works great; but only one problem, I can’t get webpages to run javascripts that read code from the URL using this method.
Basically I’m trying to run a script that takes a value from one pages and uses it on the next (both are stored locally). Normally I would just do it with a cookie, but as it stands right now, you can’t uses cookies with the UIWebView….
and suggestions would be great! Thanks!!
May 4th, 2009 at 19:55
@Dan: You can use stringByEvaluatingJavaScriptFromString to read and set JavaScript variables.
June 8th, 2009 at 15:33
Hi Nick, just wanted to stop by and say thanks! This is exactly what I was looking for 🙂
June 13th, 2009 at 09:27
Hi Nick. I am planning to grab images from a URL (using dataWithContentsOfURL) and and store them to my application Documents directory. Will I be able to access these images from my UIWebView with <img src=”abcd.jpg”> ?
June 13th, 2009 at 13:13
@Jimmy: Yes you can. What you need to do is to set baseURL to the Documents directory.
June 16th, 2009 at 19:26
Yup. Exactly what I was searching for. God bless internet and Nick.
July 7th, 2009 at 02:59
Thanks a ton!
July 7th, 2009 at 11:07
I’ve been working on this for several days, and I’m struggling the whole way.
What I’m trying to do is load a web page, modify it on the fly (to insert some CSS dynamically), and then display the page with the new code. This is working okay, the problem is that when I type in a user_id and click [submit], it immediately responds that the session has expired. What am I missing?
Thanks in advance!
Devguy
July 7th, 2009 at 11:38
@Devguy: If you are handling the response from the web server in your own code in order to modify it, and then you just load the modified HTML into the UIWebView, then you lose any HTTP header information, such as cookies. I can’t think of any easy solution to this.
July 10th, 2009 at 03:20
Thank you! This helps me a lot 🙂
August 18th, 2009 at 03:14
@Devguy : I’m also working on a project similar to yours .
How did you succeed to load the web page , modify the css and display it with the new code .
I’m a Xcode beginner so can you help me?
August 20th, 2009 at 20:08
There are a bunch of ways to do that. Easiest is via JavaScript – you can modify CSS that way – using the UIWebView’s -stringByEvaluatingJavaScriptFromString: method.
An alternative approach is to have your html reference a .css file and then modify the .css file before loading the html into the UIWebView. For example, in the view’s controller:
– (void)viewDidLoad {
[super viewDidLoad];
NSString *dcssPath = [[NSBundle mainBundle] pathForResource:@”Dynamic” ofType:@”css”];
[@”body { background-color: #ff0000; color:#ffffff; }” writeToFile:dcssPath atomically:YES encoding:NSUTF8StringEncoding error:NULL];
NSString *indexHtmlPath = [[NSBundle mainBundle] pathForResource:@”index” ofType:@”html”];
[frontView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:indexHtmlPath]]];
}
Then just include an index.html in your project’s Resources and have it reference the Dynamic.css file…
August 24th, 2009 at 01:37
Thanks Ezra ,
Can i do the same thing whith a web page (withou inserting a .html and .css in resources) .I mean to any page that we can open with webview?
August 24th, 2009 at 01:41
Can i also modify the content of the html and only keep the interesting parts?
September 4th, 2009 at 08:20
Is it possible to load remote HTML pages and have them access local images AND remote images? Like, I may have a folder icon that appears all over the place and I just want to load that locally. On the other hand, a user-submitted image on my webpage will of course not be stored locally and must be retrieved from the remote server.
Any ideas?
September 5th, 2009 at 22:02
@Dan: You can refer to images on your web page by an absolute URL, and images in your bundle by a relative URL (the image name).
September 4th, 2009 at 11:01
OK, this is weird. As soon as I use baseURL (as you’ve defined it – thanks!!!), if I use loadHTMLString:baseURL: the web view shows up empty … even though baseURL points directly to the bundle (trying this in the 3.0 simulator too). As soon as I make baseURL point elsewhere (like a web site), it shows up just fine, but it also doesn’t load any local resources – of course. Hmm …
September 4th, 2009 at 12:26
Ah-ha! “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 and tags.”
Reference: iPhone SDK Release Notes for iPhone OS 3.0
September 4th, 2009 at 12:27
But wait a sec – that IS what I’m doing. baseURL _is_ using a file scheme. Ugh. 🙁
September 8th, 2009 at 09:59
@Nick: No can do. Relative URLs do not work per the 3.0 SDK Release Notes (when using loadHTMLString:baseURL:). I even tried the Data variant. No dice. 🙁
September 8th, 2009 at 10:46
@Joe: Interesting, I was not aware of this change. Let me do some more thinking and see what else I can come up with.
September 8th, 2009 at 10:59
Just found what appears to be a good workaround for loading CSS!
http://dblog.com.au/iphone-development/loading-local-files-into-uiwebview/
October 5th, 2009 at 07:39
Thanks! This is exactly what I need!
January 31st, 2010 at 23:52
Does UIWebView cache the images loaded using img src tag. if so where do it cache in the iPhone and what is the time it keeps its content into its cache.
February 1st, 2010 at 13:29
@pramod: There seems to be a lot of confusion surrounding UIWebView and caching on the iPhone. I have not done any testing myself so unfortunately I cannot add any clarity. But this Stack Overflow entry seems to have the best overview of the situation.
March 16th, 2010 at 05:12
Hi All. If you are still interested in this topic I prepare an example in my blog and pointed the links to the blogs I used to build a page with local resources using UIWebView.
http://mentormate.com/blog/iphone-uiwebview-class-local-css-javascript-resources/
I hope this will save your time. I wm will be happy if you share your opinion on my blog.
May 6th, 2010 at 05:49
this works very well and fast but it does not load images if I give baseurl instead of nil. It takes few seconds to load.
NSURL *myUrl = [[NSURL alloc] initFileURLWithPath:self.contentPath];
//NSLog(@”Content url is %@”,myUrl);
NSString *string = [[NSString alloc]initWithContentsOfFile:self.contentPath encoding:NSASCIIStringEncoding error:nil];
[contentDisplay loadHTMLString:string baseURL:nil]; //here nil if replaced by myUrl webView takes time to load. Any help ?
[string release];
[myUrl release];
January 6th, 2011 at 11:51
Hello,
Great post, but I get this error: -[NSURL length]: unrecognized selector sent to instance
After loading the HTML, any ideas?
Thanks.
January 7th, 2011 at 15:03
@subharb: Not sure where that error comes from. I don’t see that method call in the code above.
June 18th, 2011 at 13:14
[…] See this post for an alternate way to display images: UIWebView – Loading External Images and CSS Categories: Windows & Views Tags: base64, HTML, […]
June 28th, 2011 at 23:34
It was helpfull
November 24th, 2011 at 20:15
Thanks a lot for this tip! It worked fine in my project! =)
January 18th, 2012 at 06:35
Hie, I m new going to develop a app for both Iphone & iPad using UlWebView. I m a web developer and thoght to make an intractive app, which I thought of make as offine browsing with contents.
but I saw some forums that apple no longer accepts webApps. is this ture??
thankss
January 23rd, 2012 at 09:54
@Sam: You can always develop and deploy web apps without Apple’s approval. Just put it up on your server and tell the world about it. If you want to create an app for distribution on the App Store then you need Apple’s approval. Apple is not so keen on native apps that are just web apps wrapped inside a UIWebView, and you may get rejected. It depends on the features of the app. If you can show that your app needs to be native because there are some features that cannot be implemented just using Safari, then approval should be easier.
February 29th, 2012 at 10:43
For some reason this doesn’t work for me. It just writes the string of the html page in my UIWebView:
NSString *path = [[NSBundle mainBundle] bundlePath];
NSURL *baseURL = [NSURL fileURLWithPath:path];
[webView loadHTMLString:@”tour.html” baseURL:baseURL];
Did I do that right?
June 26th, 2012 at 02:18
You saved my day… just that one line I was really struggling to get there..
Thank you
August 31st, 2012 at 02:33
Hi
i have tried all your codes you & others shared with this conversations, but it does not working for me .Can any one provide me the sample code with the external css & image files.
Thanks
December 30th, 2013 at 22:40
if have an html file ,have various divisions in that,seperated by division name.i want to load a specific division .How to do it?