在上一篇《TypeSDK安卓平臺統(tǒng)一化接口結構及思路》中我們闡述了安卓平臺的接口結構和思路。在這里我們將闡述iOS平臺下的接口結構和思路。
ios平臺主要是基于Objective-C的語言,總體的設計思路和安卓類似,具體實現的細節(jié)和接口的結構會有細微的不同。
在ios平臺,我們會涉及到部分的c語法以及oc和c的混編,相對安卓需要注意點會多一點。
那好,接下來我們來具體的闡述一下接口的結構,以及設計的思路。
和安卓一樣,我們先來看看需要考慮的幾點需求。
一、相關的需求
iOS平臺的統(tǒng)一化接口,我們需要考慮到具體以下的幾點:
1.對外需要有統(tǒng)一的接口,保證不同的渠道sdk 對同一個游戲來說,是調用相同的接口,傳遞相同的參數
2.對內需要有一套擴展性很好的框架,可以應對不同渠道的sdk差異性
二、設計的模塊
那么針對這些考慮點,安卓平臺的統(tǒng)一化接口,我們將主要分成以下幾個部分來設計:
1.基礎架構設計
2.具體渠道實現類
3.統(tǒng)一化對外平臺接口
4.跨平臺交互的設計
三、具體的細節(jié)
我們主要實現了這么一套結構
1.我們創(chuàng)建通用的基礎抽象類(BaseBonjour)。
基于oc的特性,我們對基礎類添加了2個protocol,一個是必須實現的基礎接口,一個是可以不去實現的拓展接口的申明
1.1 必須實現的基礎接口,我們做如下的定義
1.1.1 初始化接口 @required -(void)InitSDK:(NSString*)_in_data;
1.1.2 登錄接口 @required -(void)ShowLogin:(NSString*)_in_data;
1.1.3 登出接口 @required -(void)ShowLogout;
1.1.4 支付接口@required -(NSString*)PayItem:(NSString*)_in_data;
1.1.5 顯示分享接口@required -(void)ShowShare:(NSString*)_in_data;
1.2 非必需實現的拓展接口
1.2.1 獲取緩存在ios層的用戶信息 @optional -(NSString*)GetUserData;
1.2.2 獲取本地渠道的配置 @optional -(NSString*)GetPlatformData;
1.2.3 根據函數名,調用具體實現類中的函數@optional -(NSString*)DoAnyFunction:(NSString*)_funcName withArgs:(NSString*)_json_string;
1.2.4 大退游戲(殺進程) @optional -(void)ExitGame;
1.2.4 提交玩家數據 -(void)SetPlayerInfo:(NSString*)_in_data;
2.我們根據每一個渠道的sdk不同,單獨創(chuàng)建每個渠道自己的實現類Bonjour_xx。
2.1 這個類繼承通用的框架基類(BaseBonjour)。
2.2 在該框架下,實現基類所有的必需實現的抽象接口。如果沒有該接口的功能,也需要做出相應的處理,例如輸出log日志。
2.3 同時該類可以增加渠道自有的特殊接口(例如獲取好友列表)
3.發(fā)布平臺有一個統(tǒng)一的給外部調用接口實現的類:TypeSDK
3.1該類作為一個單例類,可以給在任何地方方便的提供接口的調用。
3.2 該類的單利對象是框架基類對象(BaseBonjour)
3.3 該類不是框架基類對象的子類
3.4 通過配置文件,利用類名,創(chuàng)建基類對象的子類,該子類是該渠道的具體實現類,該子類賦值給單利對象
3.5 所有的接口調用,通過獲取TypeSDK類的單利對象來調用
具體的實現,可以參照以下一部分代碼
單例對象
static TypeBaseBonjour* sharedInstance = nil;
獲取單例對象的靜態(tài)函數
@implementation TypeSDK
+(TypeBaseBonjour*)GetIns
{
if(nil == sharedInstance)
{
[self InitBonjourClass];
}
return sharedInstance;
}
@end
具體渠道實現類
@interface TypeBonjour_demo : TypeBaseBonjour
@end
通過類名動態(tài)創(chuàng)建子類對象
Class _cls = NSClassFromString(_type_name);
if(_cls && [_cls isSubclassOfClass:[TypeBaseBonjour class]])
{
NSLog(@"success get bonjour class");
sharedInstance = [[ _cls alloc]init];
NSLog(@"share instance address %p",sharedInstance);
}
這樣 我們就可以讓基礎框架,具體實現,對外調用接口三方的耦合性進一步的降低。這三部分是可以完全各自獨立維護。
4.跨平臺交互部分
跨平臺交互我們需要考慮兩個方面
a.如何將從發(fā)布平臺調用開發(fā)平臺函數
b.如何將從開發(fā)平臺調用發(fā)布平臺函數
4.1.在ios層,我們只需要將需要給到unity調用的函數
ios給unity調用,需要寫c的接口。c和oc混編,需要吧相關的類文件后綴名從.m修改成.mm
提供以下代碼參考
@implementation TypeSDKExtern
@end
#if defined(__cplusplus)
extern "C"
{
#endif
void CallShowLogin ()
{
[[TypeSDK GetIns]ShowLogin:@""];
}
#if defined(__cplusplus)
}
#endif
有關c接口代碼的一個注意點
所有的返回值,需要返回的是常量,所以不能直接把原始oc代碼里的char*返回出去,需要拷貝一份常量返回出去
切記c的代碼不要寫在oc的類申明里面
另有情提供2個非常有用的小函數
#if defined(__cplusplus)
extern "C"{
#endif
//字符串轉化的工具函數
NSString* SDKCreateNSString (const char* string)
{
if (string)
return [NSString stringWithUTF8String: string];
else
return [NSString stringWithUTF8String: ""];
}
char* SDKMakeStringCopy( const char* string)
{
if (NULL == string) {
return NULL;
}
char* res = (char*)malloc(strlen(string)+1);
strcpy(res, string);
return res;
}
#if defined(__cplusplus)
}
#endif
第一個函數是把 char*類型數據轉換成nsstring*
第二個函數是 char*的拷貝函數
在unity中的調用oc層面的c接口舉例
[DllImport("__Internal")]
private static extern void CallShowLogin ();
public void ShowLogin()
{
CallShowLogin();
}
在cocos2dx中調用c接口舉例
extern void CallShowLogin ();
void showLogin()
{
CallShowLogin();
}
4.2.在unity層,提供了我們通用的跨平臺調用接口
extern void UnitySendMessage(const char *, const char *, const char *);
我們只需要知道unity部分用來接收消息的腳本名字,需要執(zhí)行的腳本函數名,以及傳遞的參數,就可以調用unity的響應函數了。
以下給出調用舉例
-(void)SendEvent:(NSString *)_notify_class_name withJson:(NSString *)_json_string
{
UnitySendMessage("TypeSDK" , [_notify_class_name UTF8String], [_json_string UTF8String]);
}
綜上ios向unity平臺傳遞數據和調用函數,主要通過消息機制發(fā)送消息
unity向安ios平臺傳遞參數和調用函數,則是直接調用oc層的c接口。
以上就是我們ios發(fā)布平臺的聚合sdk設計思路細節(jié),下一章我們將講述unity聚合sdk的設計思路細節(jié)。
如果想了解更多,請聯系我們或關注官網
了解更多:www.typesdk.com
問題解答:1771930259
聯系郵箱:qianyuzhou@typesdk.com
項目地址:https://github.com/typesdk
更多建議: