A Simpler Way to Call Objective-C Methods with JavaScript (Experimental)

Note: After v3.6.0, jsb module is about to be deprecated, APIs will be moved to the native module of namespace cc.

Background

Prior to v3.4.0, the reflection mechanism in Using JavaScript to Call Objective-C static methods, not only needed to strictly declare package names and function signatures, but also needed to strictly check the number of parameters to ensure proper operation, which was a complicated step.

Additionally provided in v3.4.0 is another experimental method for simplifying calls from the scripting layer to the native layer. This is a kind of channel, or a bridge, named JsbBridge before introducing other scripting systems, meaning that it serves as a bridge to communicate between script and native APP via the JSB binding.

Note: both ways are working fine, developers can choose to use them according to their actual needs. To use the previous way, please review the Using JavaScript to Call Objective-C documentation.

JavaScript Interface Introduction

The only two interfaces at the scripting level are sendToNative and onNative, which are transfer and receive native layer parameters, respectively. The following points need to be noted when using them:

  • This feature is still in the experimental stage, only string transfers are supported. To transfer objects containing multiple parameters, please consider converting them to the JSON format for transfer and parsing them at different levels.
  • onNative will only record one function at a time, and will override the original onNative method when the property is set again.
  • The sendToScript method is a one-way communication and does not care about the return of the lower level, nor does it tell JavaScript whether the operation succeeded or failed. The developer needs to handle the operation itself.
  1. // JavaScript
  2. export namespace bridge{
  3. /**
  4. * Send to native with at least one argument.
  5. */
  6. export function sendToNative(arg0: string, arg1?: string): void;
  7. /**
  8. * Save your own callback controller with a JavaScript function,
  9. * Use 'jsb.bridge.onNative = (arg0: String, arg1: String | null)=>{...}'
  10. * @param args : received from native
  11. */
  12. export function onNative(arg0: string, arg1?: string | null): void;
  13. }

Objective-C Interface Introduction

The corresponding ObjC interfaces are also dominated by two, including sendToScript and onScript:

  • sendToScript corresponds to sendToNative and represents the parameters to be transferred to JavaScript.
  • onScript corresponds to onNative, which indicates the response behavior after receiving a script message. Wrap the behavior by creating an interface called ICallback and use setCallback to enable the interface function.
  1. //Objective-c
  2. typedef void (^ICallback)(NSString*, NSString*);
  3. @interface JsbBridge : NSObject
  4. +(instancetype)sharedInstance;
  5. -(bool)setCallback:(ICallback)cb;
  6. -(bool)callByScript:(NSString*)arg0 arg1:(NSString*)arg1;
  7. -(void)sendToScript:(NSString*)arg0 arg1:(NSString*)arg1;
  8. -(void)sendToScript:(NSString*)arg0;
  9. @end

Basic Usage

Using JavaScript to Trigger Objective-C Callbacks

Assuming the ad interface is set in the native layer, then when the player clicks the button to open the ad, it is logical to trigger ObjC to open the ad.

The code example of the interface to open the ad is as follows:

  1. static ICallback cb = ^void (NSString* _arg0, MSString* _arg1){
  2. //open Ad
  3. }

At this point, register the event that opens the ad first:

  1. JsbBridge* m = [JsbBridge sharedInstance];
  2. [m setCallback:cb];

Perform the open action on the button’s click event in the JavaScript layer script:

  1. import { native } from 'cc'
  2. public static onclick(){
  3. // 'usrName' and 'defaultAdUrl' are both string
  4. native.bridge.sendToNative(usrName, defaultAdUrl);
  5. }

This will send the required information to the ObjC layer through the native.Bridge channel to perform the action of opening the ad.

Using Objective-C to trigger JavaScript Callbacks

Assume that the animation playback operation is recorded in JavaScript. To play this animation in the Objective-C layer, register an event to play the animation.

First, define a function to play the animation:

  1. public void playAnimation(animationName: string, isLoop: boolean){
  2. // Code to play Animation
  3. }

Next, document the method in onNative:

  1. native.bridge.onNative = (animationName: string, isLoop: String | null):void=>{
  2. if(isLoop && isLoop == "true") {
  3. this.playAnimation(animationName, true);
  4. return;
  5. }
  6. this.playAnimation(animationName, false);
  7. return;
  8. }

The ObjC code example is as follows:

  1. JsbBridge* m = [JsbBridge sharedInstance];
  2. [m sendToScript:@"Animation1" arg1:@"true"];

This will call the JavaScript playback operation.

Sample project: simple multi-event calls

Creator provides the native-script-bridge example, which developers can download for reference use as needed.