Search code examples
ioscocoa-touchuiwebviewnsurlrequest

Can you intercept NSURLRequests in a UIWebView without breaking the back button?


I'm having trouble loading custom HTML into my UIWebView without breaking its goBack method.

What Works

I'm intercepting the URL requests of my UIWebView so I can load custom HTML. I have control over all the HTML, so I have my special app requests use a custom scheme (ie. myapp://arg1/?arg2=val) that I can parse in webView:shouldStartLoadWithRequest:navigationType:. I decide what HTML I really want to load and call loadHTMLString:baseURL and return NO to cancel the original request.

What Doesn't Work

The above works great. The problem is that I want to make use of the UIWebView's goBack method and loadRequest: appears to be the only UIWebView method that adds to its history stack.

I have a few ideas, but I'm not sure which are feasible and how to go about them. The main thing seems to be that I have to return YES in webView:shouldStartLoadWithRequest:navigationType and I have to use UIWebView's loadRequest method.

Idea 1: Modify NSURLRequest/Response: Can I subclass NSURLRequest so that (when the UIWebView makes the request) it doesn't actually make an HTTP request and returns an NSURLResponse with my HTML in it? Or maybe modify/subclass/add a category method to NSURLResponse somehow? I like the idea of it being a real request, but I'm concerned about private APIs and being rejected from the App Store.

Idea 2: Handle a custom URL Protocol Register a custom URL protocol so my app responds to it and I can have it return a legitimate NSURLResponse (filled with my custom HTML.)

Idea 3: Fool the cache Create the request with this cache policy NSURLRequestReturnCacheDataDontLoad and then somehow get my HTML in between the webView and the cache?

Or maybe I'm on the wrong track completely?


Solution

  • I would recommend against any of the above approaches.

    I got #3 working, but it was very, very fragile and hard to debug. (For example, Apple destroys and re-creates NSURLRequests, so you can't just subclass NSURLRequest and expect to come through in the subsequent response.)

    It ended up being (much) easier to my own back history and note what page to load and scroll position (vertical screen offset).