WKWebView不会打开社交媒体登录弹出窗口

我的应用程序中有一个WKWebView。 除了我展示的网站有社交媒体登录按钮外,一切都运行顺畅。 问题是,它们显示(或尝试显示)允许其访问您的社交媒体帐户的弹出窗口。 我研究了这个并尝试了一些东西,但似乎都没有。 这是我尝试过的:

在viewDidLoad中,我尝试在init上启用Javascript:

WKWebViewConfiguration *theConfiguration = [[WKWebViewConfiguration alloc] init]; WKPreferences *thePreferences = [[WKPreferences alloc] init]; thePreferences.javaScriptCanOpenWindowsAutomatically = YES; thePreferences.javaScriptEnabled = YES; theConfiguration.preferences = thePreferences; self.wkWeb = [[WKWebView alloc] initWithFrame:screenRect configuration:theConfiguration]; 

但是,这对我没有帮助。 然后我试着和代表一起玩,走那条路。 我尝试使用createWebViewWithConfiguration方法,但这似乎有点过分,因为我必须过滤掉它们是否在登录URL然后配置弹出窗口并显示它。 然后这仍然无法正常工作。 我也来这里是为了不是主框架逻辑,取消请求并在主视图中重新加载它,这是一个简单的单行修复,因为这是膨胀到20多行。

这似乎是一个常见的问题,但我似乎无法找到很多信息。 有任何想法吗?

编辑 – 加法

在玩完Armands答案后,我越来越近了。 这是我的createWebViewWithConfig方法,它只显示白屏覆盖。 这就像我需要一些东西告诉新的弹出窗口加载内容。 另外 – 我假设我可以将此模态窗口放在我当前的.m文件中,它不需要一个全新的文件?

 NSURL *url = navigationAction.request.URL; if(!navigationAction.targetFrame.isMainFrame && [url.absoluteString rangeOfString:@"initiate_"].location != NSNotFound) { //open new modal webview AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init]; config.processPool = [appDelegate getSharedPool]; self.popupLogin = [[WKWebView alloc] initWithFrame:self.wkWeb.bounds configuration:config]; self.popupLogin.frame = CGRectMake(self.wkWeb.frame.origin.x, self.wkWeb.frame.origin.y, self.wkWeb.frame.size.width, self.wkWeb.frame.size.height); self.popupLogin.navigationDelegate = self; self.popupLogin.UIDelegate = self; [webView addSubview:self.popupLogin]; [self.popupLogin loadRequest:navigationAction.request]; return nil; } 

这些登录按钮尝试打开一个新选项卡,WKWebView不支持该选项卡。 据我所知,只有一种方法可以做到这一点。

首先添加WKUIDelegate方法:

 -(WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures { NSURL *url = navigationAction.request.URL; if (navigationAction.targetFrame == nil && [url.absoluteString rangeOfString:@"facebook.com/dialog"].location != NSNotFound) { //Open new modal WKWebView } return nil; } 

在模态WKWebView中添加:

 -(void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler { NSURL *url = navigationResponse.response.URL; if ([url.absoluteString rangeOfString:@"close_popup.php"].location != NSNotFound) { //Close viewController } decisionHandler(WKNavigationResponsePolicyAllow); } 

close_popup.php适用于Facebook。 如果您需要支持多个社交网络,请在其url中找到唯一的内容。

为了实现这一点,您必须在WKWebViews之间共享Cookie。 要做到这一点,你必须使用共享的WKProcessPool初始化它们。 我更喜欢将它存储在AppDelegate中。

可以像这样创建WKWebView:

 - (void)createWebView { AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate; WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init]; config.processPool = delegate.webViewProcessPool; self.webView = [[WKWebView alloc] initWithFrame:self.view.bounds configuration:config]; self.webView.UIDelegate = self; self.webView.navigationDelegate = self; [self.view addSubview:self.webView]; } 

在AppDelegate中只是懒得加载它:

 -(id)webViewProcessPool { if (!_webViewProcessPool) { _webViewProcessPool = [[WKProcessPool alloc] init]; } return _webViewProcessPool; } 

Armands的答案在正确的轨道上,但可以显着改善。

  • 如果您希望webview能够彼此协作(例如,通过window.opener),则返回新创建的webview(而不是nil)非常重要。
  • 如果使用传入create调用的配置,则会自动共享进程池
  • 您不需要在createWebViewWith调用中进行额外检查。 (如果要阻止任意弹出窗口或创建特定的WebViewController类型,您仍应将URL列入白名单。)

在您的主WebViewController中(其中webView.uiDelegate = self ):

 func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? { let webView = WKWebView.init(frame: .zero, configuration: configuration) //OPTIONAL: check navigationAction.request.url to see what site is being opened as a popup //TODO HERE: Launch new instance of your WebViewController (within a nav controller) //and pass it this newly created webView to be added as main subview return webView } 

您仍然希望在弹出WebViewController的新实例中具有关闭侦听器(其中webView.navigationDelegate = self ):

 func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) { if let url = navigationResponse.response.url, url.absoluteString.hasPrefix("https://example.com/something-unique-to-this-popup-when-it-closes") { dismiss(animated: true, completion: nil) } decisionHandler(.allow) }