Home > Web Front-end > JS Tutorial > Detailed explanation of examples of intermodulation between JS and OC

Detailed explanation of examples of intermodulation between JS and OC

零下一度
Release: 2017-05-10 11:06:10
Original
1644 people have browsed it

1. JavaScriptCore commonly used classes

JavaScriptCore function: JavaScriptCore is Apple’s native API, used for JS and OC interactive.

JSContext: JS running environment, use it to execute JS code, and use it to obtain data in JS

JSValue: used to receive the data type obtained in JS, which can be any Object, method.

2. OC calls JS

Essence: The variables and methods have been defined in the JS code, obtain them through OC, and call

Steps:

1. Create JS running environment

2. Execute JS code

3. Get JS data (variables, methods)

4. Use JS data, methods

2.1 Get the variables defined in JS

You can directly modify the value of the variable in JS through OC

#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);}
Copy after login

2.2 Get the method defined in JS and call it

Implement OC calling JS method

#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);
}
Copy after login

3. JS calls the block in OC

Essence: There is no OC block in JS at the beginning. Therefore, you cannot directly call the OC block. You need to generate the OC block method in JS and then call it through JS.

Steps:

1. Create JS running environment

2. Generate corresponding OC code in JS

3. Use JS to call, in JS The block method generated in the environment can be called into the block of OC.

3.1 JS calls the block without parameters in OC

I want to call the block without parameters in OC through JS

#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];}
Copy after login

3.2 JS calls the block with parameters in OC

Want to call the block with parameters in OC through JS

- (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];
}
Copy after login

4. JS calls classes in OC

Essence: There is no OC class in JS at the beginning. You need to generate the OC class in JS first, and then call it through JS.

Steps

1. The OC class must comply with the JSExport protocol. As long as it complies with the JSExport protocol, JS will generate this class

2. But it is not enough, there are ## in the class #Properties and methods, also need to be generated in JS

3.JSExport itself does not have its own properties and methods, you need to customize a protocol,

inherit JSExport, in your own protocol Expose the properties and methods that need to be used in JS

4. In this way, your class only needs to inherit its own protocol, and JS will automatically generate the class, including the properties and methods declared in its own protocol

4.1 JS calls OC custom class

Custom protocol (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
Copy after login
Custom class (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
Copy after login
Calling OC custom classes through JS

#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];
}
Copy after login
4.1 JS calling OC system classes

Problem: I want to call the system’s own classes through JS What should we do? We can't modify the files of the system's own classes.

Just like calling custom classes, we also need to make a custom protocol to inherit JSExport and describe which attributes need to be exposed (which system classes we want to Attributes are exposed, just in their own protocol declaration)

Add a protocol to the class through runtime

Custom protocol (UILabelJSExport)

@protocolUILabelJSExport
@property(nonatomic, strong) NSString *text;
@end
Copy after login
JS call OC system class

#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];
}
Copy after login
[Related recommendations]

1.

Free js online video tutorial

2.

JavaScript Chinese Reference Manual

3.

php.cn Dugu Jiujian (3) - JavaScript Video Tutorial

The above is the detailed content of Detailed explanation of examples of intermodulation between JS and OC. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template