搜索
首页web前端js教程JS与OC互调的实例详解

一、JavaScriptCore常用的类

JavaScriptCore作用:JavaScriptCore是苹果原生API,用来JS和OC交互的。

JSContext: JS运行环境,用它去执行JS代码,并且通过它去获取JS里的数据

JSValue: 用于接收JS中获取的数据类型,可以是任一对象,方法。

二、OC调用JS

本质:JS代码中已经定义好变量和方法,通过OC去获取,并且调用

步骤:

1.创建JS运行环境

2.执行JS代码

3.获取JS数据(变量,方法)

4.使用JS数据,方法

2.1 获取定义在JS中的变量

可以直接通过OC修改JS中变量的值

#pragma mark - 获取JS中定义的变量
- (void)getJSVar{
// JS代码
NSString *jsCode = @"var arr = [1,2,3]";
// 创建JS运行环境
JSContext *ctx = [[JSContext alloc] init];
// 执行JS代码
[ctx evaluateScript:jsCode];
// 因为变量直接定义在JS中,所以可以直接通过JSContext获取,根据变量名称获取,相当于字典的Key
// 只有先执行JS代码,才能获取变量
JSValue *jsArr = ctx[@"arr"]; 
  jsArr[0] = @5;
// 打印结果:5,2,3
NSLog(@"%@",jsArr);}

2.2 获取定义在JS中的方法,并且调用

实现OC调用JS方法

#pragma mark - OC调用JS
// OC调用JS方法,并获取返回结果
- (void)ocCallJSFunc{
NSString *jsCode =@"function hello(say){"
" return say; "
"}";
// 创建JS运行环境
JSContext *ctx = [[JSContext alloc] init];
// 因为方法直接定义在JS中,所以可以直接通过JSContext获取,根据方法名称获取,相当于字典的Key
// 执行JS代码
[ctx evaluateScript:jsCode];
// 获取JS方法,只有先执行JS代码,才能获取
JSValue *hello = ctx[@"hello"];
// OC调用JS方法,获取方法返回值
JSValue *result = [hello callWithArguments:@[@"你好"]];
// 打印结果:你好
NSLog(@"%@",result);
}

三、JS调用OC中的block

本质:一开始JS中并没有OC的block,所以没法直接调用OC的block,需要把OC的block,在JS中生成方法,然后在通过JS调用。

步骤:

1.创建JS运行环境

2.在JS中生成对应的OC代码

3.使用JS调用,在JS环境中生成的block方法,就能调用到OC的block中.

3.1 JS调用OC中不带参数的block

想通过JS调用OC中不带参数的block

#pragma mark - JS调用OC中不带参数的block
- (void)jsCallOCBlock1WithNoneArguments{
// 创建JS运行环境
JSContext *ctx = [[JSContext alloc] init];
// JS调用Block方式// 由于JS本身没有OC这个代码,需要给JS中赋值,就会自动生成右边的代码.
// 相当于在JS中定义一个叫eat的方法,eat的实现就是block中的实现,只要调用eat,就会调用block
ctx[@"eat"] = ^(){NSLog(@"吃东西"); 
  };
// JS执行代码,就会直接调用到block中
NSString*jsCode =@"eat()"; 
  [ctx evaluateScript:jsCode];}

3.2 JS调用OC中带参数的block

想通过JS调用OC中带参数的block

- (void)jsCallOCBlockWithArguments{
// 创建JS运行环境
JSContext *ctx = [[JSContext alloc] init];
// 2.调用带有参数的block
// 还是一样的写法,会在JS中生成eat方法,只不过通过[JSContext currentArguments]获取JS执行方法时的参数
ctx[@"eat"] = ^(){
// 获取JS调用参数
NSArray *arguments = [JSContext currentArguments];
NSLog(@"吃%@",arguments[0]); 
  };
// JS执行代码,调用eat方法,并传入参数面包
NSString*jsCode =@"eat('面包')"; 
  [ctx evaluateScript:jsCode];
}

