JavaScriptCore框架使用



iOS 7中苹果正式开放加入了JavaScriptCore框架。该框架让Objective-C和JavaScript 直接进行交互 。这个框架其实只是基于WebKit实现的JavaScriptCore的的一个包装

这里写图片描述

要使用JavaScriptCore,首先我们需要引入它的头文件

#import <JavaScriptCore/JavaScriptCore.h>

这个框架主要包括五个对象:

 #import "JSContext.h"  //提供运行环境 
 #import "JSValue.h"  //是JSContext执行后的返回结果,他包括多种类型(比如基本数据类型和函数类型,对象类型等)
 #import "JSManagedValue.h" //是JSValue的封装
 #import "JSVirtualMachine.h"  //提供了底层资源
 #import "JSExport.h"   //是一种协议

JSContext对象



在OC中初始化JSContext对象,可以直接init初始化,也可根据当前webView的键获取到jscontext

 // init初始化JSContext对象 
 JSContext *context = [[JSContext alloc] init]; 
 
 //创建JSContext 对象(通过当前webView的键获取到JSContext)
 JSContext *context=[self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
通过JSContext对象调用js代码,这里是一个弹窗测试:

1.OC直接拼写,实现js弹窗

 NSString *alertJS=@"alert('test js OC')"; //准备执行的js代码
 [context evaluateScript:alertJS];//通过oc方法调用js的alert

2.引入js文件,调用js中的方法,实现js弹窗

//html代码  
//在 index.html中加入js文件
<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
       <link rel="stylesheet" type="text/css" href="html/stylesheets/index_css.css" />
       <script type="text/javascript" src='html/js/test.js'></script>//引入js
  <title>SimonLike</title>
</head>

//js代码 
// test.js文件中方法
function jsalert(test){
     alert(test);
}

//OC代码
//在OC中找到html的路径转换格式,用UIWebView进行加载,这个时候js文件、css文件也一起加了进来;
- (void)loadHtml {
   //创建webview
    CGRect webViewRect = CGRectMake(0, 64, self.view.frame.size.width, self.view.frame.size.height - 64);
    self.webView = [[UIWebView alloc] initWithFrame:webViewRect];
    self.webView.backgroundColor = [UIColor lightGrayColor];
    self.webView.scalesPageToFit = YES;
    self.webView.delegate = self;
    [self.view addSubview:self.webView];
   
   //webview加载html
    NSString * htmlPath = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"];
    NSURL *url = [NSURL fileURLWithPath:htmlPath];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    [self.webView loadRequest:request];
}

//在webview加载完成后,调用js文件中的方法,
-(void)webViewDidFinishLoad:(UIWebView *)webView
{
    NSString *alertJS=@"jsalert('test js OC')"; //准备执行的js代码
    [context evaluateScript:alertJS];//通过oc方法调用js的alert
}

js调用iOS中OC方法;其中jscandoiOS就是js的方法名称,赋给是一个block 里面是iOS代码,注意事项:1,在block中避免循环引用,我们一般会对self进行弱化;2,在block中直接调用OC方法,可能会导致异常或崩溃,所以为了避免异常或崩溃 js调用oc方法时 放在GCD中 进行异步操作;


//OC中拼接,没有加载js文件写法
[context evaluateScript:@"jscandoiOS(tag)"];

//加载js文件写法
function jscandoiOS(tag){
}
 __weak typeof(self)weakSelf = self;//避免循环引用 弱化
     context[@"jscandoiOS"] = ^(JSValue *value){
        NSString *str = value.toString;//把接收到的JSValue对象转换OC中的NSString类型
        dispatch_async(dispatch_get_main_queue(), ^{//在GCD中 进行异步操作
            switch (str.integerValue) {
                case 0:{//iOS  
                 // you can do ...
                }
                    break;
                  ...                 
                default:
                    break;
            }
            
        });
    };

JSValue对象


上面代码中,点击js方法“jscandoiOS”在iOS中能监听到并做出相应处理,在iOS这边接收到js所传值为JSValue对象,然后转换为OC中的NSString;对于JSValue对象转换OC类型的方法很多:

- (id)toObject;
- (BOOL)toBool;
- (double)toDouble;
- (int32_t)toInt32;
- (NSString *)toString;
- (NSArray *)toArray;
- (id)toObject;
- (NSDictionary *)toDictionary;
...  

JSExport对象


JSExport是一个协议,很方便的让JavaScript能够访问和操作Objective-C对象。

1,自定义个协议(JSExportTest)继承自JSExprot,并定义需要暴露给js的属性和方法,例:

@protocol JSExportTest <JSExport>

- (NSString *)personName;//暴露给js调用

@end
 

2,新建一个类对象,实现协议和方法,例:
person.h


#import "JSExportTest.h"

@interface person : NSObject<JSExportTest>
@end

person.m

#import "person.h"

@implementation person
- (NSString *)personName{
    return @"this is OC";
}
@end

3,js方法调用

-(void)jsJSExport {

    person *p = [[person alloc]init];
    context[@"person"] = p;
    JSValue *value = [context evaluateScript:@"person.personName()"];
    
    NSLog(@"context->%@",value);
}

打印结果: context->this is OC

JSVirtualMachine对象



一个 JSVirtualMachine可以运行多个context,由于都是在同一个堆内存和同一个垃圾回收下,相互之间传值是没问题的。如果在不同的JSVirtualMachine传值,垃圾回收就不知道他们之间的关系了,可能会引起异常。

JSVirtualMachine有两个方法:一个是保存JSValue对象,一个是移除JSValue对象:

//保存 
- (void)addManagedReference:(id)object withOwner:(id)owner;
//移除 
- (void)removeManagedReference:(id)object withOwner:(id)owner;

JSVirtualMachine对象


引入:http://www.jianshu.com/p/bbfa8dee967e

JavaScriptCore中引入了JSManagedValue类型,该类型主要是作为一个引用桥接,将JSValue转为JSManagedValue类型后,可以添加到JSVirtualMachine对象中,这样能够保证你在使用过程中JSValue对象不会被释放掉,当你不再需要该JSValue对象后,从JSVirtualMachine中移除该JSManagedValue对象,JSValue对象就会被释放并置空。

大家不要被这么多对象类型搞晕了,简单一点说,JSVirtualMachine就是一个用于保存弱引用对象的数组,加入该数组的弱引用对象因为会被该数组retain,所以保证了使用时不会被释放,当数组里的对象不再需要时,就从数组中移除,没有了引用的对象就会被系统释放。

异常处理

context.exceptionHandler = ^(JSContext *context, JSValue *exception) {
    [JSContext currentContext].exception = exception; 
     NSLog(@"exception:%@",exception); 
};
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,319评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,801评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,567评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,156评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,019评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,090评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,500评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,192评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,474评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,566评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,338评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,212评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,572评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,890评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,169评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,478评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,661评论 2 335

推荐阅读更多精彩内容