我正在开发一个iOS应用程序,在该应用程序中我试图使用UIWebView
来显示各种网站。最近,我完成了将Javascript注入UIWebView
以捕获window.open
、window.close
和window.opener.focus
实例的逻辑。简而言之,为了做到这一点,我注入了覆盖上述JS函数的JS,其中包括创建一个具有特定方案的iframe
,我可以在应用程序的webView:shouldStartLoadWithRequest:navigationType
方法中捕获该方案。目前一切正常,包括window.open
创建一个新的UIWebView
,而不是在同一窗口中加载。
然而,现在出现的问题是,对于窗口之间的JS通信,没有可行的解决方案。如果子窗口试图调用window.opener
或window.parent
,它总是返回一个null值,因此,它无法返回到原始web视图。
为了了解哪些iOS浏览器能够有效地执行窗口到窗口的通信,我发现在我iPhone上的9个浏览器中,只有Safari能够有效地成功执行这种通信。这让我相信UIWebView
有一些东西阻止了完全JS窗口到窗口的通信。
有没有人成功地让UIWebView与所有JS逻辑完全集成,即窗口到窗口的通信?或者有证据表明JS窗口到窗口的通信是不可能的?如有任何指示或建议,不胜感激。谢谢
找到了可能的解决方案。
将JavaScriptCore.framework添加到链接框架和您的webViewDidFinishLoad:
JSContext *parentCtx = [self.parentWebView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
JSContext *childCtx = [self.childWebView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
childCtx[@"window"][@"opener"] = parentCtx[@"window"];
现在,当您从childWebView调用window.oopener.test()时,它将在parentWebView中启动测试函数!
我不确定私人API。仅适用于iOS 7
Swift版本
import JavaScriptCore
let jsContextA = webA.valueForKeyPath("documentView.webView.mainFrame.javaScriptContext")
let jsContextB = webB.valueForKeyPath("documentView.webView.mainFrame.javaScriptContext")
//Original objc code : jsContextB[@"window"][@"opener"] = jsContextA[@"window"];
jsContextB!.setObject("opener", forKeyedSubscript: "window")
jsContextB!.setObject(jsContextA!.objectForKeyedSubscript("window"), forKeyedSubscript: "opener")