【问题标题】:How to open external links to safari/chrome browser in Cocoa如何在 Cocoa 中打开 safari/chrome 浏览器的外部链接
【发布时间】:2013-05-18 05:40:03
【问题描述】:

我是 Cocoa 开发的新手。

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

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

我已将 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];
    }
}

任何帮助将不胜感激! :)

【问题讨论】:

    标签: macos cocoa webview webkit


    【解决方案1】:

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

    // 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]];
    }
    

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

    【讨论】:

    • 感谢@silvansky 付出的努力。 :)
    【解决方案2】:

    我能够通过将我的 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];
    }
    

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

    【讨论】:

      【解决方案3】:

      根据上面的答案,我制定了以下解决方案。在 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 处理。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-11-23
        • 2014-07-12
        • 2018-02-11
        • 2017-08-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多