将自定义URL协议映射到HTTP(使用NSURLProtocol?)
我有一个使用WebKit WebView的应用程序,我希望将在此WebView中加载的URL与自定义URL协议映射到不同的HTTP URL。 例如,说我正在加载:
定制://路径/到/资源
我想在内部实际加载:
http://something-else.com/path/to/resource
换句话说,自定义协议几乎可以用作简写。 但是我不能使用-webView:resource:willSendRequest:redirectResponse:fromDataSource :,因为我想让WebKit真正相信这是有问题的URL,而不是简单地从一个重定向到另一个。
到目前为止,我一直在尝试使用自定义的NSURLProtocol子类。 然而,这比我第一次想到的要复杂得多,因为至少据我的理解,我必须自己在NSURLProtocol子类的startLoading方法中进行实际加载。 我想要一种将工作交给现有HTTP协议加载器的方式,但我找不到一种简单的方法来完成此操作。
有没有人有这样的建议,或者解决这个问题的另一种方法?
谢谢!
我使用政策委托。 它有一些缺点,但它对我的需求来说简单而充分。 我做这样的事情:
- (void)webView:(WebView *)webView decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id < WebPolicyDecisionListener >)listener;
{
if ([request.URL.scheme isEqualToString:@"custom"]) {
// do something interesting
// like force the webview to load another URL
[listener ignore];
return;
}
[listener use];
}
对于我的使用,我还需要停止JS事件的传播。 所以我通常把URL放在一个onclick事件处理函数中,它调用window.event.stopPropagation(); 设置完location.href后。
这不是很花哨,但它是一个非常灵活和非常简单的方式来沟通JS事件可可。
您可以实现WebResourceLoadDelegate
方法:
- (NSURLRequest *)webView:(WebView *)sender resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(WebDataSource *)dataSource
这应该允许您使用HTTP URL更改请求。
另外,实现一个NSURLProtocol
子类并不是很难,因为你的协议可以使用正确的HTTP URL在内部触发另一个NSURLConnection
并将其委托方法映射到协议客户端。