最近写项目,swift内嵌套h5 做一些交互 ,我这里用的UIWebView,h5 调用原生 ,原生的调用h5都有用到
前言
JSContext是代表JS的执行环境,通过evaluateScript:方法就可以执行JS代码
JSValue封装了JS与Obj-C中的对应的类型,以及调用JS的API等
JSExport, JSExport是一个协议,遵守此协议,在协议中声明的API都会在JS中暴露出来,JS调用
上代码 js调用原生
importUIKit
importJavaScriptCore
//暴露接口 这里前面需要添加@objc 因为JavaScriptCore是oc语言的库
@objc protocolJSObjectProtocol :JSExport{
func getToken()->String
func finishPage()
}
//实现协议的方法 这里会自动提示让你实现方法
@objc class JSObjext: NSObject,JSObjectProtocol {
funcgetToken()->String{
return "我是token"
}
func finishPage() {
print("关闭页面")
}
}
funcwebView(_webView:UIWebView, shouldStartLoadWith request:URLRequest, navigationType:UIWebView.NavigationType) ->Bool{
//这里的代码可以放到这里 也可以放到完成加载的方法(DidFinishLoad) 看自己的需求,如果一上来就要拿到数据 那就放在shouldStartLoad
let context = self.myWeb?.value(forKeyPath: "documentView.webView.mainFrame.javaScriptContext") as! JSContext
letobjc =JSObjext()
context.setObject(objc, forKeyedSubscript:"JSTest"asNSCopying&NSObjectProtocol)
return true
}
这样JavaScript就可以 用window.JSTest.getToken 来调用原生方法了
2. 原生调用JavaScript
funcwebView(_webView:UIWebView, shouldStartLoadWith request:URLRequest, navigationType:UIWebView.NavigationType) ->Bool{
//这里的代码可以放到这里 也可以放到完成加载的方法(DidFinishLoad) 看自己的需求,如果一上来就要拿到数据 那就放在shouldStartLoad
let context = webView!.value(forKeyPath: "documentView.webView.mainFrame.javaScriptContext") as! JSContext
// 类似于method名() 这里用调用原生的eat 方法 不传参数 当然也可以传参数 例如 eat("🍎")
let string = "eat()"
context.evaluateScript(string)
}
// 注意
如果是要给h5传图片的base64字符串的话
let imageData = image.jpegData(compressionQuality: 0.5)! let strings = imageData.base64EncodedString(options: Data.Base64EncodingOptions.endLineWithCarriageReturn)
必须是endLineWithCarriageReturn的类型 否则传过去h5也解析不了
网友评论