原文http://www.cnblogs.com/wanxudong/p/5581367.html  http://www.cnblogs.com/wanxudong/p/5983706.html

前提:在iOS控制器中加载UIWebView,设置代理,遵守UIWebViewDelegate协议。

    iOS与js交互

一、iOS调用JS方法

   通过iOS调用JS代码实现起来比较方便直接调用UIWebView的方法- (nullable NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script;

   1.查询标签

      // 查询标签
      NSString *str = @"var word = document.getElementById('word');"
                             @"alert(word.innerHTML)";
      [webView stringByEvaluatingJavaScriptFromString:str];

   2.为网页添加标签:

      NSString *str = @"var img = document.createElement('img');"
                      "img.src = 'icon5.jpg';"
                      "img.width = 300;"
                      "img.heigth = 100;"
                      "document.body.appendChild(img);";
     [webView stringByEvaluatingJavaScriptFromString:str];

   3.删除网页标签:

      // 删除标签
      NSString *str1 = @"var word = document.getElementById('word');"
                                @"word.remove();";
      [webView stringByEvaluatingJavaScriptFromString:str1];

   4.更改标签:

      // 更改
      NSString *str2 = @"var change = document.getElementsByClassName('change')[0];"
                                "change.innerHTML = 'hello';";
      NSString *result =  [webView stringByEvaluatingJavaScriptFromString:str2];

 

   HTML端代码:

     <!DOCTYPE html>
     <html lang="en">
     <head>
            <meta charset="UTF-8">
            <title>iOS和H5交互</title>
     </head>
     <body>
            <p id="word">6666666666</p>
            <ul>
                 <li class="change">111111</li>
                 <li class="haha">222222</li>
                 <li>333333</li>
                 <li>444444</li>
            </ul>
            <input class="name" placeholder="请输入密码">
            <button onclick="buttonClick()">提交信息</button>
    <script type="text/javascript">
            alert('这个一个弹框');
    </script>
    </body>
    </html>

二、JS调用iOS方法:

   1.第一种方法比较简单,通过字符串的比对。这种方式iOS端代码比较简单,网页加载完成后后台需要重新定义网页url,将移动端需要的参数拼接到url上返回,或者按照和后台约定好的字段来进行字符串比对以达到调用iOS方法的目的。下面贴代码。

     oc代码:(需要实现webView的协议)

     // 拦截协议头,调取系统摄像头
     #pragma mark UIWebViewDelegate
     - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:            (UIWebViewNavigationType)navigationType
    {
        NSString *str = request.URL.absoluteString;
        if ([str containsString:@"wxd://"]) {
             [self getImage];
         }
        return YES;
     }

    - (void)getImage
   {
        if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) { //调用相册
            //实例化控制器
            UIImagePickerController *picker = [[UIImagePickerController alloc] init];
            picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
            picker.delegate = self;
            // 是否有图片选取框
            picker.allowsEditing = YES;
            [self presentViewController:picker animated:YES completion:nil];
        }
    }
   HTML端代码:
   <!DOCTYPE html>
   <html lang="en">
          <head>
          <meta charset="UTF-8">
          <title>在html中调用oc的方法</title>
          </head>
          <body>
                  <button onclick="getImage()">访问相册</button>
          <script type="text/javascript">
                  function getImage(){
                        window.location.href = "wxd://getImage";
                  }
          </script>
          </body>
   </html>

   2.第二种方法,JS直接用oc方法名来调用oc方法,类似于安卓.addJavascriptInterface(new JsObject(), "Android")方法,头文件需要导入#import <JavaScriptCore/JavaScriptCore.h>。

      首先创建一个继承自NSObject的类,在这里我命名为JSTestObjext,.h代码如下:

iOS与js交互

     .m中实现协议方法,代码如下:

iOS与js交互

  之后在加载webView的控制器中调用:

iOS与js交互

到此为止,oc代码就已经写完了,我们只需告诉JS端使用testobject类,就可以调oc的方法了。下面附上JS调用的代码:

iOS与js交互

到此公司里所使用的iOS与H5交互的方法就都写在这里了。



重点来了!

在这里推荐一个比较好的第三方库即:WebViewJavascriptBridge   , 我没试过, 如果有需求,就试试,哈哈 ,懒加载啊

地址:https://github.com/marcuswestin/WebViewJavascriptBridge

通过使用该库可以轻松实现JS与原生交互。

//初始化WebViewJavascriptBridge方法

_bridge= [WebViewJavascriptBridge bridgeForWebView:self.BookWebView webViewDelegate:self handler:^(id data,WVJBResponseCallback responseCallback) {

}];

//原生与JS约定接口名为“testObjcCallback”,data是JS传递过来的信息,responseCallback来将信息传递给JS

