swift与js之间的交互与传值
一.swift调用JS的函数:
通过JSContext,我们有两种调用JS代码的方法
1:直接调用JS代码。
2:在Swift中通过JSContext注入模型,然后调用模型的方法。
1.直接调用JS代码:(不推荐 其方法是在swift文件中写入JS代码)
let context = JSContext()
context.evaluateScript(“var num = 10”)
context.evaluateScript(“function square(value) { return value * 2}”)
// 直接调用
let squareValue = context.evaluateScript(“square(num)”)
print(squareValue)
// 通过下标来获取到JS方法。
let squareFunc = context.objectForKeyedSubscript(“square”)
print(squareFunc.callWithArguments([“10”]).toString());
这种方式是没有注入模型到JS中的。这种方式使用起来不太合适,通常在JS中有很多全局的函数,为了防止名字重名,使用模型的方式是最好不过了。通过我们协商好的模型名称,在JS中直接通过模型来调用我们在Swift中所定义的模型所公开的API。
2.注入模型的交互
首先要加载JS:
func loadJS() {
let path = Bundle.main.path(forResource: "/US.Maintenance/html/workingPersonnel/applyForMaintenance", ofType: "htm")
/*path的 forResourse是你的htm文件所在的地址*/
print(path)
let url = NSURL.fileURL(withPath:path!)
print(url)
let request = URLRequest(url: url)
//self.jsContext.evaluateScript("bbb",withSourceURL:url)
view1.webView.loadRequest(request)
}
接下来,我们在controller中在webview加载完成的代理中,给JS注入模型:
func webViewDidFinishLoad(_ webView: UIWebView) {
print("webViewDidFinishLoad")
self.jsContext = webView.value(forKeyPath: "documentView.webView.mainFrame.javaScriptContext") as! JSContext
let model = SwiftJavaScriptModel()
model.controller = self
model.jsContext = self.jsContext
self.jsContext.setObject(model, forKeyedSubscript: "WebViewJavascriptBridge" as NSCopying & NSObjectProtocol)
let path = Bundle.main.path(forResource: "/US.Maintenance/html/workingPersonnel/applyForMaintenance", ofType: "htm")
/*path的 forResourse是你的htm文件所在的地址*/
let url = NSURL.fileURL(withPath:path!)
self.jsContext.evaluateScript("bbbb",withSourceURL:url)
self.jsContext.exceptionHandler = { (context, exception) in
print("exception:", exception as Any)
}
}
然后就可以调用JS的函数了
@objc func success(sv:String) {
let jsHandlerFunc = self.jsContext?.objectForKeyedSubscript("cc")
//通过下标来调用JS的函数 cc为函数名
let dict = ["svb": sv] as [String : Any]
//创建字典来储存值
_ = jsHandlerFunc?.call(withArguments:[dict])
//通过字典传值
//如无参数:_ = jsHandlerFunc?.call(withArguments:)
}
JS文件:
cc = function(arg){
//arg就是我们传过来的字典
document.getElementById('gu').innerHTML = arg['svb'];
//通过下标svb取值
}
二.JS调用Swift的函数
首先,我们需要先定义一个协议,而且这个协议必须要遵守JSExport协议。
All methods that should apply in Javascript,should be in the following protocol.注意,这里必须使用@objc,因为JavaScriptCore库是ObjectiveC版本的。如果不加@objc,则调用无效果。
@objc protocol SwiftJavaScriptDelegate: JSExport {
func up()
func audiostart()
func audioend()
func audiosss()
}
接下来,我们还需要定义一个模型:(在这个协议中实现我们上面定义的函数)
@objc class SwiftJavaScriptModel: NSObject, SwiftJavaScriptDelegate {
weak var controller: UIViewController?
weak var jsContext: JSContext?
func audiostart(){
let audio = RecordManager()
audio.downAction()
print("start")
}
func audioend(){
let audio = RecordManager()
audio.upAction()
print("end")
}
func audiosss() {
let audio = RecordManager()
audio.playAction()
}
func up(){
let view22 = view2()
view22.delegate = ViewController() as View2Delegate
let top = UIApplication.shared.keyWindow?.rootViewController
top?.present(view22,animated: true,completion: nil)
}
}
接下来,我们在controller中在webview加载完成的代理中,给JS注入模型:
func webViewDidFinishLoad(_ webView: UIWebView) {
self.jsContext1 = webView.value(forKeyPath: "documentView.webView.mainFrame.javaScriptContext") as! JSContext
let model = SwiftJavaScriptModel()
model.controller = self
model.jsContext = self.jsContext1
// 这一步是将OCModel这个模型注入到JS中,在JS就可以通过OCModel调用我们公暴露的方法了。
self.jsContext1.setObject(model, forKeyedSubscript: "WebViewJavascriptBridge" as NSCopying & NSObjectProtocol)
let path = Bundle.main.path(forResource: "/US.Maintenance/html/workingPersonnel/applyForMaintenance", ofType: "htm")
let url = NSURL.fileURL(withPath:path!)
self.jsContext1.evaluateScript("bbbb",withSourceURL:url)
self.jsContext1.exceptionHandler = { (context, exception) in
print("exception:", exception as Any)
}
}
然后我们就可以在JS中调用我们写好的swift函数了
audiostart = function(){
//WebViewJavascriptBridge是我们在webViewDidFinishLoad中定义的key(名字随便定义) .audiostart()是我们暴露的swift方法
WebViewJavascriptBridge.audiostart();
}
audioend = function(){
WebViewJavascriptBridge.audioend();
}
audiosss = function(){
WebViewJavascriptBridge.audiosss();
}