你能否在UIWebView中拦截NSURLRequests而不会破坏后退按钮?

我无法在不破坏goBack方法的情况下将自定义HTML加载到我的UIWebView

什么有用

我正在拦截我的UIWebView的URL请求,所以我可以加载自定义HTML。 我可以控制所有的HTML,所以我有我的特殊应用程序请求使用我可以在webView:shouldStartLoadWithRequest:navigationType:解析的自定义方案(即myapp://arg1/?arg2=valwebView:shouldStartLoadWithRequest:navigationType: . 我决定加入什么HTML,并调用loadHTMLString:baseURL并返回NO以取消原始请求。

什么行不通

以上工作很棒。 问题是我想使用UIWebView's goBack方法和loadRequest:似乎是唯一添加到其历史堆栈的UIWebView方法。

我有一些想法,但我不确定哪些是可行的以及如何解决它们。 主要似乎是我必须在webView:shouldStartLoadWithRequest:navigationType返回YES webView:shouldStartLoadWithRequest:navigationType ,我必须使用UIWebViewloadRequest方法。

想法1:修改NSURLRequest / Response:我可以将NSURLRequest子类化,以便(当UIWebView发出请求时)它实际上不会发出HTTP请求并返回带有我的HTML的NSURLResponse吗? 或者可能以某种方式修改/子类/将类别方法添加到NSURLResponse? 我喜欢它是一个真正的请求,但我担心私有API并被App Store拒绝。

想法2:处理自定义URL协议注册自定义URL协议,以便我的应用程序响应它,我可以让它返回合法的NSURLResponse(填充我的自定义HTML。)

想法3:愚弄缓存使用此缓存策略创建请求NSURLRequestReturnCacheDataDontLoad然后以某种方式在webView和缓存之间获取我的HTML?

或许我完全走错了轨道?

我刚刚测试了另一种非常聪明的方法:只需创建一个自定义NSURLProtocol ,而不是修改NSURLCache或重写整个导航历史代码,只要创建HTTP请求,标准NSURLConnection就会使用它。 在那里,您可以创建自己的NSURLRequest来加载数据,并可以检查MIME类型,更改请求的内容或根据需要将数据缓存到磁盘。 这个想法来自Rob Napier:

http://robnapier.net/blog/offline-uiwebview-nsurlprotocol-588

他的代码现在也在GitHub上:

https://github.com/rnapier/RNCachingURLProtocol

我首先尝试走#3路线。 也许在Cocoa with Love上“用本地数据代替远程UIWebView请求”对你有帮助。

我建议不要采用任何上述方法。

我有#3工作,但它非常,非常脆弱,很难调试。 (例如,Apple会破坏并重新创建NSURLRequests ,因此您不能只是inheritanceNSURLRequest并期望在后续响应中完成。)

它最终(我)更容易回到自己的历史记录,并注意要加载的页面和滚动位置(垂直屏幕偏移)。