JavaScriptCore

原创 2016年08月31日 16:54:54

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的键获取到JSContextJSContext *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 {
    JSContext *context=[self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];

    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); 
};

相关文章推荐

JavaScriptCore ios 源代码

  • 2012年08月06日 10:27
  • 1.68MB
  • 下载

javaScriptCore的mac os系统

  • 2012年08月03日 09:52
  • 1.43MB
  • 下载

[iOS] 在桌面應用程式中使用 WebKit (2) - JavaScriptCore

zz from: http://zonble.net/archives/2010_09/1403.php 前一篇最後簡略提了一下 JavaScriptCore Framework。JavaScrip...
  • mkhgg
  • mkhgg
  • 2011年12月26日 23:33
  • 1293

JavaScriptCore-Demo-master.zip

  • 2015年10月27日 15:50
  • 116KB
  • 下载

iOS 基于JavaScriptCore 不等webView加载完毕就交互,网页获取原生内容。 webView的高级用法之JS交互,js与oc的相互调用

一:本文解决的问题:    1.不等webView加载完毕,就能获取原生的内容,    2.举个例子: 加载一个城市生活网页,不等加载完成,h5端获取原生定位所在城市,然后根据城市名不同加载不同的城...
  • horisea
  • horisea
  • 2017年03月09日 10:58
  • 1345

nokia浏览器源码javascriptcore_32

  • 2008年09月24日 10:27
  • 968KB
  • 下载

OC中JavaScriptCore交互 JS交互

  • 2016年06月03日 18:18
  • 66KB
  • 下载

iOS webView的高级用法之JS交互,js与oc的相互调用(JavaScriptCore)

前言:说起JS交互,很多童鞋会黯然色变,感觉很高深的样子。大部分小伙伴只知道一种,哪一种我也说说吧。    1.在webView中将要请求的时候,拦截URL,进行重定向,然而该场景实用有限,网上资料也...
  • horisea
  • horisea
  • 2016年08月12日 15:24
  • 5084

IOS7开发~JavaScriptCore (二)

IOS7开发~JavaScriptCore(一) IOS7开发~JavaScriptCore(二)
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:JavaScriptCore
举报原因:
原因补充:

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