0

I am writing a MacRuby (objective-c) application that is basically a web browser that opens a specific website (mine) by default.

However, I don't want links to open in the WebView. I would rather they open in the user's default browser. Here is the code I have so far, but it doesn't seem to be calling the decidePolicyForNavigation method.

framework "WebKit"

class AppDelegate
    attr_accessor :window

    def applicationDidFinishLaunching(notification)
        load_web_view
    end

    def load_web_view
        web_view = WebView.new
        request = NSURLRequest.requestWithURL(NSURL.URLWithString("http://example.com"))
        web_view.mainFrame.loadRequest(request)
        window.contentView = web_view
        web_view.frameLoadDelegate = self
        web_view.setPolicyDelegate(self)
    end

    # this makes it so links open in the default browser
    def webView(view, decidePolicyForNavigationAction:actionInformation, request:request, frame:frame, decisionListener:listener)
        puts 'running nav policy'
        listener.ignore
        NSWorkspace.sharedWorkspace.openURL(request.URL)
    end
end

What am I doing wrong?

Andrew
  • 227,796
  • 193
  • 515
  • 708

1 Answers1

0

You don't want to use WebKit directly if it's your goal to simply open a URL with the user's default browser - you want to use the LaunchServices APIs. See http://developer.apple.com/library/mac/#documentation/Carbon/Reference/LaunchServicesReference/Reference/reference.html

jkh
  • 3,246
  • 16
  • 13
  • So using the LaunchServices API would take the place of my `NSWorkspace.sharedWorkspace.openURL(request.URL)`? I still need to prevent these external links from opening within the WebView and my "policy method" isn't getting called. Do you know what I'm doing wrong? – Andrew Jan 05 '12 at 00:14
  • Perhaps I'm misunderstanding the bigger picture here. First, why are you creating a webview at all? What is its purpose? – jkh Jan 05 '12 at 17:38
  • It's a GUI wrapper around my web-based chatroom app. When someone posts a link in the chatroom, I want those links to open in the user's default browser, rather than navigate away from the chatroom and display the page in the small 800 x 400px chat window. – Andrew Jan 05 '12 at 18:23
  • Ahh, OK, I totally understand what you're trying to do now. This may be somewhat brute-force, but what happens if you declare your own resource loading delegate object with the -setResourceLoadDelegate method? That will invoke the delegate (conforming to the WebResourceLoadDelegate protocol - see http://bit.ly/yqgdm4) for every resource your WebView attempts to load, and you can examine the target to see if it's an internal resource or an external one that should be passed to LaunchServices instead. Sorry, but I don't see any easier way after a quick read of the WebView docs. – jkh Jan 05 '12 at 22:34
  • ok, I'll try that. When you say "invoke the delegate (conforming to the WebResourceLoadDelegate protocol)", is there anything I need to do in order to make the delegate "conform", other than specify the method I want to call? I'm just specifying my AppDelegate for anything that needs a delegate and that may be part of my problem. – Andrew Jan 06 '12 at 16:20
  • The WebResourceLoadDelegate would be another object which conforms to the protocol I mentioned. In essence, you need two objects here. One for the WebView and another to "proxy" all the resource load requests such that you can redirect some of the operations. That second object is what you'd pass to the setResourceLoadDelegate method for the first object. Confusing, I know! – jkh Jan 07 '12 at 22:34