說明
Cocos Creator 項目發佈到IOS中用到。
環境:MAC電腦, xCode11,CocosCreator2.3.1。
首先,cocos creator 文檔介紹:https://docs.cocos.com/creator/manual/zh/advanced-topics/oc-reflection.html
看完文檔後,進入實際操作步驟:
這裏先看 object-c 如何調用 js/ts
1.新建類CallJS的頭文件:CallJS.h
xcode 中新建 .h 文件 (文件名隨意)。這裏命名:CallJS.h
定義與 js/ts 交互的函數名字。
代碼如下:
#import <UIKit/UIKit.h>
@interface CallJS : NSObject
{
}
/*
object-c 調用 cocos creator 固定節點綁定的固定(js/ts)腳本的固定函數,並且該函數有個1個參數。
固定(js/ts)腳本:(object-c中寫死的腳本名字,cocose creator 中必須要有此腳本,並且掛在了 object-c 中寫死的節點名字上)。
固定函數:(object-c中寫死的函數名。此函數必須在固定腳本中存在,並且名字相同,參數個數與類型都必須相同)。
**/
+(void)callJsCCNodeFunc_1:(NSString*) cmdStr;
/**
object-c 調用 cocos creator 固定節點綁定的固定(js/ts)腳本的 funcNameStr函數(funcNameStr:代表函數名字符串),並且該函數有個2個參數。
固定(js/ts)腳本:(object-c中寫死的腳本名字,cocose creator 中必須要有此腳本,並且掛在了 object-c 中寫死的節點名字上)。
固定函數:(object-c中寫死的函數名。此函數必須在固定腳本中存在,並且名字相同,參數個數與類型都必須相同)。
*/
+(void)callJsCCNodeFunc_3:(NSString*) funcNameStr withCmd:(NSString*) cmdStr withContent:(NSString*) contentStr;
/**
object-c 調用 cocos creator 中(js/ts)腳本中的全局的funcNameStr函數(funcNameStr:代表函數名字符串),並且該函數有個0個參數。
*/
+(void)callJsGlobalFunc_1:(NSString*) funcNameStr;
/**
object-c 調用 cocos creator 中(js/ts)腳本中的全局的funcNameStr函數(funcNameStr:代表函數名字符串),並且該函數有個1個參數。
*/
+(void)callJsGlobalFunc_2:(NSString*) funcNameStr withCmd:(NSString*) cmdStr;
/**
object-c 調用 cocos creator 中(js/ts)腳本中的全局的funcNameStr函數(funcNameStr:代表函數名字符串),並且該函數有個2個參數。
*/
+(void)callJsGlobalFunc_3:(NSString*) funcNameStr withCmd:(NSString*) cmdStr withContent:(NSString*) contentStr;
@end
2.實現類CallJS的文件:CallJS.mm
新建文件 CallJS.m (注意-->>新建文件後,在xcode中將文件名改名爲 CallJS.mm 至於爲什麼要將 .m 文件改名爲 .mm 文件,可以去百度下這兩種文件的區別,我是個小白,無法解釋太多。)實現 CallJS.h 中到函數。
實現與js/ts交換的函數。
代碼如下:
#import <Foundation/Foundation.h>
#import "cocos2d.h"
#import "CallJS.h"
// 這個.h文件必須導入,否則報錯。
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"
//using namespace std;
@implementation CallJS
+(void)callJsCCNodeFunc_1:(NSString*) cmdStr{
NSLog(@"-------callJsCCNodeFunc_1...");
std::string param001 = [cmdStr UTF8String];
// "cc.find('AppMain').getComponent('IOSCtrl').GetAward(\"%s\");", param001.c_str()
// 可以理解爲:調用 cc.find() 函數在場景中查找 AppMain 節點,在利用 getComponent() 函數獲取該節點下 名爲 IOSCtrl.ts 的腳本。最後調用 腳本中的成員函數 GetAward(),此函數有一個參數。
std::string jsCallStr = cocos2d::StringUtils::format("cc.find('AppMain').getComponent('IOSCtrl').GetAward(\"%s\");", param001.c_str());
NSLog(@"--------- jsCallStr = %s", jsCallStr.c_str());
se::ScriptEngine::getInstance()->evalString(jsCallStr.c_str());
}
+(void)callJsCCNodeFunc_3:(NSString*) funcNameStr withCmd:(NSString*) cmdStr withContent:(NSString*) contentStr{
NSLog(@"-------callJsCCNodeFunc_3...");
std::string funcName = [funcNameStr UTF8String];
std::string param001 = [cmdStr UTF8String];
std::string param002 = [contentStr UTF8String];
std::string jsCallStr = cocos2d::StringUtils::format("cc.find('AppMain').getComponent('IOSCtrl').%s(\"%s\",\"%s\");", funcName.c_str(),param001.c_str(),param002.c_str());
NSLog(@"--------- jsCallStr = %s", jsCallStr.c_str());
se::ScriptEngine::getInstance()->evalString(jsCallStr.c_str());
}
+(void)callJsGlobalFunc_1:(NSString*) funcNameStr{
NSLog(@"-------callJsGlobalFunc_1...");
std::string funcName = [funcNameStr UTF8String];
std::string jsCallStr = cocos2d::StringUtils::format("%s();",funcName.c_str());
NSLog(@"--------- jsCallStr = %s", jsCallStr.c_str());
se::ScriptEngine::getInstance()->evalString(jsCallStr.c_str());
}
+(void)callJsGlobalFunc_2:(NSString*) funcNameStr withCmd:(NSString*) cmdStr{
NSLog(@"-------callJsGlobalFunc_2...");
std::string funcName = [funcNameStr UTF8String];
std::string param001 = [cmdStr UTF8String];
std::string jsCallStr = cocos2d::StringUtils::format("%s(\"%s\");",funcName.c_str(), param001.c_str());
NSLog(@"--------- jsCallStr = %s", jsCallStr.c_str());
se::ScriptEngine::getInstance()->evalString(jsCallStr.c_str());
}
+(void)callJsGlobalFunc_3:(NSString*) funcNameStr withCmd:(NSString*) cmdStr withContent:(NSString*) contentStr{
NSLog(@"-------callJsGlobalFunc_3...");
std::string funcName = [funcNameStr UTF8String];
std::string param001 = [cmdStr UTF8String];
std::string param002 = [contentStr UTF8String];
std::string jsCallStr = cocos2d::StringUtils::format("%s(\"%s\",\"%s\");",funcName.c_str(), param001.c_str(),param002.c_str());
NSLog(@"--------- jsCallStr = %s", jsCallStr.c_str());
// ScriptingCore::getInstance()->evalString(jsCallStr.c_str());
se::ScriptEngine::getInstance()->evalString(jsCallStr.c_str());
}
@end
3.實現TS腳本:IOSCtrl.ts
到這裏了,看下我的Cocos Creator 中的 ts 代碼吧!腳本名字:IOSCtrl.ts
在這裏我們定義了與 object-c 交互的函數。
代碼如下:
const { ccclass, property } = cc._decorator;
/**
* 這裏是一個全局函數,函數名爲 GetBigAward ,帶有一個參數。
* 可供 object-c 調用 js/ts 用。
*/
window["GetBigAward"] = function(code:string){
console.error("------ object-c 調用 js 全局函數,參數 code = ",code);
}
/**
* 與 Ios object-c 交互
* 此腳本 綁定在 遊戲中景中 AppMain 節點下,可以通過 cc.find('AppMain');語句找到此節點。
*/
@ccclass
export class IOSCtrl extends cc.Component {
onLoad(){
console.log("------ IOSCtrl onLoad");
// this.AddListener();
}
onDestroy(){
// this.RemoveListener();
}
// private AddListener(){
// Messenger.AddListener(MsgEvent.CSJSDK_IOS_LookVideo,this.LookVideo,this);
// Messenger.AddListener(MsgEvent.CSJSDK_IOS_ShowBanner,this.ShowBanner,this);
// Messenger.AddListener(MsgEvent.CSJSDK_IOS_HideBanner,this.HideBanner,this);
// }
// private RemoveListener(){
// Messenger.RemoveListener(MsgEvent.CSJSDK_IOS_LookVideo,this.LookVideo,this);
// Messenger.RemoveListener(MsgEvent.CSJSDK_IOS_ShowBanner,this.ShowBanner,this);
// Messenger.RemoveListener(MsgEvent.CSJSDK_IOS_HideBanner,this.HideBanner,this);
// }
/**
* js/ts 調用 object-c 用。
*/
private LookVideo():void{
if ('jsb' in window) {
if (cc.sys.os == cc.sys.OS_IOS) {
console.error("------- js 調用 object-c 去 看視頻 ");
// js 調用 object-c 中 AppController 類中的 靜態函數 csjAdRewardOpen ,帶有一個參數。
// 注意 函數名必須帶上 ":" ,否則無法找到 函數。 如 "csjAdRewardOpen:"
jsb.reflection.callStaticMethod("AppController", "csjAdRewardOpen:","參數1");
// 如果在 object-c 把函數定義成這個樣子:+ (void)csjAdRewardOpen:(NSString *)code withcmd:(NSString *)code2;
// 那麼調用時函數名必須寫成 "csjAdRewardOpen:withcmd:"
// jsb.reflection.callStaticMethod("AppController", "csjAdRewardOpen:withcmd:","參數1","參數2");
}
}
}
/**
* js/ts 調用 object-c 用。
*/
private ShowBanner():void{
if ('jsb' in window) {
if (cc.sys.os == cc.sys.OS_IOS) {
console.error("------- js 調用 object-c 去 csjAdShowBanner ");
jsb.reflection.callStaticMethod("AppController", "csjAdShowBanner:","2222");
}
}
}
/**
* js/ts 調用 object-c 用。
*/
protected HideBanner():void{
if ('jsb' in window) {
if (cc.sys.os == cc.sys.OS_IOS) {
console.error("------- js 調用 object-c 去 csjAdHideBanner ");
jsb.reflection.callStaticMethod("AppController", "csjAdHideBanner:","3333");
}
}
}
/**
* 可供 object-c 調用 js/ts 用。
*/
public GetAward(code:string){
console.error("------ object-c 調用了 js 返回了視屏獎勵,code =",code)
// let mon = Platform.instance.platformHadler as CSJSDKPlatform;
// if(mon){
// CSJSDKPlatform.IOSGetRewardVideo();
// }
}
/**
* 可供 object-c 調用 js/ts 用。
* @param code
* @param code2
*/
public GetAward2(code:string,code2:string){
console.error("------ object-c 調用了 js 返回了視屏獎勵,code =",code,",code2 = ",code2)
// let mon = Platform.instance.platformHadler as CSJSDKPlatform;
// if(mon){
// CSJSDKPlatform.IOSGetRewardVideo();
// }
}
}
4.Object-C 如何調用 js/ts 。
最後 Object-C 如何調用 js/ts 。
在 xCode 某個腳本中,定義並實現 testCallJs 函數。(例如可以在 AppController 腳本中,腳本中導入 CallJS.h 頭文件 纔可以調用 CallJS 中的函數)。
#import "CallJS.h"
- (void)testCallJs{
// 調用 js/ts 腳本中的函數: AppMain 節點下 IOSCtrl 腳本中的 GetAward 的函數。
[CallJS callJsCCNodeFunc_1:@"第1個參數!"];
// 調用 js/ts 腳本中的函數: AppMain 節點下 IOSCtrl 腳本中的 GetAward2 的函數。
[CallJS callJsCCNodeFunc_3:@"GetAward2" withCmd:@"第1個參數!" withContent:@"第2個參數!"];
// 調用 js/ts 的全局函數:GetBigAward
[CallJS callJsGlobalFunc_2:@"GetBigAward" withCmd:@"第1個參數!"];
}
再看 js/ts 如何調用 object-c
1.在object-c中實現供ts調用的函數。
在xcode 編輯器中。找到 AppController.h , AppController.m 腳本,分別添加一個靜態函數(必須是靜態函數)聲名與定義。在這裏添加函數工 js/ts 調用。
代碼如下:
AppController.h 中添加靜態函數聲明:
// 靜態函數聲明
+ (void)csjAdRewardOpen:(NSString *)code;
// 靜態函數聲明
+ (void)csjAdShowBanner:(NSString *)code;
// 靜態函數聲明
+ (void)csjAdHideBanner:(NSString *)code;
AppController.m 中添加靜態函數實現:
+ (void)csjAdRewardOpen:(NSString *)code{
NSLog(@"-------------------靜態函數實現");
}
+ (void)csjAdShowBanner:(NSString *)code{
NSLog(@"-------------------靜態函數實現");
}
+ (void)csjAdHideBanner:(NSString *)code{
NSLog(@"-------------------靜態函數實現");
}
2. 在js/ts調用object-c函數。
其實在上面代碼 IOSCtrl.ts 腳本中已經給出。這裏就複製一份代碼吧。
/**
* js/ts 調用 object-c 用。
*/
private LookVideo():void{
if ('jsb' in window) {
if (cc.sys.os == cc.sys.OS_IOS) {
console.error("------- js 調用 object-c 去 幹事 ");
// js 調用 object-c 中 AppController 類中的 靜態函數 csjAdRewardOpen ,帶有一個參數。
// 注意 函數名必須帶上 ":" ,否則無法找到 函數。 如 "csjAdRewardOpen:"
jsb.reflection.callStaticMethod("AppController", "csjAdRewardOpen:","參數1");
// 如果在 object-c 把函數定義成這個樣子:+ (void)csjAdRewardOpen:(NSString *)code withcmd:(NSString *)code2;
// 那麼調用時函數名必須寫成 "csjAdRewardOpen:withcmd:"
// jsb.reflection.callStaticMethod("AppController", "csjAdRewardOpen:withcmd:","參數1","參數2");
}
}
}
結束
有關 cocos creator js/ts 與 object-c 的交互就寫完了。
如有不懂,仔細閱讀 cocos creator 文檔。https://docs.cocos.com/creator/manual/zh/advanced-topics/oc-reflection.html