本文分两部分,分别讲解使用 UIWebView 和 iOS8 引入的 WKWebView 进行 Web <==> Native 双向交互的方式。
UIWebView
Objective-C 调用 JavaScript 方法
UIWebView 的 API stringByEvaluatingJavaScriptFromString:
是在 WebView 中运行 JS 代码的实例方法。在 Web 端用 JS 提供具体的方法实现,在 native 端就可以方便的调用。
JS 文件中:
1 | function myJavascriptFunction(){ |
OC 文件中:
1 | [webview stringByEvaluatingJavaScriptFromString: @“myJavascriptFunction()”]; |
JavaScript 调用 Objective-C 方法
在 Web 端用 JS 捕获重定向到新的页面的动作,并立刻取消,这样就能触发并利用 UIWebViewDelegate 协议中的 shouldStartLoadWithRequest
代理方法,实现调用 OC 代码的需求。但实操过程中往往会引发一些难以解决的 bug。
最佳实践
创建一个 IFrame 并且用setAttribute
方法对它的 location 进行重新赋值,这样可以触发 UIWebView 中的shouldStartLoadWithRequest
方法。成功触发后再移除掉 IFrame.
JS 文件中:
1 | var iframe = document.createElement("IFRAME"); |
OC 文件中:
1 | - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { |
三方库
可引入 WebViewJavascriptBridge 第三方库来完成需求。该第三方库具有更强大的通信和回调机制。微信等知名应用均引入该三方库,显示了其强大的稳定性。
WKWebView(iOS8)
苹果在 iOS8 引入新的 WKWebView, 提供了一些新的 API ,相应地 Native 端和 Web 端的通信方式增加了更多的方式。
Objective-C 调用 JavaScript 方法
和 UIWebView 相似,利用方法 evaluateJavaScript:completionHandler:
在 WebView 运行 JS 代码。不同的是,这个 API 提供了运行 JS 完成时的回调,可以处理运行成功或失败后的操作。在 WKWebView 加载的特定阶段例还可以执行加入 WKUserContentController 的 UserScript.
OC 文件中:
1 | - (void)viewDidLoad { |
JavaScript 调用 Objective-C 方法
WKWebView 相关架构中定义了三个协议(protocols), 分别是 WKNavigationDelegate 、 WKUIDelegate 、 WKScriptMessageHandler, 其中 WKScriptMessageHandler 的作用就是处理 Web JS 发送到 Native 端的信息。
JS文件中:
1 | function alertClick(message){ |
OC 文件中:
1 | - (void)viewDidLoad { |