TYPESDK手游聚合SDK客户端设计思路与架构之三:iOS平台统一化接口结构及思路

2018-06-14 16:09 更新

在上一篇《TypeSDK安卓平台统一化接口结构及思路》中我们阐述了安卓平台的接口结构和思路。在这里我们将阐述iOS平台下的接口结构和思路。

       ios平台主要是基于Objective-C的语言,总体的设计思路和安卓类似,具体实现的细节和接口的结构会有细微的不同。

       在ios平台,我们会涉及到部分的c语法以及oc和c的混编,相对安卓需要注意点会多一点。

       那好,接下来我们来具体的阐述一下接口的结构,以及设计的思路。

       和安卓一样,我们先来看看需要考虑的几点需求。

一、相关的需求

       iOS平台的统一化接口,我们需要考虑到具体以下的几点:

       1.对外需要有统一的接口,保证不同的渠道sdk 对同一个游戏来说,是调用相同的接口,传递相同的参数

       2.对内需要有一套扩展性很好的框架,可以应对不同渠道的sdk差异性

二、设计的模块

       那么针对这些考虑点,安卓平台的统一化接口,我们将主要分成以下几个部分来设计:

       1.基础架构设计

       2.具体渠道实现类

       3.统一化对外平台接口

       4.跨平台交互的设计

三、具体的细节


我们主要实现了这么一套结构

1.我们创建通用的基础抽象类(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不同,单独创建每个渠道自己的实现类Bonjour_xx。

       2.1 这个类继承通用的框架基类(BaseBonjour)。

       2.2 在该框架下,实现基类所有的必需实现的抽象接口。如果没有该接口的功能,也需要做出相应的处理,例如输出log日志。

       2.3 同时该类可以增加渠道自有的特殊接口(例如获取好友列表)

3.发布平台有一个统一的给外部调用接口实现的类:TypeSDK

       3.1该类作为一个单例类,可以给在任何地方方便的提供接口的调用。

       3.2 该类的单利对象是框架基类对象(BaseBonjour)

       3.3 该类不是框架基类对象的子类

       3.4 通过配置文件,利用类名,创建基类对象的子类,该子类是该渠道的具体实现类,该子类赋值给单利对象

       3.5 所有的接口调用,通过获取TypeSDK类的单利对象来调用

具体的实现,可以参照以下一部分代码

单例对象

static TypeBaseBonjour* sharedInstance = nil;

获取单例对象的静态函数


@implementation TypeSDK
 
+(TypeBaseBonjour*)GetIns
{
 
    if(nil == sharedInstance)
    {
        [self InitBonjourClass];
    }
    return sharedInstance;
}
@end

具体渠道实现类


@interface TypeBonjour_demo : TypeBaseBonjour
@end

通过类名动态创建子类对象


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.如何将从发布平台调用开发平台函数

              b.如何将从开发平台调用发布平台函数

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部分用来接收消息的脚本名字,需要执行的脚本函数名,以及传递的参数,就可以调用unity的响应函数了。

       以下给出调用举例



-(void)SendEvent:(NSString *)_notify_class_name withJson:(NSString *)_json_string
       {
               UnitySendMessage("TypeSDK" , [_notify_class_name UTF8String], [_json_string UTF8String]);
       }

综上ios向unity平台传递数据和调用函数,主要通过消息机制发送消息

       unity向安ios平台传递参数和调用函数,则是直接调用oc层的c接口。

       以上就是我们ios发布平台的聚合sdk设计思路细节,下一章我们将讲述unity聚合sdk的设计思路细节。


如果想了解更多,请联系我们或关注官网

了解更多:www.typesdk.com

问题解答:1771930259

联系邮箱:qianyuzhou@typesdk.com

项目地址:https://github.com/typesdk


以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号