It seems that the error with webView:decidePolicyForNewWindowAction:request:newFrameName:decisionListener: is that the request is always nil , but there is a reliable solution that works with both regular target="_blank" links and javascript.
I mainly use another ephemeral WebView to handle a new page load. Like Yoni Shalom, but with a bit more syntactic sugar.
To use it, first set the delegate object for your WebView, in which case I set myself as a delegate:
webView.UIDelegate = self;
Then just implement the webView:createWebViewWithRequest: delegate method and use my block based API to do something when a new page loads, in this case I open the page in an external browser:
-(WebView *)webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request { return [GBWebViewExternalLinkHandler riggedWebViewWithLoadHandler:^(NSURL *url) { [[NSWorkspace sharedWorkspace] openURL:url]; }]; }
This is pretty much the case. Here is the code for my class. Title:
// GBWebViewExternalLinkHandler.h // TabApp2 // // Created by Luka Mirosevic on 13/03/2013. // Copyright (c) 2013 Goonbee. All rights reserved. // #import <Foundation/Foundation.h> @class WebView; typedef void(^NewWindowCallback)(NSURL *url); @interface GBWebViewExternalLinkHandler : NSObject +(WebView *)riggedWebViewWithLoadHandler:(NewWindowCallback)handler; @end
implementation:
// GBWebViewExternalLinkHandler.m // TabApp2 // // Created by Luka Mirosevic on 13/03/2013. // Copyright (c) 2013 Goonbee. All rights reserved. // #import "GBWebViewExternalLinkHandler.h" #import <WebKit/WebKit.h> @interface GBWebViewExternalLinkHandler () @property (strong, nonatomic) WebView *attachedWebView; @property (strong, nonatomic) GBWebViewExternalLinkHandler *retainedSelf; @property (copy, nonatomic) NewWindowCallback handler; @end @implementation GBWebViewExternalLinkHandler -(id)init { if (self = [super init]) { //create a new webview with self as the policyDelegate, and keep a ref to it self.attachedWebView = [WebView new]; self.attachedWebView.policyDelegate = self; } return self; } -(void)webView:(WebView *)sender decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id<WebPolicyDecisionListener>)listener { //execute handler if (self.handler) { self.handler(actionInformation[WebActionOriginalURLKey]); } //our job is done so safe to unretain yourself self.retainedSelf = nil; } +(WebView *)riggedWebViewWithLoadHandler:(NewWindowCallback)handler { //create a new handler GBWebViewExternalLinkHandler *newWindowHandler = [GBWebViewExternalLinkHandler new]; //store the block newWindowHandler.handler = handler; //retain yourself so that we persist until the webView:decidePolicyForNavigationAction:request:frame:decisionListener: method has been called newWindowHandler.retainedSelf = newWindowHandler; //return the attached webview return newWindowHandler.attachedWebView; } @end
Licensed as Apache 2.
lms
source share