[_bridge registerHandler:@"testObjcCallback" handler:^(id  data,WVJBResponseCallback responseCallback) {

responseCallback("postInfomationToJS")

}];


UIWebView页面信息的离线缓存

推荐一个比较好的第三方库RNCachingURLProtocol ,只需要在AppDelegate中加入下面方法即可。

[NSURLProtocolregisterClass:[RNCachingURLProtocolclass]];

地址:https://github.com/rnapier/RNCachingURLProtocol



js 调 iOS  , 另一种方法

一、原生框架<JavaScriptCore/JavaScriptCore>

(1)JavaScriptCore: 是一种JavaScript引擎,主要为webKit提供脚本处理能力,可以JS调用OC,也可以OC调用JS;

  (2) JSContext: 代表了JS的执行环境,通过-evalueScript: 方法就可以执行-- JS代码;

  (3) JSValue: 他封装了JS与OC中对应的类型,以及调用JS的API等;

  (4) JSExport: 是一个协议,遵守此协议,就可以定义我们自己的协议,在协议中声明的API都会在JS中暴露出来,才能调用;


二、交互方法

1.第一种:直接拦截H5页面中点击事件的URL,可以截取这个URL中的参数,进行拼接,然后跳转到自己指定的界面;

[objc] view plain copy
 iOS与js交互iOS与js交互
  1. #pragma mark ------------ 交互  
  2. -(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType  
  3. {  
  4. //     直接 截取后面的id  
  5.     NSString *str = request.URL.resourceSpecifier;  
  6.     NSLog(@"request.URL.resourceSpecifier = %@",request.URL.resourceSpecifier);  
  7.     NSString *strTwo = [NSString stringWithFormat:@"http:%@",str];  
  8.     NSRange range = [strTwo rangeOfString:@"newbieImg/"];  
  9.     if (range.location != NSNotFound) {  
  10.         NSArray *array = [strTwo componentsSeparatedByString:@"newbieImg/"];  
  11.         NSString *strId = array[1];  
  12.         NSLog(@"strId = %@", strId);  
  13.         CCCCCViewController *courseVC = [[CCCCCViewController alloc] init];  
  14.         courseVC.urlId = strTwo;  
  15.         [self.navigationController pushViewController:courseVC animated:YES];  
  16.         return NO;  
  17.     }  
  18.     return YES;  
  19. }  
  20.    

2.需要与后台也就是写H5的人约定方法。但这里有两种方法,一种是JS调用OC, 一种是OC调用JS

(1)JS调用OC,并且传递参数

 

[objc] view plain copy
 iOS与js交互iOS与js交互
  1. //第一步 添加框架,引入头文件  
  2. #import <JavaScriptCore/JavaScriptCore.h>  
  3.   
  4. @interface WebCenterViewController ()<UIWebViewDelegate>  
  5. @property(nonatomic,strongUIWebView *webView;  
  6. //第二步 声明属性  
  7. @property (nonatomicstrongJSContext *context;  
  8.   
  9. @end  

第三步,就需要知道后台指定的方法是什么了,比如




test1是一个无参数的方法,test2是一个有参数的方法,这时我们就可以在webView网页加载完毕的那个方法中写到:

[objc] view plain copy
 iOS与js交互iOS与js交互
  1. #pragma mark ------------ webView加载完毕  
  2. -(void)webViewDidFinishLoad:(UIWebView *)webView  
  3. {    NSLog(@"网页加载完毕");  
  4.     //在网页加载完成后,获取每个参数  
  5.     //获取JS的运行环境  
  6.     _context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];  
  7.     //JS调用无参数OC  
  8.     __weak WebCenterViewController *weakSelf = self;  
  9.     _context[@"test1"] = ^() {  
  10.         [weakSelf methond];  
  11.     };  
  12.       
  13.     //JS调用有参数的OC  
  14.     _context[@"test2"] = ^() {  
  15.     //用数组接收传过来的多个参数  
  16.         NSArray *paramArray = [JSContext currentArguments];  
  17.         //然后取出相对应的值  
  18.         NSString *str1 = paramArray[0];  
  19.         NSString *str2 = paramArray[1];  
  20.         [weakSelf methondParam:str1 withStr:str2];  
  21.     };  
  22.       
  23.   
  24. }  
  25.   
  26. //无参数的方法  
  27. - (void)methond {  
  28.     NSLog(@"调用无参数的方法");  
  29.   
  30. }  
  31.   
  32. //有参数的方法  
  33. - (void)methondParam:(NSString *)str1 withStr:(NSString *)str2 {  
  34.     NSLog(@"str1 = %@, str2 = %@", str1, str2);  
  35. }  


注意::::调用的方法名test1,test2,一定要和html中的保持一致!!!!!!


相关文章: