Home > Article > Web Front-end > Detailed explanation of examples of intermodulation between JS and OC
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.
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);}
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); }
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];}
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]; }
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 protocol4.1 JS calls OC custom classCustom 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); @endCustom 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); } @endCalling 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]; }4.1 JS calling OC system classesProblem: 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 runtimeCustom protocol (UILabelJSExport)
@protocolUILabelJSExport @property(nonatomic, strong) NSString *text; @endJS 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]; }[Related recommendations]1.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!