The code address is as follows:
Http://www.demodashi.com/demo/12754.html
Js-oc-swift
JS and Oc/swift call each other, mainly summarizes the JS and OC interaction of three ways
1. Using UIWebView, use javascriptcore to achieve
2. Using Wkwebview, use wkscriptmessagehandler to achieve
3. Using a third-party framework Webviewjavascriptbridge implementation
Part
JavaScriptCore
JavaScriptCore Introduction
The JavaScriptCore framework is a wrapper based on the javascriptcore of the WebKit, which makes the direct interaction of objective-c and JavaScript code more simple and convenient, consisting mainly of the following classes.
1.JSContext
JS execution environment, but also through Jsvirtualmachine to manage the life cycle of all objects, each jsvalue is associated with jscontext and strong reference context. The corresponding jscontext can be obtained from WebView by [WebView valueforkeypath:@ "DocumentView.webView.mainFrame.javaScriptContext"].
2.JSValue
A strong reference to the JS object in Jsvirtualmachine is actually the Hybird object. Our operation of JS is through it. And each jsvalue is strongly referencing a context. At the same time, the conversion between OC and JS object is also through it.
3.JSManagedValue
Memory management helper Objects for JS and OC objects. Because JS memory management is garbage collection, and the object in JS is a strong reference, and OC is a reference count. If the two sides refer to each other, it is bound to cause a circular reference, which leads to memory leaks. We can use Jsmanagedvalue to save Jsvalue to avoid.
4.JSVirtualMachine
JS runs a virtual machine that has a separate heap space and garbage collection mechanism.
5.JSExport
A protocol, if the JS object wants to directly invoke the methods and properties inside the OC object, then this OC object can only implement this Jsexport protocol.
Get the context of JS in Swift
context = webView.value(forKeyPath: "documentView.webView.mainFrame.javaScriptContext") as? JSContext
Inject the desired object into JS, and the object name is consistent with what is used in HTML. self
is to comply with the Jsexport agreement, but also other compliance with the object of the agreement.
context?.setObject(self, forKeyedSubscript: "OC" as NSCopying & NSObjectProtocol)
JS calls Swift's method to implement the protocol in Swift
@objc protocol JSDelegate :JSExport { //包含参数的func,需要注意参数名对函数名称的影响 func showMessageToYou(_ message:String) /* 对应html中“showAAndB”,此方法包含两个参数,需要在参数前加“_” func showA(_ aString: String, andB: String) func showAAndB(_ aString:String,_ bStr:String) 以上两个方法等同 */ func showAAndB(_ aString:String,_ bStr:String) func doActionCallBack()}
Method of Swift calling JS
let jsStr = String(format:"callback(‘%@‘)",(textField?.text)!)self.context?.evaluateScript(jsStr)
Block can be used in OC and implement the Jsexport protocol in two ways, code implementation:
JSContext *context = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];self.context = context;//注入JS需要的“OC”对象,该对象与html中的保持一致即可self.context[@"OC"] = self;
Wkscriptmessagehandler
After initializing the Wkwebview, add a bridge for JS to call Oc/swift, where name corresponds to name in Wkscriptmessage
webView.configuration.userContentController.add(_ scriptMessageHandler: WKScriptMessageHandler, name: String)
Abide by the protocol Wkscriptmessagehandler, the implementation of the following methods, JS can be implemented to send messages to Oc/swift.
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage)
Oc/swift Call JS
let jsStr = String(format:"callback(‘%@‘)",(textField?.text)!)self.webView.evaluateJavaScript(jsStr as String, completionHandler: { (result:Any?, error:Error?) in print("error:",error as Any) })
Webviewjavascriptbridge
Webviewjavascriptbridge is a third-party library that objective-c and JavaScript communicate with each other, which makes it easy to realize the functions of OC and JavaScript intermodulation. Webviewjavascriptbridge the process of intermodulation is also easy to understand, that is, in the OC environment and JavaScript environment each save a mutually called bridge object, each call has an ID and callbackid to find the corresponding processing of the two environments. After downloading the source from GitHub, you can see that the core classes are mainly comprised of the following:
Webviewjavascriptbridge_js: Bridge initialization and processing for JavaScript environments. is responsible for receiving the messages that OC sends to JavaScript, and sends the JavaScript environment message to OC.
Wkwebviewjavascriptbridge/webviewjavascriptbridge: primarily responsible for message processing in the OC environment, and sends messages from the OC environment to the JavaScript environment.
webviewjavascriptbridgebase: The main realization of the OC Environment Bridge initialization and processing.
Initialize Wkwebviewjavascriptbridge
self.webViewBridge = [WKWebViewJavascriptBridge bridgeForWebView:self.webView];[self.webViewBridge setWebViewDelegate:self];
JS calls OC need to register event
[self.webViewBridge registerHandler:@"handlerName" handler:^(id data, WVJBResponseCallback responseCallback) { //code}];
OC Call JS
[self.webViewBridge callHandler:@"handlerName" data:@[textField.text] responseCallback:^(id responseData) { NSLog(@"%@",responseData); }];
The following code needs to be placed in the HTML
/*这段代码是固定的,必须要放到js中*/function setupWebViewJavascriptBridge(callback) { if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); } if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); } window.WVJBCallbacks = [callback]; var WVJBIframe = document.createElement(‘iframe‘); WVJBIframe.style.display = ‘none‘; WVJBIframe.src = ‘wvjbscheme://__BRIDGE_LOADED__‘; document.documentElement.appendChild(WVJBIframe); setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0)}/*与OC交互的所有JS方法都要放在此处注册,才能调用通过JS调用OC或者让OC调用这里的JS*/setupWebViewJavascriptBridge(function(bridge) { bridge.registerHandler(‘callback‘, function(data, responseCallback) { callback(data); responseCallback(‘js执行过了‘+data); })})
Project structure
Summary of mutual invocation between JS and native Oc/swift
The code address is as follows:
Http://www.demodashi.com/demo/12754.html
Note: This copyright belongs to the author, by the demo master, refused to reprint, reprint need the author authorization
Summary of mutual invocation between JS and native Oc/swift