WKWebView与JS交互

1,569 阅读2分钟
  • OC需要用到的方法

 WKUserContentController类

//添加
- (void)addScriptMessageHandler:(id <WKScriptMessageHandler>)scriptMessageHandler name:(NSString *)name;

//移除
- (void)removeScriptMessageHandlerForName:(NSString *)name;

//OC调用js
- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^ _Nullable)(_Nullable id, NSError * _Nullable error))completionHandler;


//协议
WKScriptMessageHandler 

//OC与WKWebView通信桥梁
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
    
    //我收到js传过来的值了
}

WKScriptMessage里面:

@property (nonatomic, readonly, copy) id body; //JS传过来的值
@property (nonatomic, readonly, copy) NSString *name; //消息体名称


@end


  • html代码
<html>
 <head>
     <meta charset="utf-8">
         <title>html代码</title>
         <script type="text/javascript">
            // js传递给OC数据
             function jsCallOCMethod(){
             print("打开摄像头");
                
            /*
             js与OC交互桥梁,只要需要与OC进行交互 就需要这个方法
             <name> 消息名称 如打开手机摄像头、微信分享 
             <messageBody> OC需要接受的值 可以是一个对象,数组,字符串
            */
           
            //格式
            window.webkit.messageHandlers.<name>.postMessage(<messageBody>) 
           
            例如:
            window.webkit.messageHandlers.打开手机摄像头.postMessage({age:"18"});
         }
         
         //OC代码会调用到这个函数,会将id为occalljs的p标签值改为OC传过来的值
         function ocCallJSMethod (param) {
             var x = document.getElementById("occalljs");//找到标签
             x.innerHTML=param;//更改标签值
         }
         </script>
 </head>
 
 <body>
    
    // 界面显示元素   
    <p id="content">几岁是生命中最好的年龄呢? </p>
    
    //这个标签负责接收OC传过来的值
    <p id="occalljs" > 这个标签用来显示OC传过来的值 </p>
    
    // 点击按钮会把事件传递给OC
    <button type="button" onclick= jsCallOCMethod()>拍照</button>
 
 </body>
    
</html>

  • OC核心代码
- (void)viewDidLoad() {

  WKUserContentController * userContentController = [[WKUserContentController alloc]init ];
  
  *** OC与JS交互核心代码
  
  //self 遵循协议
  //name:处理消息的名称
  添加处理消息一
  [userContentController addScriptMessageHandler:self name:@"打开手机摄像头"];
  添加处理消息二
  [userContentController addScriptMessageHandler:self name:@"微信分享"];
  ...
  ...
  ...
  
  
  //创建WKWebView配置config
  WKWebViewConfiguration * config = [[WKWebViewConfiguration alloc]init];
  config.userContentController = userContentController;
  
  
  //创建WKWebview
  WKWebView * wkWebView = [[WKWebView alloc]initWithFrame:CGRectZero configuration:config ];
  _wkWebView.UIDelegate = self;
  _wkWebView.navigationDelegate = self;
  [self addSubview:wkWebView];
  
  //加载url
  NSURLRequest * request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"要加载的url字符串"]]; 
  [self.wkWebView loadRequest:request];
  
 }
 
 
  
  //WKScriptMessageHandler,OC接受js传递过来的值
  
  #pragma mark - WKScriptMessageHandler

 - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
   // html页面点击事件,会传递到这个方法里面来
   // WKScriptMessage : 里面有name、body
   // name 消息名称 OC、js必须统一
   if ([message.name isEqualToString:@"打开手机摄像头"]) {
       //html界面按钮点后,通过js方法,通知原生打开手机摄像头
       
       //原生打开手机摄像头之后,通知html界面
       //OC回调事件给JS,比如刷新html界面颜色
        NSString * str = @"OC代码调用js方法ocCallJSMethod,改变html的值";
       
       //向前端人员获取到js的方法
       //比如js里面有一个方法为:ocCallJSMethod(str)
       
       NSString * jsMethod = [NSString stringWithFormat:@"ocCallJSMethod('%@')",str];
        
       //通过WKWebview的evaluateJavaScript...调用js的ocCallJSMethod()方法
       [self.wkWebView evaluateJavaScript: jsMethod completionHandler:^( id _Nullable data ,NSError * _Nullable error) {
            NSLog(@"error:%@ --- data:%@",error,data);
        }];
       
   }
   
   if ([message.name isEqualToString:@"微信分享"]) {
       // 处理微信分享事件
   }
   
   if...
   if...
   if...
   
  }