首先来看下WKWebView的初始化相关设置:
一、导入相关头文件、设置相关代理和属性
二、WKWebView初始化
注意:
楼主遇到的第一个坑:如果JS给OC传值为空,必须写成: postMessage(null),如果什么都不写,方法是调不通的。
1、在viewWillAppear中配置,addScriptMessageHandler name: "这里就是JS的方法,方法名必须统一"
楼主遇到的第二个坑:配置完后必须在 viewWillDisappear 中 remove,否则会造成循环引用,导致crash
2、实现 WKScriptMessageHandler 协议
以上就是JS调OC,JS向OC传值...
楼主这里举三个例子:
1: webview加载完成前,将用户信息传给js
2: webview加载完成,将相关信息传给js
3: 调用相册或相机时,将选择的图片请求后台接口,后台返回图片地址,将该地址回传给H5,H5将图片显示到页面上
第一个例子:webView加载完成前传值
因为 evaluateJavaScript 方法默认是在加载完成后调用,所以直接在页面开始加载中调用是传不过去的,这个时候怎么办呢? 我们可以让js端写两个方法, 第一个方法是js端开始向oc端发起信息需求的方法名,当oc端收到该方法名的时候,就去调用js端第二个获取传值的方法,把信息传递过去。
先让JS端写个方法调OC,OC实现方法后在这个方法内部给JS传值
在WKScriptMessageHandler协议中,实现该方法,然后在方法内部给JS传值
注意: 以上就是在Webview加载完成前传值,如果打印没报错,证明传参成功,如果web端没收到,让他把获取到值的方法写到页面中即可。
第二个例子: webView加载完成,传值给js
第三个例子: 传图片地址给js,js拿到后显示图片
1:拍照事件
1.1:将拍的照片请求上传图片接口,成功返回图片地址,并传值给H5
2: 从相册中选取照片
2.2:将相册中选取的照片请求上传图片接口,成功返回图片地址,并传值给H5
注意: getPhotoCallback 即为调用的方法名,后面传值格式必须为: ('') , 这里遇到了第三个坑, 如果方法名写为: 名称.名称 (例如:hello. getPhotoCallback),这种是调不通的,可以写成hello_getPhotoCallback的形式,一般的话最好还是定义一个完整的名称。 刚开始这个问题卡了比较久,一直调不通,在此记录一下.....
在 viewDidLoad 中注册进度条监听
开始加载网页
加载完成
加载失败
页面跳转失败
progressView懒加载
添加监听观察者
最后别忘记 removeObserver
Demo地址:https://github.com/zhwIdea/WKWebViewAndJS
首先确保一份已经配好功能的html文件:1.初始化一个webview(viewdidload)
UIWebView* webView = [[UIWebView alloc] initWithFrame:self.view.bounds]
[self.view addSubview:webView]
2.将此webview与WebViewJavascriptBridge关联(viewdidload)
if (_bridge) { return}
[WebViewJavascriptBridge enableLogging]
_bridge = [WebViewJavascriptBridge bridgeForWebView:webView webViewDelegate:self handler:^(id data, WVJBResponseCallback responseCallback) {
NSLog(@"ObjC received message from JS: %@", data)
responseCallback(@"Response for message from ObjC")
}]
ps:此时你的webview就与js搭上桥了。下面就是方法的互调和参数的互传。
(1) js调oc方法(可以通过data给oc方法传值,使用responseCallback将值再返回给js)
[_bridge registerHandler:@"testObjcCallback" handler:^(id data, WVJBResponseCallback responseCallback) {
NSLog(@"testObjcCallback called: %@", data)
responseCallback(@"Response from testObjcCallback")
}]
这里注意testObjcCallback这个方法的标示。html那边的命名要跟ios这边相同,才能调到这个方法。当然这个名字可以两边商量着自定义。简单明确即可。
(2)oc调js方法(通过data可以传值,通过 response可以接受js那边的返回值 )
id data = @{ @"greetingFromObjC": @"Hi there, JS!" }
[_bridge callHandler:@"testJavascriptHandler" data:data responseCallback:^(id response) {
NSLog(@"testJavascriptHandler responded: %@", response)
}]
注意这里的 testJavascriptHandler也是个方法标示。
(3)oc给js传值(通过 response接受返回值 )
[_bridge send:@"A string sent from ObjC to JS" responseCallback:^(id response) {
NSLog(@"sendMessage got response: %@", response)
}]
(4)oc给js传值(无返回值)
[_bridge send:@"A string sent from ObjC after Webview has loaded."]
与android交互: function onBtnClick() { window.ncp.callOnJs("id")} 与objective-c交互: function onBtnClick(cmd,parameter1) { document.write(Date())document.location="objc://"+callOnJs+":/"+id}