Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Need content in UIWebView to display quickly

Part of my app caches web pages for offline viewing. To do that, I am saving the HTML fetched from a site and rewriting img urls to point to a file on the local store. When I load the html into a UIWebView, it loads the images as expected and everything's fine. I am also caching stylesheets in this fashion.

The problem is that when I put the phone into airplane mode, loading this cached html causes the UIWebView to display a blank screen and pause for a while before displaying the page. I've figured out that it's caused by non-cached URLs referenced from the original HTML doc that the web view is trying to fetch. These other URLs include images within the cached stylesheets, content in iframes, and javascript that opens a connection to fetch other resources. The pause happens when the UIWebView tries to fetch these resources, and the web page only appears after all these other fetches have timed out.

My questions is, how can I make UIWebView just display the stuff I've cached immediately? Here are my thoughts:

  • write even more code to cache these other references. This is potentially a ton more code to catch all the edge cases, etc., especially having to parse the Javascript to see what it loads after the page is loaded
  • force UIWebView to time out immediately so there's no pause. I haven't figured out how to do this.
  • somehow get what's already loaded to display even though the external references haven't finished fetching yet
  • strip the code of all scripts, link tags and iframes to "erase" the external references. I've tried this one, but for some sites, the resultant page is severely messed up

Can anyone help me here? I've been working on this forever, and am running out of ideas.

like image 489
leftspin Avatar asked Aug 07 '09 18:08

leftspin


2 Answers

Edit: Just pointing out that this question, and its answers, are 4 years old. I'm chatting about iOS 3.x below. I can easily imagine that things have changed in the meantime -- heck, the devices alone are faster than the iPhone 3G was. YMMV. :)

I've been looking at this myself for the past while, not actually implementing anything yet, just Googling. It seems overall that it's very hard / impossible to do this on the iPhone using DontLoad. Even in March, there were reports that it works in Simulator, but not on device: http://discussions.apple.com/message.jspa?messageID=9245292

I'm just guessing, but based on even other StackOverflow questions (e.g. this one) I'm thinking perhaps the on-device caching is somehow more limited than both its Mac and Safari counterparts.

Others on the Apple forums report experiences with rude engineers when asking about UIWebView and NSURLCache, where in bug reports the engineers say it should work, but actual developers say it doesn't. http://discussions.apple.com/thread.jspa?threadID=1588010 (Jul 29-Aug 20)

Some solutions might be found here. Considering [UIImage imageWithData:...], David describes some code for "an implementation of an asynchronous, caching image downloader for iPhone."

And now I've discovered this Aug 10th email on the cocoa-dev mailing list:

On Aug 10, 2009, at 1:38 PM, Mike Manzano wrote:

Has anyone been able to successfully get the URL loading system on iPhone to pay attention to custom versions of NSURLCache? It seems to me that it's being ignored. More info here:

[a link to this page; removed.]

(See the second "answer" on that page).

Just need some sort of clue if I'm doing something wrong or if my code's just being ignored.

Yes, I've had it work - it just requires making your own cache instance and explicitly setting the shared cache to that new instance.

But it absolutely did work - once implemented, my "set the table view cell's image to an image from the net" works nicely (and without it scrolling was painful at best).

Glenn Andreas gandreas@xxxxxxxxxxxx http://www.gandreas.com/ wicked fun! Mad, Bad, and Dangerous to Know

The above email can be found at http://www.cocoabuilder.com/archive/message/cocoa/2009/8/10/242484 (with no further replies)

Further proof that NSURLCache can work is found in iCab Blog: URL filtering for UIWebView on the iPhone (Aug 18, 2009)

Anyone here probably should also look to Apple's URLCache sample app as it may be relevant to their work: https://developer.apple.com/iphone/library/samplecode/URLCache/index.html Except having just looked at it now, it says "This application does not use a NSURLCache disk or memory cache, so our cache policy is to satisfy the request by loading the data from its source." and uses cachePolicy:NSURLRequestReloadIgnoringLocalCacheData. So this is less relevant than I thought, and why this person was calling NSURLCache a joke.

So it seems NSURLCache is not as tricky or impossible as I started this post by saying. Gotta love finding a way that works while researching reasons it won't work. I still can't believe there are only 25 Google search results for "iphone" and "NSURLRequestReturnCacheDataDontLoad"... This answer has just about every one of em. And I'm glad I wrote it so I can refer to it later ;-)

like image 128
Louis St-Amour Avatar answered Sep 22 '22 17:09

Louis St-Amour


Generate a NSURLRequest with +requestWithURL:cachePolicy:timeoutInterval:. Set the cache policy to NSURLRequestReturnCacheDataDontLoad. Load the request into the webview using -loadRequest:. Full docs here.

like image 25
Rob Napier Avatar answered Sep 22 '22 17:09

Rob Napier