10分钟 搞定JS和OC交互

转载 2016年05月30日 17:28:02

10分钟 搞定JS和OC交互


JS和iOS的交互

JS和iOS交互,是每个应用都少不了的需求,尤其是在页面变动比较大的情况,页面经常更新,JS和iOS交互用起来就很幸福了。

原理:
通过JavaScriptCore解决JS和iOS之间的交互

说明:
JavaScriptCore是封装了JavaScript和Objective-C桥接的Objective-C API,只需要较少的的代码,就可以实现JavaScript与Objective-C的相互调用。
  iOS7之后苹果推出了JavaScriptCore这个框架,从而让web页面和本地原生应用交互起来非常方便,而且使用此框架可以做到Android那边和iOS相对统一,web前端写一套代码就可以适配客户端的两个平台,从而减少了web前端的工作量。
iOS和Android协商好定义方法名称,然后把这个名称告知h5即可,在这里其实也可以有h5定义好,告知我们,这样减少我们的协商。
JavaScriptCore中web页面调用原生应用的方法可以用Delegate或Block两种方法,这里用block实现方法,因为block的方法更加简单一点。

JavaScriptCore中类及协议:
JSContext:给JavaScript提供运行的上下文环境,JSContext是代表JS的执行环境,通过-evaluateScript:方法就可以执行一JS代码
JSValue:JSValue封装了JS与ObjC中的对应的类型,以及调用JS的API等,可以理解为JavaScript和Objective-C数据和方法的桥梁
JSManagedValue:管理数据和方法的类
JSVirtualMachine:处理线程相关,使用较少
JSExport:JSExport是一个协议,遵守此协议,就可以定义我们自己的协议,在协议中声明的API都会在JS中暴露出来,才能调用

进入正题

一、贴上h5的代码

<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>

注释:这里的方法要写在head里面,PS:在测试这段代码之前,本身方法是写在body中,但是Android不能实现,后来放在head中就可以实现,这个没有太多了解是什么原因,有大神可以指教

二、快速接入 - block解决
.m文件如下

//
//  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

注释:
1.#import <JavaScriptCore/JavaScriptCore.h> 导入放在.h文件中
2.因为这里h5需要调用我们的Native定义的startFunction 方法,以及需要的回调的数据格式,所以这里需要和h5沟通一下

这就是简单的js和oc之间的交互,可以使用在平台的应用中,下面是遇到的问题汇总,如有遇到问题,积极分享咯!

问题汇总:
问题1.
在执行回调时,iOS可以实现回调方法,而Android无法实现,双发都检查了代码,没有问题,检查h5代码时,发现方法写在body中,Android无法实现回调

解决办法:
h5的方法写在head中,实现了,好吧,大神指导好吗?

问题2:
在进行js和iOS的交互时,我写了个代码,demo中我把#import <JavaScriptCore/JavaScriptCore.h>
库的引入放在了.m文件中,block回调时拿到了数据,但是当在公司项目中实现时,怎么都不执行回调方法,很是诡异,怎么都无法实现,

解决办法:
把库的导入#import <JavaScriptCore/JavaScriptCore.h> 放在.h文件中就执行了。满面懵逼!,求指教

PS:来简书混,关注是必须的,点赞❤️ 是要给的!

相关文章推荐

10分钟 搞定JS和iOS的交互

JS和iOS的交互 JS和iOS交互,是每个应用都少不了的需求,尤其是在页面变动比较大的情况,页面经常更新,JS和iOS交互用起来就很幸福了。 进入正题 一、贴上h5的代码 htm...
  • hj7jay
  • hj7jay
  • 2016-07-01 09:56
  • 3646

10分钟搞定Matlab GUI

  • 2015-01-11 01:10
  • 1.05MB
  • 下载

10分钟搞定linux编辑器vim的配置

前言Vim是linux操作系统的一款非常强大的编辑器,配置Vim就是要让其形成一个像VS一样的IDE集成环境。所以为了能在linux下实现高效编程和开发,Vim的配置是必须要完成的一项任务。然而,对l...

10分钟搞定matlabGUI.ppt

  • 2012-06-25 23:05
  • 1.05MB
  • 下载

10分钟搞定,slony的安装和配置

最近要配置Postgres的数据复制功能(replication) Replication 分为2类:synchronization 和 asynchronization 在Postgres的最新版本...
  • alajl
  • alajl
  • 2013-08-23 12:17
  • 2087

Python:10分钟搞定不写代码的爬虫

点击头像看历史 你可曾知道 当使用 Chrome 浏览器插件 Web Scraper 可以轻松实现网页数据的爬取 不写代码,鼠标操作,点哪爬哪, 还不用考虑爬虫中的登...

三步10分钟搞定数据库版本的降迁 (将后台数据库SQL2008R2降为SQL2005版本)

前思后想仍觉得实战数据库版本的降迁 一文中的方式不仅老土而且低效,故有了下文三步搞定数据库从MSSQL2008R2 高版本降迁至SQL2005低版本。 整个过程如果思路清晰,数据量小,不过就是10...

三步10分钟搞定数据库版本的降迁 (将后台数据库SQL2008R2降为SQL2005版本)

三步10分钟搞定数据库版本的降迁 (将SQL2008R2降为SQL2005版本)   转载原文,并注明出处!虽无多少技术含量,毕竟是作者心血原创,希望理解。 前思后想仍觉...

10分钟搞定工作周报

有不少老板要求下属写周报,希望通过周报了解部门每个人及整体的工作情况,但很多人在写周报时往往遇到很多问题,比如: 花费很多时间回忆一周做的事情 不知道写什么 不知道用...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)