4

我是可可开发的新手。

我已阅读有关使用 WebPolicyDelegate 的信息。但是,我似乎无法让它按应有的方式工作。我希望该应用程序打开外部链接并在 chrome 或 safari 等网络浏览器中启动它。这应该只在单击链接时发生。

目前,我的应用程序的默认 URL 也与我的应用程序的 webview 正在执行的操作同时打开到 Web 浏览器。

我已将 policyDelegate 设置为我的 webview,并使用以下代码实现它:

- (void)webView:(WebView *)webView 
decidePolicyForNavigationAction:(NSDictionary *)actionInformation 
request:(NSURLRequest *)request 
frame:(WebFrame *)frame 
decisionListener:(id <WebPolicyDecisionListener>)listener
{
    if ([actionInformation objectForKey:WebActionElementKey]) {
        [listener ignore];
        [[NSWorkspace sharedWorkspace] openURL:[request URL]];
    }
    else {
        [listener use];
    }
}

任何帮助将非常感激!:)

4

3 回答 3

16

我可以通过将我的 webView 设置为 PolicyDelegate 来解决我的问题。

[webView setPolicyDelegate:self];

并从以下代码实现: pandoraboy

- (WebView *)webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request
{
    // HACK: This is all a hack to get around a bug/misfeature in Tiger's WebKit
    // (should be fixed in Leopard). On Javascript window.open, Tiger sends a null
    // request here, then sends a loadRequest: to the new WebView, which will
    // include a decidePolicyForNavigation (which is where we'll open our
    // external window). In Leopard, we should be getting the request here from
    // the start, and we should just be able to create a new window.

    WebView *newWebView = [[WebView alloc] init];
    [newWebView setUIDelegate:self];
    [newWebView setPolicyDelegate:self];

    return newWebView;
}

- (void)webView:(WebView *)sender decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id<WebPolicyDecisionListener>)listener {
     if( [sender isEqual:webView] ) {
        [listener use];
     }
     else {
        [[NSWorkspace sharedWorkspace] openURL:[actionInformation objectForKey:WebActionOriginalURLKey]];
        [listener ignore];
        [sender release];
     }
}

- (void)webView:(WebView *)sender decidePolicyForNewWindowAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request newFrameName:(NSString *)frameName decisionListener:(id<WebPolicyDecisionListener>)listener {
    [[NSWorkspace sharedWorkspace] openURL:[actionInformation objectForKey:WebActionOriginalURLKey]];
    [listener ignore];
}

我希望这也可以帮助其他人。:)

于 2013-06-01T01:11:51.937 回答
5

您可以检查您的 URL 的方案以检查它是否应该在默认浏览器中打开。

// open local urls in our app, and external in default browser
NSString *scheme = [[request URL] scheme];
if ([scheme isEqualToString:@"file"])
{
    [listener use];
}
else
{
    [listener ignore];
    [[NSWorkspace sharedWorkspace] openURL:[request URL]];
}

这段代码对我有用。它是可扩展的:您可以检查您的自定义方案以执行一些自定义操作。

于 2013-05-30T13:21:42.037 回答
0

根据上面的答案,我制定了以下解决方案。在 cordova-osx 应用程序中使用 window.open() 时遇到问题(它没有做任何事情)。这是我的解决方法,如果有人遇到同样的问题(像这样更改 CDVWebViewDelegate.m):

- (WebView *)webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request {
    return sender; //[self externalWebView:sender];
}

#pragma mark WebPolicyDelegate

- (void) webView:(WebView*) sender decidePolicyForNavigationAction:(NSDictionary*) actionInformation request:(NSURLRequest*) request frame:(WebFrame*) frame decisionListener:(id <WebPolicyDecisionListener>) listener {
    NSString* url = [[request URL] description];
    NSLog(@"navigating to %@", url);
    //[listener use];
    NSString *scheme = [[request URL] scheme];
    if ([scheme isEqualToString:@"file"])
    {
        [listener use];
    }
    else
    {
        [listener ignore];
        [[NSWorkspace sharedWorkspace] openURL:[request URL]];
    }
}

JS中调用window.open()时,在delegate中调用createWebViewWithRequest,返回当前WebView(sender)。然后依次调用当前委托的 decisionPolicyForNavigationAction。使用 url 方案,我们决定请求是否应由外部浏览器(sharedWorkspace)的 WebView 处理。

于 2016-05-13T07:02:18.767 回答