四、JS调用OC中的类

本质:一开始JS中并没有OC的类,需要先在JS中生成OC的类,然后在通过JS调用。

步骤

1.OC类必须遵守JSExport协议,只要遵守JSExport协议,JS才会生成这个类

2.但是还不够,类里面有属性和方法,也要在JS中生成

3.JSExport本身不自带属性和方法,需要自定义一个协议,继承JSExport,在自己的协议中暴露需要在JS中用到的属性和方法

4.这样自己的类只要继承自己的协议就好,JS就会自动生成类,包括自己协议中声明的属性和方法

4.1 JS调用OC自定义类

自定义协议(PersonJSExport)

@protocolPersonJSExport
@property(nonatomic, strong) NSString *name;
-(void)play;
// 调用多个参数的方法,JS函数命名规则和OC还不一样,很可能调用不到对应的JS生成的函数,为了保证生成的JS函数和OC方法名一致,OC提供了一个宏JSExportAs,用来告诉JS应该生成什么样的函数对应OC的方法,这样就不会调错了。
// PropertyName:JS函数生成的名字
// Selector:OC方法名
// JS就会自动生成playGame这个方法JSExportAs(playGame,
- (void)playWithGame:(NSString *)gametime:(NSString *)time);
@end

自定义类(Person)

@interfacePerson: NSObject
@property(nonatomic, strong) NSString *name;
-(void)playWithGame:(NSString*)gametime:(NSString*)time;
@end
@implementationPerson
-(void)play{
NSLog(@"%@玩",_name);
}
-(void)playWithGame:(NSString*)gametime:(NSString*)time{
NSLog(@"%@在%@玩%@",_name,time,game);
}
@end

通过JS调用OC自定义类

#pragmamark - JS调用OC自定义类
- (void)jsCallOCCustomClass{
// 创建Person对象
Person *p = [[Person alloc] init];   
p.name = @"zs";   
JSContext *ctx = [[JSContext alloc] init];
// 会在JS中生成Person对象,并且拥有所有值
// 前提:Person对象必须遵守JSExport协议,
ctx[@"person"] = p;
// 执行JS代码
// 注意:这里的person一定要跟上面声明的一样,因为生成的对象是用person引用// NSString *jsCode = @"person.play()";
NSString *jsCode = @"person.playGame('德州扑克','晚上')"; 
  [ctx evaluateScript:jsCode];
}

4.1 JS调用OC系统类

问题:系统自带的类,想要通过JS调用怎么办,我们又没办法修改系统自带类的文件

和调用自定义类一样,也要弄个自定义协议继承JSExport,描述需要暴露哪些属性(想要把系统类的哪些属性暴露,就在自己的协议声明)

通过runtime,给类添加协议

自定义协议(UILabelJSExport)

@protocolUILabelJSExport
@property(nonatomic, strong) NSString *text;
@end

JS调用OC系统类

#pragma mark - JS调用OC系统类
- (void)jsCallOCSystemClass{ 
  // 给系统类添加协议 class_addProtocol([UILabel class],
@protocol(UILabelJSExport)); 
  // 创建UILabel 
UILabel *label= [[UILabel alloc] initWithFrame:CGRectMake(50, 50, 100, 100)];
[self.view addSubview:label];
JSContext *ctx = [[JSContext alloc] init];   
// 就会在JS中生成label对象,并且用laebl引用
ctx[@"label"] =label;
// 利用JS给label设置文本内容
NSString *jsCode = @"label.text = 'Oh Year'"; 
  [ctx evaluateScript:jsCode];
}

【相关推荐】

1. 免费js在线视频教程

2. JavaScript中文参考手册

3. php.cn独孤九贱(3)-JavaScript视频教程

以上是JS与OC互调的实例详解的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
如何使用JS和百度地图实现地图平移功能如何使用JS和百度地图实现地图平移功能Nov 21, 2023 am 10:00 AM

