你能在不破坏后退按钮的情况下拦截 UIWebView 中的 NSURLRequests 吗?
我无法将自定义 HTML 加载到我的 UIWebView
中而不破坏其 goBack
方法。
有效方法
我正在拦截 UIWebView
的 URL 请求,以便可以加载自定义 HTML。我可以控制所有 HTML,因此我的特殊应用程序请求使用自定义方案(即 myapp://arg1/?arg2=val
),我可以在 webView 中解析该方案: shouldStartLoadWithRequest:navigationType:
。我决定我真正想要加载的 HTML 并调用 loadHTMLString:baseURL
并返回 NO
以取消原始请求。
什么不起作用
上面的效果很好。问题是我想利用 UIWebView 的
goBack
方法,而 loadRequest:
似乎是唯一的 UIWebView
添加到其历史堆栈的方法。
我有一些想法,但我不确定哪些可行以及如何实施。主要的事情似乎是我必须在 webView:shouldStartLoadWithRequest:navigationType
中返回 YES
并且我必须使用 UIWebView
的 loadRequest 方法。
想法1:修改NSURLRequest/Response: 我可以子类化 NSURLRequest 以便(当 UIWebView 发出请求时)它实际上不会发出 HTTP 请求并返回一个包含我的 HTML 的 NSURLResponse 吗?或者也许以某种方式修改/子类/添加一个类别方法到 NSURLResponse ?我喜欢它是一个真正的请求的想法,但我担心私有 API 和被 App Store 拒绝。
想法 2:处理自定义 URL 协议 注册一个自定义 URL 协议,以便我的应用程序响应它,并且我可以让它返回一个合法的 NSURLResponse(填充有我的自定义 HTML)。
想法 3:欺骗缓存 使用此缓存策略创建请求 NSURLRequestReturnCacheDataDontLoad
然后以某种方式让我的 HTML 位于 webView 和缓存之间?
或者也许我完全走错了路?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我刚刚测试了另一种非常聪明的方法:无需修改
NSURLCache
或重写整个导航历史记录代码,只需创建一个自定义的NSURLProtocol
,供每当发出 HTTP 请求时,都会使用标准NSURLConnection
。在那里,您创建自己的NSURLRequest
来加载数据,并可以根据需要检查 MIME 类型、更改请求内容或将数据缓存到磁盘。这个想法来自 Rob Napier:http://robnapier.net/blog/offline-uiwebview-nsurlprotocol-588< /a>
他的代码现在也在 GitHub 上:
https://github.com/rnapier/RNCachingURLProtocol
There is another really clever approach which I just tested out: Instead of tinkering with the
NSURLCache
or rewriting the entire navigation history code, just create a customNSURLProtocol
which is used by the standardNSURLConnection
whenever a HTTP request is made. There, you create your ownNSURLRequest
to load the data and can inspect the MIME type, change the content of the request or cache your data to disk as you please. This idea comes courtesy of Rob Napier:http://robnapier.net/blog/offline-uiwebview-nsurlprotocol-588
His code is now also on GitHub:
https://github.com/rnapier/RNCachingURLProtocol
我首先尝试走路线#3。也许“用本地数据替换远程 UIWebView 请求”爱可可对你有帮助。
I'd first try to go route #3. Maybe "Substituting local data for remote UIWebView requests" on Cocoa with Love is helpful for you.
我建议不要采用上述任何方法。
我让#3 工作了,但它非常非常脆弱并且难以调试。 (例如,Apple 销毁并重新创建了
NSURLRequests
,因此您不能只是子类化 NSURLRequest 并期望在后续响应中完成。)最终对我自己来说(更)容易了历史记录并记下要加载的页面和滚动位置(垂直屏幕偏移)。
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).