2017-10-07 208 views
1

在我的iOS应用程序中,我有2 WKWebView控件来模拟我们的Web应用程序中2选项卡/窗口的父/子关系,以便我们可以重用所有这些JavaScript。问题在于这些2 WKWebView之间没有通用的通信通道。从源WKWebView(window.opener)访问javascripts函数

Web架构
- 第一个/主窗口中加载我们内部的JavaScript函数与第二/子窗口中打开链接。
- 第二个/子窗口加载第三方网页内容。
- 第三方内容使用javascript窗体源窗口(使用window.opener/window.parent API桥)与我们的系统进行通信。

现在,在本机应用程序,这是我在做什么重用现有的JavaScript和模拟网络杜彦武 -

一个。下面从网页中JS调用1 WKWebView -

window.open("http://localhost/child.html", "myWindow", "width=200,height=100"); 

湾该WKUIDelegate拦截此调用(a)和打开第二WKWebView -

- (nullable WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures { 
    // Here, window.open js calls are handled by loading the request in another/new web view 
    UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil]; 
    WebViewController *webViewController = [mainStoryboard instantiateViewControllerWithIdentifier:@"WebViewController"]; 
    webViewController.loadURLString = navigationAction.request.URL.absoluteString; 

    // Show controller without interfering the current flow of API call, thus dispatch after a fraction of second 
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 
     [self.navigationController pushViewController:webViewController animated:YES]; 
    }); 
    return nil; 
} 

℃。在网页/电脑浏览器中,网页应用程序的子窗口可以使用window.openerwindow.parent

如何在WKWebView中实现相同的功能?换句话说,第二个WKWebView中的js函数可以从父/源WKWebView调用js函数?

回答

1

您绝对不应该从webView:createWebViewWithConfiguration:forNavigationAction:windowFeatures:返回nil,而是您的WKWebView的一个实例。

不幸的是,我现在无法验证这一点。但据我记得,诀窍还是不要忽略webView:createWebViewWithConfiguration:forNavigationAction:windowFeatures:委托方法的参数,但创建第二个WKWebView实例,将该参数作为参数initWithFrame:configuration:之一传递。

此外,根据Apple文档,如果您要返回正确的Web视图实例,则看起来您不需要自己加载请求。 WebKit应该为您处理。

总体代码应类似于:

- (nullable WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures { 
    WKWebView *childWebView = [[WKWebView alloc] initWithFrame:CGFrameZero configuration:configuration]; 
    WebViewController *webViewController = [[WebViewController alloc] initWithWebView: childWebView]; 

    // looks like this is no longer required, but I can't check it now :(
    // [childWebView loadRequest:navigationAction.request]; 

    // Show controller without interfering the current flow of API call, thus dispatch after a fraction of second 
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 
     [self.navigationController pushViewController:webViewController animated:YES]; 
    }); 
    return childWebView; 
} 
+0

好,这看起来像一个有希望的答案。兴奋。今天就来试试吧。 – Ashok

0

一个简单的方法来完成您的任务将是有一个WKWebView,并使用HTML来分隔标题和细节。最简单的解决方案是拥有一个包含头文件和所有细节的HTML文档,但是如果您需要动态添加细节,那么也可以使用DOM。使用这种方法对头部和细节重用JavaScript是最简单的。

+0

其实,在2个独立的WKWebViews打开数据是一个先决条件,使我们可以重新使用的Web应用程序架构在我们的应用程序这个功能。另外,从用户角度来看,它将在Web应用程序以及本机应用程序中提供相同的体验。 – Ashok