由于项目需求,需要开发一款功能性的SDK与Unity进行交互,开发SDK已经轻车熟路了,下面记录一下和Unity交互的经验。
首先Unity开发完成后会导出一个Xcode项目,此时要注意确保导出的Xcode项目可以正常运行。然后将开发好的SDK导入到Xcode项目中。由于Unity不能直接调iOS的API,此时需要一个桥接文件来连接iOS和Unity,进行跨语言交互。那么桥接文件应该如何制作呢?
1、在Unity导出的Xcode项目中创建“XXXAgent”桥接文件,注意实现类的后缀为".mm"
2、在.h中暴露初始化函数
@interface TestSDKAgent : NSObject
+ (void)initTestSDK;
@end
3、在.mm文件中进行实现
@implementation TestSDKAgent
+ (NSString *)dictionaryTurnJsonString:(NSDictionary *)dicJson {
if (![dicJson isKindOfClass:[NSDictionary class]] || ![NSJSONSerialization isValidJSONObject:dicJson]) {
return nil;
}
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dicJson options:0 error:nil];
NSString *strJson = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
return strJson;
}
+ (void)initTestSDK{
//1、在这里初始化提供的SDK
[[XXXSDKManger sharedManager] initSDK];
//2、如果需要SDK走服务器获取结果时,可定义一个actiontype,SDK拿到结果后可使用Block发送消息给Unity,这里的“ config”是个Json字符串,通过服务器拿到结果后转Json字符串获得,Unity方收到消息进行解析即可拿到服务器返回的结果
XXXSDKManger *sdk = [XXXSDKManger sharedManager];
[sdk setConfigBlock:^(NSString * _Nonnull config) {
[TestSDKAgent sendMessage:config];
}];
}
+ (void)sendMessage:(NSString *)msg {
char* cMsg = (char*)malloc(strlen(msg.UTF8String) + 1);
strcpy(cMsg, msg.UTF8String);
//此方法中的入参需与Unity方协商定义好
[[self class] sendMessageToGOWithName:"XSSdkCallback" functionName:"callback" message:cMsg];
}
+ (void)sendMessageToGOWithName:(const char*)goName functionName:(const char*)name message:(const char*)msg {
NSLog(@"---goName---%s\n---name--%s\n--msg--%s", goName, name, msg);
UnitySendMessage(goName, name, msg);
}
@end
4、定义Unity调用的接口
这里主要是定义C语言的接口函数,Unity通过调取C语言函数,然后C函数调取OC函数来实现交互的。注意的是不管是入参还是返回参数均以字符串的形式进行传递。举个例子:
+ (NSString *)dictionaryTurnJsonString:(NSDictionary *)dicJson {
if (![dicJson isKindOfClass:[NSDictionary class]] || ![NSJSONSerialization isValidJSONObject:dicJson]) {
return nil;
}
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dicJson options:0 error:nil];
NSString *strJson = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
return strJson;
}
+ (void)initTestSDK{
//1、在这里初始化提供的SDK
//2、如果需要SDK走服务器获取结果时,可定义一个actiontype,SDK拿到结果后可使用Block发送消息给Unity
}
+ (void)sendMessage:(NSString *)msg {
char* cMsg = (char*)malloc(strlen(msg.UTF8String) + 1);
strcpy(cMsg, msg.UTF8String);
//此方法中的入参需与Unity方协商定义好
[[self class] sendMessageToGOWithName:"XSSdkCallback" functionName:"callback" message:cMsg];
}
+ (void)sendMessageToGOWithName:(const char*)goName functionName:(const char*)name message:(const char*)msg {
NSLog(@"---goName---%s\n---name--%s\n--msg--%s", goName, name, msg);
UnitySendMessage(goName, name, msg);
}
@end
// Unity调用OC
#ifdef __cplusplus
extern "C" {
#endif
//返回值为bool类型的,Unity调用此函数,此函数可调用SDK的函数,直接返回对应的BOOL值
bool isBusiOpen(void) {
return 1;
}
//无返回值,带入参的
void onEvent(const char * eventId, const char * jsonData){
[[XXXSDKManger sharedManager] onEvent:[NSString stringWithUTF8String:eventId] andJsonData:[NSString stringWithUTF8String:jsonData]];
}
//返回值为int型的
int getSUCCCount(void) {
return [[XXXSDKManger sharedManager] getIntNunber];
}
//返回值为字符串类型的,这里注意的是不能直接进行字符串OC转C的操作,这样程序运行后,调用此函数时会闪退,此处应该使用“<string.h>”库里的“ strdup()”函数进行分配空间后再返回给Unity即可
const char * getAccountBalance(void) {
return strdup([[XXXSDKManger sharedManager] getString].UTF8String);
}
#ifdef __cplusplus
}
#endif
此处基本算是可以了,能满足日常的开发需求,总之能直接返回的就通过定义函数直接返回所需的对应类型的数值或字符串;不能直接返回的,需要SDK走网络请求拿到结果处理后返回的,就通过Blokc的形式给Unity发送消息,Unity通过前面定义好的actiontype,收到消息后进行解析后展示UI。
网友评论