如何使用JS和百度地图实现地图平移功能百度地图是一款广泛使用的地图服务平台,在Web开发中经常用于展示地理信息、定位等功能。本文将介绍如何使用JS和百度地图API实现地图平移功能,并提供具体的代码示例。一、准备工作使用百度地图API前,首先需要在百度地图开放平台(http://lbsyun.baidu.com/)上申请一个开发者账号,并创建一个应用。创建完成

如何使用JS和百度地图实现地图多边形绘制功能如何使用JS和百度地图实现地图多边形绘制功能Nov 21, 2023 am 10:53 AM

如何使用JS和百度地图实现地图多边形绘制功能在现代网页开发中,地图应用已经成为常见的功能之一。而地图上绘制多边形,可以帮助我们将特定区域进行标记,方便用户进行查看和分析。本文将介绍如何使用JS和百度地图API实现地图多边形绘制功能,并提供具体的代码示例。首先,我们需要引入百度地图API。可以利用以下代码在HTML文件中导入百度地图API的JavaScript

js字符串转数组js字符串转数组Aug 03, 2023 pm 01:34 PM

js字符串转数组的方法:1、使用“split()”方法,可以根据指定的分隔符将字符串分割成数组元素;2、使用“Array.from()”方法,可以将可迭代对象或类数组对象转换成真正的数组;3、使用for循环遍历,将每个字符依次添加到数组中;4、使用“Array.split()”方法,通过调用“Array.prototype.forEach()”将一个字符串拆分成数组的快捷方式。

如何使用JS和百度地图实现地图热力图功能如何使用JS和百度地图实现地图热力图功能Nov 21, 2023 am 09:33 AM

如何使用JS和百度地图实现地图热力图功能简介:随着互联网和移动设备的迅速发展,地图成为了一种普遍的应用场景。而热力图作为一种可视化的展示方式,能够帮助我们更直观地了解数据的分布情况。本文将介绍如何使用JS和百度地图API来实现地图热力图的功能,并提供具体的代码示例。准备工作:在开始之前,你需要准备以下事项:一个百度开发者账号,并创建一个应用,获取到相应的AP

js中new操作符做了哪些事情js中new操作符做了哪些事情Nov 13, 2023 pm 04:05 PM

js中new操作符做了:1、创建一个空对象,这个新对象将成为函数的实例;2、将新对象的原型链接到构造函数的原型对象,这样新对象就可以访问构造函数原型对象中定义的属性和方法;3、将构造函数的作用域赋给新对象,这样新对象就可以通过this关键字来引用构造函数中的属性和方法;4、执行构造函数中的代码,构造函数中的代码将用于初始化新对象的属性和方法;5、如果构造函数中没有返回等等。

用JavaScript模拟实现打字小游戏!用JavaScript模拟实现打字小游戏!Aug 07, 2022 am 10:34 AM

这篇文章主要为大家详细介绍了js实现打字小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。

php可以读js内部的数组吗php可以读js内部的数组吗Jul 12, 2023 pm 03:41 PM

php在特定情况下可以读js内部的数组。其方法是:1、在JavaScript中,创建一个包含需要传递给PHP的数组的变量;2、使用Ajax技术将该数组发送给PHP脚本。可以使用原生的JavaScript代码或者使用基于Ajax的JavaScript库如jQuery等;3、在PHP脚本中,接收传递过来的数组数据,并进行相应的处理即可。

js是什么编程语言?js是什么编程语言?May 05, 2019 am 10:22 AM

js全称JavaScript,是一种具有函数优先的轻量级,直译式、解释型或即时编译型的高级编程语言,是一种属于网络的高级脚本语言;JavaScript基于原型编程、多范式的动态脚本语言,并且支持面向对象、命令式和声明式,如函数式编程。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
2 周前By尊渡假赌尊渡假赌尊渡假赌
仓库:如何复兴队友
4 周前By尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒险:如何获得巨型种子
4 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SecLists

SecLists

SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

功能强大的PHP集成开发环境

EditPlus 中文破解版

EditPlus 中文破解版

体积小,语法高亮,不支持代码提示功能