内嵌动态开发指南
本文介绍如何在游戏中加入 TapTap 内嵌动态。使用内嵌动态功能需依赖 TapTap 登录。由于 TapTap 登录有两种形式,分别为基于内建账户系统登录和单纯登录,所以内嵌动态 SDK 获取以及初始化根据 TapTap 登录集成方式的不同而有区别。
以下先介绍基于内建账户系统登录条件下内嵌动态的集成,如果使用单纯的 TapTap 登录 并接入内嵌动态,初始化和 SDK 获取请参考:单纯的内嵌动态初始化。
环境要求
- Unity
- Android
- iOS
- UE4
- Unity 2019.4 或更高版本
- iOS 11 或更高版本,Xcode 版本 14.1 或更高版本
- Android 5.0(API level 21)或更高版本
Android 5.0(API level 21)或更高版本
iOS 11 或更高版本,Xcode 版本 14.1 或更高版本
- 安装 UE 4.26 及以上版本
- iOS 12 或更高版本
- Android 5.0(API level 21)或更高版本
- macOS 10.14.0 或更高版本
- Windows 7 或更高版本
支持平台:Android / iOS / Windows / macOS
权限说明
- Unity
- Android
- iOS
- UE4
该模块需要如下权限:
权限 | 使用目的 | 权限申请时机 |
---|---|---|
网络权限 | 用于访问网络数据 | 用户首次使用该功能时会申请权限 |
获取网络状态 | 用于检测当前网络连接是否有效 | 用户首次使用该功能时会申请权限 |
读写存储权限 | 用于发布或下载动态页面内图片、视频 | 下载或使用本地图片发布动态时申请 |
该模块将在应用中添加如下权限:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
集成前准备
- 参考 准备工作 创建应用、开启内嵌动态应用配置、绑定 API 域名;
SDK 获取
请先参考 TapTap 登录完成 SDK 获取,然后在此基础上可以通过 下载 获得 TapSDK,添加 TapMoment
模块:
- Unity
- Android
- iOS
- UE4
SDK 可以通过 Unity Package Manager 导入或手动导入,二者任选其一。请根据项目需要选择。
方法一:使用 Unity Package Manager
从 3.29.1 版本开始, SDK 修改 JSON 解析库为 Newtonsoft-json
,如果当前工程已接入该依赖库,则不需额外处理,否则需在 Packages/manifest.json
添加如下依赖:
"com.unity.nuget.newtonsoft-json":"3.2.1"
NPMJS 安装
从 3.25.0 版本开始,TapSDK 支持了 NPMJS 安装,优势是只需要配置版本号,并且支持嵌套依赖。
在项目的 Packages/manifest.json
文件中添加以下依赖:
"dependencies":{
"com.taptap.tds.moment":"3.29.4",
"com.taptap.tds.common":"3.29.4",
}
但需要注意的是,要在 Packages/manifest.json
中 dependencies
同级下声明 scopedRegistries
:
"scopedRegistries": [
{
"name": "NPMJS",
"url": "https://registry.npmjs.org/",
"scopes": ["com.tapsdk", "com.taptap"]
}
]
GitHub 安装
在项目的 Packages/manifest.json
文件中添加以下依赖:
"dependencies":{
"com.taptap.tds.common":"https://github.com/TapTap/TapCommon-Unity.git#3.29.4",
"com.taptap.tds.moment":"https://github.com/TapTap/TapMoment-Unity.git#3.29.4",
}
在 Unity 顶部菜单中选择 Window > Package Manager 可查看已经安装在项目中的包。
方法二:手动导入
在 下载页 找到 TapSDK Unity 下载地址,下载
TapSDK-UnityPackage.zip
。在 Unity 项目中依次转到 Assets > Import Packages > Custom Packages,从解压后的
TapSDK-UnityPackage.zip
中,选择希望在游戏中使用的 TapSDK 包导入,其中:TapTap_Common.unitypackage
TapSDK 基础库,必选。TapTap_Moment.unitypackage
TapTap 内嵌动态库,必选。
如果当前项目已集成
Newtonsoft.Json
依赖,则忽略该步骤,否则在NuGet.org
Newtonsoft.Json 页面中通过点击右侧 「Download package」 下载库文件,并将下载的文件后缀从.nupkg
修改为.zip
,同时解压该文件并复制内部的Newtonsoft.Json.dll
文件拷贝到工程Assets
的Plugins
目录下,另外为了避免导出 IL2CPP 平台时删除必要数据,需在Assets
目录下创建link.xml
文件(如果已有该文件,则添加如下内容),其内容如下:
<linker>
<assembly fullname="System.Core">
<type fullname="System.Linq.Expressions.Interpreter.LightLambda" preserve="all" />
</assembly>
</linker>
repositories{
flatDir {
dirs 'libs'
}
}
dependencies {
...
implementation (name:'TapMoment_3.29.4', ext:'aar') // TapTap 内嵌动态
}
// 内嵌动态
TapMomentResource.bundle
TapMomentSDK.framework
PublicDependencyModuleNames.AddRange(new string[] {
//...
"TapMoment"
});
SDK 初始化
请确认已经完成了 Tap 登录初始化,则内嵌动态无需再次进行初始化;
- 如果使用 单纯的 TapTap 登录 并接入内嵌动态,初始化和 SDK 获取请参考:单纯的内嵌动态初始化。
设置回调
设置回调以获取动态的状态变化。
- Unity
- Android
- iOS
- UE4
TapMoment.SetCallback((code, msg) => {
Debug.Log(code + "---" + msg);
});
TapMoment.setCallback(new TapMoment.TapMomentCallback() {
@Override
public void onCallback(int code, String msg) {
}
});
@interface ViewController ()<TapMomentDelegate>
@end
[TapMoment setDelegate:self];
- (void)onMomentCallbackWithCode:(NSInteger)code msg:(NSString *)msg
{
NSLog (@"msg:%@, code:%i", msg, code);
}
FTapMoment::SetCallback(FTapMoment::FDelegate::CreateLambda([](int Code, const FString& Msg) {
}));
回调方法中 code 表示事件类型,现支持的回调类型如下:
回调 | 回调值 | 说明 |
---|---|---|
CALLBACK_CODE_PUBLISH_SUCCESS | 10000 | 动态发布成功 |
CALLBACK_CODE_PUBLISH_FAIL | 10100 | 动态发布失败 |
CALLBACK_CODE_PUBLISH_CANCEL | 10200 | 关闭动态发布页面 |
CALLBACK_CODE_GET_NOTICE_SUCCESS | 20000 | 获取新消息成功 |
CALLBACK_CODE_GET_NOTICE_FAIL | 20100 | 获取新消息失败 |
CALLBACK_CODE_MOMENT_APPEAR | 30000 | 动态页面打开 |
CALLBACK_CODE_MOMENT_DISAPPEAR | 30100 | 动态页面关闭 |
CALLBACK_CODE_CLOSE_CANCEL | 50000 | 取消关闭所有动态界面(弹框点击取消按钮) |
CALLBACK_CODE_CLOSE_CONFIRM | 50100 | 确认关闭所有动态界面(弹框点击确认按钮) |
CALLBACK_CODE_LOGIN_SUCCESS | 60000 | 动态页面内登录成功 |
CALLBACK_CODE_SCENE_EVENT | 70000 | 场景化入口回调 |
获取新消息
定时调用获取消息通知的接口,有新信息时可以在 TapTap 动态入口显示小红点,提醒玩家查看新动态。
- Unity
- Android
- iOS
- UE4
TapMoment.FetchNotification();
TapMoment.fetchNotification();
[TapMoment fetchNotification];
FTapMoment::FetchNotification();
获取消息通知的结果会在本文刚开始设置的回调中返回,code
为 CALLBACK_CODE_GET_NOTICE_SUCCESS
(20000
)表示获取成功,CALLBACK_CODE_GET_NOTICE_FAIL
(20100
)表示获取失败。
获取成功时,msg
为新消息数量,0
表示没有新消息。
为了方便玩家查看好友动态、游戏公告等,我们建议将 TapTap 动态入口放在显眼的位置,每分钟调用 1 次获取消息通知的接口。
获取消息通知时,如果没有新消息(msg
为 0
),那么游戏需要清除界面上的小红点。
同样,打开 TapTap 动态页面后,游戏也需要清除界面上的小红点。
设置默认屏幕方向
在游戏中显示动态页面时,如果游戏屏幕方向始终保持不变,开发者可调用如下接口设置动态默认展示的屏幕方向。
- Unity
- Android
- iOS
- UE4
TapMoment.SetDefaultOrientation(Orientation.ORIENTATION_LANDSCAPE);
TapMoment.setDefaultOrientation(TapMoment.ORIENTATION_PORTRAIT);
TapMomentConfig *mConfig = TapMomentConfig.new;
mConfig.orientation = TapMomentOrientationDefault;
[TapMoment setDefaultConfig:mConfig];
//暂不支持
设置方向后,后续打开动态页面接口可选择使用该方向。
显示动态页面
在游戏中显示 TapTap 动态页面,在这个页面,玩家不仅可以查看动态,还能发布新动态。
- Unity
- Android
- iOS
- UE4
//使用指定屏幕方向
TapMoment.Open(Orientation.ORIENTATION_LANDSCAPE);
//使用默认方向
TapMoment.Open();
//使用指定屏幕方向
TapMoment.open(TapMoment.ORIENTATION_PORTRAIT);
//使用默认方向
TapMoment.open();
//使用指定屏幕方向
TapMomentConfig *mConfig = TapMomentConfig.new;
mConfig.orientation = TapMomentOrientationDefault;
[TapMoment open:mConfig];
//使用默认方向
[TapMoment open];
//使用指定屏幕方向
FTapMoment::Open(ETapMomentOrientation::PORTRAIT);
打开动态页面时,请先屏蔽游戏自身的声音,以免干扰动态内的视频声音。
如需要动态能支持横竖屏随设备自动旋转,需要游戏自身能支持横竖屏。
如前所述,打开动态页面后别忘了清除动态页面入口处的小红点。
动态页面的背景图可以配置,步骤如下图所示。 背景图需要人工审核后才能生效,请预留充足的时间。
场景化入口
开发者可以结合游戏场景绘制入口,玩家打开入口跳转到指定的页面。使用前需要在开发者中心后台完成场景化入口配置。
- Unity
- Android
- iOS
- UE4
// sceneId 为开发者中心后台创建场景化入口后生成的「入口 ID」
var sceneDic = new Dictionary<string, object>() { { TapMomentConstants.TapMomentPageShortCutKey, sceneId } };
//使用指定屏幕方向
TapMoment.DirectlyOpen(Orientation.ORIENTATION_DEFAULT, TapMomentConstants.TapMomentPageShortCut, sceneDic);
// 使用默认屏幕方向
TapMoment.DirectlyOpen(TapMomentConstants.TapMomentPageShortCut, sceneDic);
参数说明
参数 | 说明 |
---|---|
orientation | 打开方向 |
page | 固定为 TapMomentConstants.TapMomentPageShortCut |
Dictionary | 其中 TapMomentConstants.TapMomentPageShortCutKey 固定,第三个参数为需要跳转的页面 id |
Map<String, String> extras = new HashMap<>();
// 注意:这里的 key 是固定的,"scene_id";第二个参数是开发者中心后台创建场景化入口后生成的「入口 ID」
extras.put("scene_id", "xxxx");
// 使用指定屏幕方向,注意:第二个参数固定为 "tap://moment/scene/"
TapMoment.directlyOpen(TapMoment.ORIENTATION_DEFAULT,"tap://moment/scene/", extras);
//使用设置的默认方向
TapMoment.directlyOpen("tap://moment/scene/", extras);
参数说明
参数 | 说明 |
---|---|
orientation | 打开方向 |
page | 固定为 tap://moment/scene/ |
HashMap | 集合中的 Key 固定为 scene_id 表示需要跳转的页面 id |
TapMomentConfig *mConfig = TapMomentConfig.new;
mConfig.orientation = TapMomentOrientationDefault;
//使用指定方向
[TapMoment directlyOpen:mConfig page:TapMomentPageShortcut extras:@{ TapMomentPageShortcutKey: @"sceneid" }];
//使用设置的默认屏幕方向
[TapMoment directlyOpen:TapMomentPageShortcut extras:@{ TapMomentPageShortcutKey: @"sceneid" }];
参数说明
参数 | 说明 |
---|---|
orientation | 打开方向 |
page | 固定为 TapMomentPageShortcut |
Dictionary | TapMomentPageShortcutKey 为固定写法,表示需要跳转的页面 id |
TSharedPtr<FJsonObject> JsonObject = MakeShared<FJsonObject>();
// 注意:这里的 key 是固定的,FTapMomentPage::ShortCutKey;第二个参数是开发者中心后台创建场景化入口后生成的「入口 ID」
JsonObject->SetStringField(FTapMomentPage::ShortCutKey, "xxxx");
// 注意:第二个参数固定为 FTapMomentPage::ShortCut
FTapMoment::DirectlyOpen(ETapMomentOrientation::DEFAULT, FTapMomentPage::ShortCut, JsonObject);
参数 | 说明 |
---|---|
Orientation | 打开方向 |
Page | 固定为 FTapMomentPage::ShortCut |
Extras | 其中 FTapMomentPage::ShortCutKey 固定,第三个参数为需要跳转的页面 id |
场景化入口回调格式说明
SDK 回调结构
字段名 | 值类型 | required | 说明 |
---|---|---|---|
sceneId | 字符串 | 是 | 场景化入口 ID |
eventType | 字符串 | 是 | 枚举的事件类型,如 VIEW,FORWARD,VOTE 等 |
eventPayload | 字符串 | 是 | 根据类型自定义的 JSON 字符串 |
timestamp | 整数 | 是 | unix 时间戳,ms |
事件类型
eventType | eventPayload (未序列化) | 说明 |
---|---|---|
READY | {} | 场景化页面已打开 |
REPOST | {} | 转发,仅帖子本身 |
VOTE | { isCancel: boolean } | 点赞(含是否取消),仅帖子本身 |
FOLLOW | { isCancel: boolean } | 关注(含是否取消),仅帖子本身 |
COMMENT | {} | 评论,仅帖子本身 |
关闭动态页面
玩家可以在动态页面退出。 但在特定场景下,游戏可能需要主动关闭动态页面。
比如,玩家排位等待结束,准备进入对局时提示玩家关闭动态页面,玩家确认后关闭。
- Unity
- Android
- iOS
- UE4
TapMoment.Close("提示", "匹配成功,进入游戏");
TapMoment.closeWithConfirmWindow("提示", "匹配成功,进入游戏");
[TapMoment closeWithTitle:@"提示" content:@"匹配成功,进入游戏" showConfirm:YES];
FTapMoment::Close(TEXT("提示"), TEXT("匹配成功,进入游戏"));
用户的选择会通过回调返回:
CALLBACK_CODE_CLOSE_CANCEL
(50000),表示玩家点了「取消」,选择不关闭动态页面。CALLBACK_CODE_CLOSE_CONFIRM
(50100),表示玩家点了「确认」,选择关闭动态页面。
如果需要直接关闭动态窗口,不弹出二次确认框:
- Unity
- Android
- iOS
- UE4
TapMoment.Close();
TapMoment.close();
[TapMoment close];
FTapMoment::Close();
一键发布
这是可选功能,请根据项目需求决定是否在游戏中加入这一功能。
我们推荐游戏让玩家直接在动态页面发布新动态。 不过,SDK 也提供了发布图文动态的 API,以支持「一键发动态」等需求。 图文动态包括单张或多张图片及相应的文字内容。
- Unity
- Android
- iOS
- UE4
string content = "我是描述";
string[] images = {"imgpath01","imgpath02","imgpath03"};
//使用指定屏幕方向
TapMoment.Publish(Orientation.ORIENTATION_LANDSCAPE, images, content);
//使用默认方向
TapMoment.Publish(images, content);
int orientation = TapMoment.ORIENTATION_PORTRAIT;
String content = "描述";
String[] imagePaths = new String[]{"content://hello.jpg", "/sdcard/world.jpg"};
//使用指定屏幕方向
TapMoment.publish(orientation, imagePaths, content);
//使用默认方向
TapMoment.publish(imagePaths, content);
TapMomentConfig * tconfig = TapMomentConfig.new;
tconfig.orientation = TapMomentOrientationDefault;
TapMomentImageData *postData = TapMomentImageData.new;
postData.images = @[@"file://..."];
postData.content = @"我是图片描述";
//使用指定屏幕方向
[TapMoment publish:tconfig content:(postData)];
//使用默认方向
[TapMoment publish:(postData)];
TArray<FString> ImagePaths = {"imgpath01", "imgpath02", "imgpath03"};
FTapMoment::Publish(ETapMomentOrientation::PORTRAIT, ImagePaths, TEXT("我是描述"));
玩家在动态页面可以发布图文动态和视频动态。 「一键发布」只支持发布图文动态。
国际化
内嵌动态支持设置语言:
- Unity
- Android
- iOS
- UE4
TapCommon.SetLanguage(TapLanguage.AUTO);
支持如下语言:
namespace TapTap.Common
{
public enum TapLanguage
{
AUTO = 0, // 自动
ZH_HANS = 1, // 简体中文
EN = 2, // 英文
ZH_HANT = 3, // 繁体中文
JA = 4, // 日文
KO = 5, // 韩文
TH = 6, // 泰文
ID = 7, // 印尼语
DE = 8, // 德语
ES = 9, // 西班牙语
FR = 10, // 法语
PT = 11, // 葡萄牙语
RU = 12, // 俄语
TR = 13, // 土耳其语
VI = 14, // 越南语
}
}
TapLanguage lang = 0;
TapBootstrap.setPreferredLanguage(TapLanguage.AUTO);
支持如下语言:
AUTO 跟随系统
ZH_HANS 简体中文
EN 英文
ZH_HANT 繁体中文
JA 日文
KO 韩文
TH 泰文
ID 印尼语
DE 德语
ES 西班牙语
FR 法语
PT 葡萄牙语
RU 俄语
TR 土耳其语
VI 越南语
[TapBootstrap setPreferredLanguage:TapLanguageType_Auto];
支持如下语言:
typedef NS_ENUM (NSInteger, TapLanguageType) {
TapLanguageType_Auto = 0, // 自动
TapLanguageType_zh_Hans, // 简体中文
TapLanguageType_en, // 英文
TapLanguageType_zh_Hant, // 繁体中文
TapLanguageType_ja, // 日文
TapLanguageType_ko, // 韩文
TapLanguageType_th, // 泰文
TapLanguageType_id, // 印度尼西亚语
TapLanguageType_de, // 德语
TapLanguageType_es, // 西班牙语
TapLanguageType_fr, // 法语
TapLanguageType_pt, // 葡萄牙语
TapLanguageType_ru, // 俄语
TapLanguageType_tr, // 土耳其语
TapLanguageType_vi, // 越南语
};
TapUECommon::SetLanguage(ELanguageType::AUTO);
支持如下语言:
UENUM(BlueprintType)
enum class ELanguageType : uint8
{
AUTO = 0, // 自动
ZH, // 简体中文
EN, // 英文,海外默认语言
ZHTW, // 繁体中文
JA, // 日语
KO, // 韩语
TH, // 泰文
ID, // 印尼文
DE, // 德语
ES, // 西班牙语
FR, // 法语
PT, // 葡萄牙语
RU, // 俄语
TR, // 土耳其语
VI, // 越南语
};
「自动」会尝试根据系统语言设置语言,如果系统语言不在上述支持的语言之中,那么会根据 SDK 初始化时配置的区域设置语言。 区域为中国大陆时会设置为简体中文,否则会设置为英文。
单纯的内嵌动态初始化
这里 SDK 获取及初始化,仅供使用 单纯的 TapTap 登录 的开发者参考。
- 请先 下载 TapSDK,并添加相关依赖。内嵌动态功能依赖
TapLogin
、TapCommon
和TapMoment
模块。
TapSDK Unity v3.7.1 及更高版本还需要添加 com.leancloud.storage
模块。Android SDK 及 iOS SDK 不需要额外增加依赖。
- Unity
- Android
- iOS
- UE4
"dependencies":{
"com.taptap.tds.login":"https://github.com/TapTap/TapLogin-Unity.git#3.29.4",
"com.taptap.tds.common":"https://github.com/TapTap/TapCommon-Unity.git#3.29.4",
"com.taptap.tds.moment":"https://github.com/TapTap/TapMoment-Unity.git#3.29.4",
"com.leancloud.storage": "https://github.com/leancloud/csharp-sdk-upm.git#storage-2.3.0",
}
repositories{
flatDir {
dirs 'libs'
}
}
dependencies {
...
implementation (name:'TapCommon_3.29.4', ext:'aar') // 必选:TapSDK 基础库
implementation (name:'TapLogin_3.29.4', ext:'aar') // 必选:TapTap 登录
implementation (name:'TapMoment_3.29.4', ext:'aar') // TapTap 内嵌动态
}
// 基础库
TapCommonSDK.framework
// 3.29.4 版本需要添加 LibProtocolBuffers
LibProtocolBuffers.framework
TapLoginSDK.framework
TapCommonResource.bundle
TapLoginResource.bundle
// 内嵌动态
TapMomentResource.bundle
TapMomentSDK.framework
// 基础库
TapCommon
TapLogin
// 内嵌动态
TapMoment
请确认完成了 单纯 TapTap 登录的初始化。
完成内嵌动态功能的初始化,示例如下:
- Unity
- Android
- iOS
- UE4
// 适用于中国大陆
TapMoment.Init(string clientID);
// 适用于其他国家或地区 isCN 为 true 表示中国大陆,false 表示其他国家或地区
TapMoment.Init(string clientID, boolean isCN);
参数说明
参数 | 描述 |
---|---|
clientID | TapTap 开发者中心对应游戏的 Client ID。 |
// 适用于中国大陆
TapMoment.init(Context context, String clientID);
// 适用于其他国家或地区 isCN 为 true 表示中国大陆,false 表示其他国家或地区
TapMoment.init(Context context, String clientID, boolean isCN);
参数说明
参数 | 描述 |
---|---|
context | 上下文,一般是当前 Application。 |
clientID | TapTap 开发者中心对应游戏的 Client ID。 |
// 适用于中国大陆
[TapMoment initWithClientID:@"your clientId"];
// 适用于其他国家或地区 isCN 为 true 表示中国大陆,false 表示其他国家或地区
[TapMoment initWithClientID:@"your clientId" isCN:isCN];
参数说明
参数 | 描述 |
---|---|
clientId | TapTap 开发者中心对应应用的 Client ID |
FTapMomentConfig Config;
Config.RegionType = ERegionType::Global;
Config.ClientID = "your clientId";
FTapMoment::Init(Config);
参数说明
参数 | 描述 |
---|---|
Config | 其中 ClientID 是 TapTap 开发者中心对应游戏的 Client ID。 |
- 使用本篇文档中提到的其他接口。