10分钟 搞定JS和iOS的交互

lez02f064 9年前
   <p>JS和iOS的交互</p>    <p>JS和iOS交互,是每个应用都少不了的需求,尤其是在页面变动比较大的情况,页面经常更新,JS和iOS交互用起来就很幸福了。</p>    <p>进入正题</p>    <h2>一、贴上h5的代码</h2>    <pre>  <code class="language-xml"><html>      <head>          <meta http-equiv="Content-Type"    content="text/html;charset=UTF-8">              <script type="text/javascript">                    var share = JSON.stringify({"title": "Migi000",                                             "desc": "简书",                                             "shareUrl": "http://www.jianshu.com/p/f896d73c670a"                                             });                //IOS              function startFunction(share){                  window.android.startFunction(share)//android              }                    </script>      </head>      <body>          <br/>          <h1>Objective-C和JavaScript交互的那些事</h1> <br/>          <input  type="button" value="Share" onClick="startFunction(share)" >点击调用原生代码并传递参数</a>                </body></html></code></pre>    <p>注释:这里的方法要写在head里面,PS:在测试这段代码之前,本身方法是写在body中,但是Android不能实现,后来放在head中就可以实现,这个没有太多了解是什么原因,有大神可以指教</p>    <h2>二、快速接入 - block解决</h2>    <p>.m文件如下</p>    <pre>  <code class="language-javascript">////  ViewController.m//  jsTest////  Created by fangpinhui on 16/5/18.//  Copyright © 2016年 Lumic. All rights reserved.//    #import "ViewController.h"#import <JavaScriptCore/JavaScriptCore.h>    @interface ViewController ()<UIWebViewDelegate>@property (nonatomic)UIWebView *webView;  @property (nonatomic)JSContext *jsContext;  @property (nonnull,strong) UIButton *btn;  @end    @implementation ViewController    - (void)viewDidLoad {      [super viewDidLoad];        self.webView = [[UIWebView alloc]initWithFrame:self.view.bounds];      self.webView.delegate = self;      [self.view addSubview:_webView];      NSString *str = [[NSBundle mainBundle] pathForResource:@"migi" ofType:@"html"];      [self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:@"f"]]];  //    [self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://192.168.1.59:8020/Online-Booking/index.html"]]];        //  在上面添加一个按钮,实现oc端控制h5实现弹alert方法框      self.btn = [[UIButton alloc] initWithFrame:CGRectMake(100, 400, 100, 40)];      self.btn.backgroundColor = [UIColor redColor];      [self.btn addTarget:self action:@selector(showAlert) forControlEvents:UIControlEventTouchUpInside];      [self.view addSubview:self.btn];      }  - (void)showAlert  {      //要将script的alert()方法转化为string类型      NSString *alertJs=@"alert('Hello Word')";      [_jsContext evaluateScript:alertJs];  }    - (void)webViewDidFinishLoad:(UIWebView *)webView{      _jsContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];      _jsContext[@"startFunction"] =^(id obj){  ////这里通过block回调从而获得h5传来的json数据          /*block中捕获JSContexts          我们知道block会默认强引用它所捕获的对象,如下代码所示,如果block中直接使用context也会造成循环引用,这使用我们最好采用[JSContext currentContext]来获取当前的JSContext:           */          [JSContext currentContext];          NSData *data = [(NSString *)obj dataUsingEncoding:NSUTF8StringEncoding ];          NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];          NSLog(@" data   %@   ======  ShareUrl %@",obj,dict[@"shareUrl"]);      };      //      _jsContext.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {          context.exception = exceptionValue;          //比如把js中的方法名改掉,OC找不到相应方法,这里就会打印异常信息          NSLog(@"异常信息:%@", exceptionValue);      };      }    - (void)didReceiveMemoryWarning {      [super didReceiveMemoryWarning];      // Dispose of any resources that can be recreated.  }    @end</code></pre>    <p>注释:<br> 1.#import <JavaScriptCore/JavaScriptCore.h> 导入放在.h文件中<br> 2.因为这里h5需要调用我们的Native定义的startFunction 方法,以及需要的回调的数据格式,所以这里需要和h5沟通一下</p>    <p>这就是简单的js和oc之间的交互,可以使用在平台的应用中,下面是遇到的问题汇总,如有遇到问题,积极分享咯!</p>    <h2>问题汇总:</h2>    <p>问题1.<br> 在执行回调时,iOS可以实现回调方法,而Android无法实现,双发都检查了代码,没有问题,检查h5代码时,发现方法写在body中,Android无法实现回调</p>    <p>解决办法:<br> h5的方法写在head中,实现了,好吧,大神指导好吗?</p>    <p>问题2:<br> 在进行js和iOS的交互时,我写了个代码,demo中我把#import <JavaScriptCore/JavaScriptCore.h><br> 库的引入放在了.m文件中,block回调时拿到了数据,但是当在公司项目中实现时,怎么都不执行回调方法,很是诡异,怎么都无法实现,</p>    <p>解决办法:<br> 把库的导入#import <JavaScriptCore/JavaScriptCore.h> 放在.h文件中就执行了。满面懵逼!,求指教</p>    <p>来自:http://www.jianshu.com/p/0819c84f9ef1</p>    <p> </p>