Кажется, есть ошибка с webView:decidePolicyForNewWindowAction:request:newFrameName:decisionListener:
в том, что запрос всегда nil
, но есть надежное решение, которое работает как с обычными target="_blank"
ссылками, так и с javascript.
В основном я использую другой эфемерный WebView для обработки загрузки новой страницы. Похож на Yoni Shalom, но с немного более синтаксическим сахаром.
Чтобы использовать его, сначала установите объект делегата для вашего WebView, в этом случае я устанавливаю себя в качестве делегата:
webView.UIDelegate = self;
Затем просто реализуйте метод делегата webView:createWebViewWithRequest:
и используйте мой блочный API, чтобы что-то делать при загрузке новой страницы, в этом случае я открываю страницу во внешнем браузере:
-(WebView *)webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request {
return [GBWebViewExternalLinkHandler riggedWebViewWithLoadHandler:^(NSURL *url) {
[[NSWorkspace sharedWorkspace] openURL:url];
}];
}
Вот и все. Вот код для моего класса. Заголовок:
// 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
реализация:
// 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
Лицензия Apache 2.