ios ——JS 与OC混编

来源:互联网 发布:交互设计师软件 编辑:程序博客网 时间:2024/06/05 23:31

ios7之后,ios中加入了JavaScriptCore框架。该框架让Objective-C和JavaScript代码直接的交互变得更加的简单方便。

一、JSContext 与 JSValue

JSContext是OC与js交互的中间上下文,用于相互转化。
在iOS框架中,凡是带session或者context后缀的,这种类一般自己不干活,作用一般都是两个:1.管理其他类,帮助他们搭建沟通桥梁,好处就是解耦 2.负责帮助我们管理复杂环境下的内存
context与session不同之处是:session一般与硬件打交道,例如摄像头捕捉ARSession,网卡的调用NSURLSession等使用的都是session后缀。没有硬件参与,一般用context,如绘图上下文,自定义转场上下文等。

JSValue则可以说是JavaScript和Object-C值之间互换的桥梁,它提供了多种方法可以方便地把JavaScript数据类型转换成Objective-C,或者是转换过去。

二、OC 调用js代码

JSContext *context = [JSContext new];JSValue *result = [context evaluateScript:@"1 + 2"];    NSLog(@"%.2f",[result toDouble]);

三、 OC调用JS 的函数

 //先定义一句js上下文,带有sum函数    JSContext *context = [JSContext new];    NSString *js = @"function sum(a,b) {return a+b;}";    [context evaluateScript:js];    JSValue *sum = context[@"sum"];    JSValue *result = [sum callWithArguments:@[@1,@2]];    NSLog(@"%.2f",[result toDouble]);

四、在OC中js 中报错

如果js代码报错,项目中是无法体现的,所以要进行异常处理

 JSContext *context = [JSContext new];    context.exceptionHandler = ^(JSContext *context, JSValue *exception) {        NSLog(@"%@",exception);    };    [context evaluateScript:@"a.b = 123"];

五、block 与 js 进行互动

JSContext *context = [JSContext new];    //block 与 js 进行互动时, block里面不要调用外边oc的变量    context[@"sum"]=^(int a, int b) {        //想在这里拿到contextz        //JSContext *ctx = [JSContext currentContext];        return a + b;    };    JSValue *result = [context evaluateScript:@"sum(1,2)"];    NSLog(@"%.2f",[result toDouble]);

六、 给js中添加对象

创建Point3D类,利用协议

Point3D.h文件

#import <Foundation/Foundation.h>#import <JavaScriptCore/JavaScriptCore.h>@protocol Point3DExport <JSExport>@property double x;@property double y;@property double z;-(double)length;@end@interface Point3D : NSObject<Point3DExport>{    JSContext *context;}-(id)initWithContext:(JSContext *)ctx;@end

Point3D.m文件

#import "Point3D.h"@implementation Point3D@synthesize z;@synthesize y;@synthesize x;-(id)initWithContext:(JSContext *)ctx{    if (self =[super init]) {        context = ctx;        context[@"Point3D"] = [Point3D new];    }    return self;}-(double)length {    return sqrt(self.x * self.x + self.y * self.y + self.z * self.z);}@end

调用

JSContext *context = [JSContext new];    Point3D *point3D = [[Point3D alloc] initWithContext:context];    point3D.x = 1;    point3D.y = 2;    point3D.z = 3;    context[@"point3D"] = point3D;    NSString *script = @"point3D.x = 2;point3D.y = 2;point3D.length()";    JSValue *result = [context evaluateScript:script];     NSLog(@"%.2f",[result toDouble]);

当执行 context[@”point3D”] = point3D;时,相当于通过OC往js中添加point3D对象,但是js中并没有point3D class,只是把对象塞了过来。

七、OC 调用js 文件

创建test.js

这里写图片描述

var foo = function(a) {    return "Hello Oc,I'm foo in JS."+a;};function bar(a) {    return "Hello Oc,I'm bar in JS."+a;};foo(123);bar(123);console.log(foo(123));

此时console不能打印在xcode控制台
因此要创建Console类来重写打印方法

Console.h

#import <Foundation/Foundation.h>#import <JavaScriptCore/JavaScriptCore.h>@protocol ConsoleExport <JSExport>- (void)log;@end@interface Console : NSObject <ConsoleExport>{    JSContext *context;}-(id)initWithContext:(JSContext *)ctx;@end

Console.m

#import "Console.h"@implementation Console -(id)initWithContext:(JSContext *)ctx{    if (self =[super init]) {        context = ctx;        context[@"Console"] = [Console new];    }    return self;}-(void)log {    //所有的参数的数组    NSArray *args = [JSContext currentArguments];    NSLog(@"%@",[args componentsJoinedByString:@","]);}@end

调用

JSContext *context = [JSContext new];    context.exceptionHandler = ^(JSContext *context, JSValue *exception) {        NSLog(@"%@",exception);    };    context[@"console"] = [[Console alloc]initWithContext:context];    [self loadScriptWithContext:context WithFileName:@"test.js"];

demo代码下载地址

原创粉丝点击