将自定义URL协议映射到HTTP(使用NSURLProtocol?)

时间:2010-05-12 06:51:25

标签: cocoa webkit nsurlprotocol

我有一个使用WebKit WebView的应用程序,我想将使用自定义URL协议加载到此WebView中的URL映射到不同的HTTP URL。例如,假设我正在加载:

自定义://路径/到/资源

我想在内部实际加载:

http://something-else.com/path/to/resource

换句话说,自定义协议几乎就像一个简写。但我不能使用-webView:resource:willSendRequest:redirectResponse:fromDataSource :,因为我希望WebKit实际上相信这是有问题的URL,而不是简单地从一个重定向到另一个。

到目前为止,我一直在尝试使用自定义NSURLProtocol子类。然而,这比我最初想的要复杂,因为至少根据我的理解,我将不得不在NSURLProtocol子类'startLoading方法中进行实际加载。我想要一种方法将工作交给现有的HTTP协议加载器,但我找不到一种简单的方法来做到这一点。

是否有人对此提出建议,或者可能是另一种解决此问题的方法?

谢谢!

2 个答案:

答案 0 :(得分:3)

我使用策略委托。它有一些缺点,但它很简单,足以满足我的需求。我做这样的事情:

 - (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放在一个调用window.event.stopPropagation()的onclick事件处理程序中;设置location.href后。

它不是很花哨,但它是一种非常灵活且非常简单的方式将JS事件传递给cocoa。

答案 1 :(得分:0)

您可以实施WebResourceLoadDelegate方法:

- (NSURLRequest *)webView:(WebView *)sender resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(WebDataSource *)dataSource

这应该允许您使用HTTP URL更改请求。

或者,实现NSURLProtocol子类对此并不是很难,因为您的协议可以使用正确的HTTP URL在内部激活另一个NSURLConnection并将其委托方法映射到协议客户端。