客户端渠道接入规则
MSDK 客户端整体架构逻辑如下
接口层、Core 层为所有渠道的共用逻辑,均由 MSDK 以组件形式提供,开发者只需按照 MSDK 开放平台接入规则实现新接入的渠道代码即可
一、 渠道命名规则
1.1. Android平台
Android 平台中新增渠道,在工程目录下命名为:
渠道名,其中渠道名为小写英文字母,示例:garena,qq,google
渠道包名(package name)规则:com.tencent.gcloud.msdk.渠道,示例:com.tencent.gcloud.msdk.garena
1.2. iOS平台
iOS 平台中新增渠道,在工程目录下命名为:MSDK + 渠道,其中渠道名区分大小写
示例:MSDKGarena,MSDKQQ,MSDKGameCenter
二、 版本号规则
版本号分为两个:字符串版本号和数字版本号
2.1 字符串版本号,从前到后分为四段:
大版本号,固定为 5
特性版本号,需要跟 MSDK Core 版本号一致
插件版本号,长度为 3 位,逻辑变更时递增
Build 版本号,可以取 SVN 或 GIT 版本标记
示例:"5.0.010.123"
2.2 数字类型版本号
取字符串版本号的前三个字段
示例:当字符串版本号为 "5.0.010.123" 时,数字版本号为 50010
2.3 查看方法:
Android 平台
Android 编译插件 jar 包中,BuildConfig 文件内容,示例:
package com.tencent.gcloud.msdk.garena;
public final class BuildConfig{
// 数字类型版本号
public static final int VERSION_CODE = 50010;
// 字符串版本号
public static final String VERSION_NAME = "5.0.010.123";
}
iOS 平台
iOS 以宏定义的方式放到头文件中,示例:
// 字符串版本号
#define MSDKGarena_Version_String "5.0.010.2280"
// 数字类型版本号
#define MSDKGarena_Version_Int 50010
三、 代码开发规则
3.1 单例模式
MSDK 插件均为单例模式
Android 平台中,单例模式由 MSDK Core 包支持,不需要插件处理
iOS 平台中,单例模式需要由插件完成
需要注意:
Android 平台中,构造器只会调用一次
iOS 平台中,单例的实现方式包括两种:通过 MSDK 提供的单例宏进行定义,在类的 interface 中添加 SYNTHESIZE_SINGLETON_FOR_CLASS_HEADER(类名),并在类的 implementation 中添加 SYNTHESIZE_SINGLETON_FOR_CLASS(类名)
如果渠道插件需要在初始化时进行一些处理,可以参考 MSDKPushXG 的方式,可以在保证单例的情况下进行一些初始化操作
3.2 生命周期处理
MSDK 提供了统一生命周期处理机制,建议插件中的生命周期按 MSDK 的通用规则来处理,实现方法:
Android 平台 创建渠道名(区分大小写)+ LifeCycleObserver 类,该类实现 ILifeCycle 接口,以处理应用的生命周期
需要在 MSDKConfig.ini 配置文件中,添加渠道名(区分大小写,以逗号隔开)在 MSDK_LIFECYCLE_OBSERVERS 配置项,使得应用启动时就监控该渠道的生命周期
iOS 平台
在 MSDKApplicationDelegate 中,业务可自主在系统监听函数中实现需要的功能
3.2.1 Android LifeCycleObserver 类
LifeCycleObserver 类常用于渠道 SDK 需要处理生命周期的情况,为可选实现
包名规则:固定为 com.tencent.gcloud.msdk
类名规则:渠道名(区分大小写) + LifeCycleObserver,如:GarenaLifeCycleObserver
必须实现 ILifeCycle 接口
参见其他渠道的开源代码:客户端开源代码示例
3.2.2 iOS MSDKApplicationDelegate 类扩展
MSDKApplicationDelegate 类扩展常用于渠道 SDK 需要处理生命周期的情况,为可选实现
文件名规则:MSDKApplicationDelegate + 渠道,如 MSDKApplicationDelegate+Garena.mm
类名规则:MSDKApplicationDelegate (渠道),如:MSDKApplicationDelegate (Garena)
支持的生命周期处理函数列表:
生命周期定义
监控的系统生命周期
APPLICATION_DIDFINISHLAUNCHINGWITHOPTIONS
application:didFinishLaunchingWithOptions:
APPLICATION_OPENURL_SOURCEAPPLICATION_ANNOTATION
application:openURL:sourceApplication:annotation:
APPLICATION_OPENURL_OPTIONS
application:openURL:options:
APPLICATION_DEVICE_TOKEN
application:didRegisterForRemoteNotificationsWithDeviceToken:
APPLICATION_FAIL_DEVICE_TOKEN
application:didFailToRegisterForRemoteNotificationsWithError:
APPLICATION_NOTIFICATION
application:didReceiveRemoteNotification:
APPLICATION_NOTIFICATION_HANDLE
application:didReceiveRemoteNotification:fetchCompletionHandler:
APPLICATION_LOCAL_NOTIFICATION
application:didReceiveLocalNotification:
APPLICATION_CONTINUEUSERACTIVITY
application:continueUserActivity:restorationHandler
参见其他渠道的开源代码:客户端开源代码示例
3.3 插件版本号上报
接入 MSDK 的插件,建议都上报对应的插件版本号,可用于版本监控及统计。MSDK 已经提供了版本上报的函数接口,在插件中仅需调用对应的方法即可
Android 平台
/* MSDK 插件上报函数
* 建议每个插件都通过 MSDK 上报接口进行插件信息上报
* - pluginVer 插件版本号,建议从 BuildConfig 中获取,规则请参考插件 build.gradle 文件中版本号定义说明
* - sdkName 插件名称,一般为渠道名称,如:Garena
* - sdkVer 渠道 SDK 版本,一般从渠道 SDK 中获取,如:GGPlatform.GGGetSDKVersion()。如无法获取,可以为空
* - seqID 为调用序列 ID,直接返回函数传入的 ID 即可,如无法获取,可以为空
* - extra 为扩展信息,可以传入自定义的 JSON 结构字符串,如不需要,可以为空
*/
IT.reportPlugin(BuildConfig.VERSION_NAME, "Garena",GGPlatform.GGGetSDKVersion(), seqID, "{}");
iOS 平台
/** MSDK 插件上报函数
* 建议每个插件都通过 MSDK 上报接口进行插件信息上报
* 函数为宏定义模式实现,原型:
* - REPORT_PLUGIN(pluginName, pluginVer, sdkName, sdkVer, seqID, extraJson)
* - pluginName 插件名称,一般为 MSDK + 渠道,如:MSDKGarena
* - pluginVer 插件版本号字符串
* - sdkName 插件名称,一般为渠道名称,如:Garena
* - sdkVer 渠道 SDK 版本,一般从渠道 SDK 中获取,如:GG::GGPlatform::GetInstance()->GGGetSDKVersion()。如无法获取,可以为空
* - seqID 为调用序列 ID,直接返回函数传入的 ID 即可,如无法获取,可以为空
* - extraJson 为扩展信息,可以传入自定义的 JSON 结构字符串,如不需要,可以为空
*/
REPORT_PLUGIN("MSDKGarena", MSDKGarena_Version_String ,"Garena",
GG::GGPlatform::GetInstance()->GGGetSDKVersion().c_str(),"", "{}");
3.4 回调说明
大多数插件的接口在处理完成后,需要将插件处理结果回调给 MSDK Core 对数据进行进一步处理,比如登录成功后,需要将登录结果交给 MSDK Core,MSDK Core 将发生请求到服务器进行登录鉴权。回调的参数包括:ObserverID、MethodID、seqID
相关字段说明:
字段
说明
使用
ObserverID
观察者 ID,用于不同的回调处理
在渠道代码的回调中,需要传回 ObserverID 到 MSDK Core 以回调给对应 listener
MethodID
方法名 ID,每一个方法对应不同的 methodID,MSDK Core 会根据 methodID 做不同处理
在渠道代码中可判断 methodID 做不同处理,如通过 methodID 判断要调用的功能是后台支持还是插件支持;渠道代码的回调中传回的结构体数据也需要传回对应的 methodID 以区分当前调用的方法;在必要的日志中可打印 methodID 以方便问题的定位和日志查询
seqID
每一次方法调用的序列号,MSDK Core 中根据调用时间随机生成
在渠道代码的回调中传回 seqID 方便追踪当前的调用记录;在必要的日志和插件上报中打印 seqID,方便问题的定位和日志查询
3.4.1 观察者 ID : ObserverID
每个 ObserverID 对应一个 MSDK Core 中的处理方法,这些处理方法在插件回调后,用于对插件处理结果进行进一步处理。
说明:
可能存在一个方法对应多个 ObserverID(如 Android Login 方法正确回调 MSDK_LOGIN_OBSERVER_LOGIN_PLUGIN,错误回调 MSDK_LOGIN_OBSERVER_LOGIN_RET)
也可能多个方法对应一个 ObserverID(如 Android Friend 模块的 share 和 sendMessage 都对应 MSDK_FRIEND_OBSERVER_DELIVER_MESSAGE),具体情况请参考具体的模块开发文档
3.4.2 方法ID - MethodID
通常情况下每个方法都有一个 MethodID,同样的 ObserverID,但 MethodID 不同的话,对应的处理逻辑也不相同。
注意: 登录模块的 Login 方法的 MethodID 会存在多个,因此在进行回调时,插件开发者尽量选择方法中传递进来的 MethodID 进行回调,可以保证回调正确
[info] 特殊情况
部分功能,插件需要主动回调结果给 MSDK Core,比如推送模块收到推送消息后,需要主动回调给 MSDK Core
3.4.3 返回结构体 - Ret
返回结构体用于保存插件的处理结果,其中包括的字段:
methodNameID 即 MethodID,MSDK 定义的函数 ID,用于回调方法定义
retCode MSDK 错误码,常见错误码定义可以在 MSDKErrorCode 类或 assets/MSDKRetMsg.json 错误信息配置文件中找到中找到。常用错误码使用说明:SUCCESS 成功返回
CANCEL 操作被取消,建议渠道操作取消时,返回该值
THIRD 渠道错误,在渠道操作失败时返回,此时 thirdCode 必须赋值
retMsg MSDK 错误信息,根据情况进行填写即可
thirdCode 渠道错误码,根据渠道错误码定义进行返回
thirdMsg 渠道错误信息,跟进渠道错误信息填写即可
extraJson 扩展信息,插件可以用来传递自定义参数,为 JSON 字符串
3.4.4 回调函数说明
Android 平台
使用统一的回调处理方法 IT.onPluginRetCallback
函数原型:
public static native void onPluginRetCallback(int observerID, MSDKRet ret, String seqID);
observerID 回调函数 ID
ret 返回结构,必须是 MSDKRet 的子类
seqID 为调用序列 ID,直接返回函数传入的序列 ID 即可
iOS 平台
统一的回调处理方法 MSDKInnerObserverHolder::CommitToTaskQueue,其中泛型参数 T 需要与返回结构 ret 的类型 RetType 相同
函数原型:
static void CommitToTaskQueue(const RetType &ret, const unsigned int observerID, const String &seqID)
ret 返回结构
observerID 回调函数 ID
seqID 为调用序列 ID,直接返回函数传入的序列 ID 即可
四、 渠道插件打包规则
4.1 Android 平台
建议打包 release 版本 aar,解压 aar 后按整理成 ADT 工程目录结构打包到游戏
文件夹及 jar 包命名规则统一为:msdk-渠道,如:msdk-garena
注意整理 AndroidManifest.xml、res 目录下文件内容
4.2 iOS 平台
[info] 打包环境
iOS Framework 打包版本必须为 C11,否则可能存在跨库问题
打包与插件同名 framework 即可,并公开对应插件功能头文件即可,示例: