[Cocos2d-js] JavaScriptからObjective-Cのメソッドを呼び出す方法

By | 2018年1月4日

Cocos2d-jsでiOSアプリを作成した際は JavaScript から Objective-C のメソッドを呼び出すことができます。

今回は AppController.mm に定義した Objective-C のメソッドを JavaScript 側から呼び出す簡単なサンプルプログラムを紹介します。

以下の動作確認を行った Cocos2d-x のバージョンは 3.16 です。

手順

Cocos2d-x で使用言語を JavaScript に設定して新規プロジェクトを作成した場合を例に手順を紹介します。

以下のように Call_CPP_Test という名前でプロジェクトを作ったとします。

Cocos2d-xでJavaScriptを使用言語に設定

(C++ ではなく Objective-C のメソッドを呼び出すので CPP ではなく OBJC にするべきでした...)

Objective-C側の設定

まず、呼び出されるメソッドを実装するクラスのヘッダーファイルにメソッドの定義を書きます。

今回は AppController.mm に呼び出されるメソッドを定義するので AppController.h にそのメソッドの定義を書きます。

以下のディレクトリにある AppController.h を開いて下さい。

/frameworks/runtime-src/proj.ios_mac/ios/

そして、以下のメソッド定義(test)を追記して下さい。

#import <UIKit/UIKit.h>

@class RootViewController;

@interface AppController : NSObject <UIApplicationDelegate> {

}

@property(nonatomic, readonly) RootViewController* viewController;

// これを追記
+ (void)test;

@end

次に、同じディレクトリにある AppController.mm の中(クラス AppController の内部)に、実際のメソッドの中身を書きます。

...(略)...

static AppDelegate s_sharedApplication;

// メソッドの定義
+ (void)test {
    NSLog(@"%s", "JavaScriptから呼び出された!");
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    cocos2d::Application *app = cocos2d::Application::getInstance();

...(略)...

以上で、呼び出されるメソッドの設定は完了です。

JavaScript側の設定

上記のように設定したメソッドを呼び出すための JavaScript のコードを書きます。

プロジェクト作成時に作られた app.js を開き、以下のコードを ctor の中に追記して下さい。

ctor の中身はそのままでも構いませんが、この記事では簡略化のため this._super(); 以外を全て消去しています。

実際のコードの中身は次のようになります。

var HelloWorldLayer = cc.Layer.extend({
    ctor:function () {
        
        this._super();

        // AppController に定義された test という名前のメソッドを呼び出す
        jsb.reflection.callStaticMethod("AppController", "test");
    }
});

var HelloWorldScene = cc.Scene.extend({
    onEnter:function () {
        this._super();
        var layer = new HelloWorldLayer();
        this.addChild(layer);
    }
});

Objective-Cに定義されたメソッドを呼び出すために使用するjsbのメソッドは以下の通りです。

jsb.reflection.callStaticMethod(クラス名, メソッド名, 渡す値...);

引数があるメソッドを呼び出す場合は、第3引数から渡す値を設定します。上記の例で呼び出している test というメソッドには引数を設定しないので、第2引数まで指定しています。

実行例

以上の設定を行った後、iOSアプリとして起動するとXcodeのコンソールに以下のように表示され、正しくメソッドが呼び出せていることが確認できます。

JavaScriptからObjective-cのメソッドを呼び出した例

引数が複数個あるメソッドを呼び出す場合

2つの数値を引数として受け取るメソッドを呼び出す例は以下のようになります。

AppController.h

#import <UIKit/UIKit.h>

@class RootViewController;

@interface AppController : NSObject <UIApplicationDelegate> {

}

@property(nonatomic, readonly) RootViewController* viewController;

+ (void) test:(NSNumber *)num number2:(NSNumber *)num2;

@end

Objective-C側では、数値の型を NSNumber とします。数値の型を int などにしてしまうと、おかしな値が表示されます。

AppController.mm

...(略)...

static AppDelegate s_sharedApplication;

+ (void)test:(NSNumber *)num number2:(NSNumber *)num2 {
    NSLog(@"%s : %@", "JavaScriptから呼び出された!", num);
    NSLog(@"%@", num2);
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    cocos2d::Application *app = cocos2d::Application::getInstance();

...(略)...

第2引数の名前(number2)はJavaScriptから呼び出すために必要になります。

app.js

var HelloWorldLayer = cc.Layer.extend({
    ctor:function () {
        
        this._super();

        jsb.reflection.callStaticMethod("AppController", "test:number2:", 123, 45);
    }
});

var HelloWorldScene = cc.Scene.extend({
    onEnter:function () {
        this._super();
        var layer = new HelloWorldLayer();
        this.addChild(layer);
    }
});

第2引数を、呼び出したいメソッドの形式に対応するように書き換える必要があります。第3引数以降に渡したい数値を書きます。

結果

2つの引数が受け取れていることが確認できます。

複数の引数を受け取るネイティブメソッドを呼び出す例

以上がJavaScriptからObjective-Cのメソッドを呼び出す基本的な手順です。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です