开发指南
集成前准备
- 参考 开发者中心配置 创建应用、配置包名与签名证书
- 参考 TapTap 登录功能介绍开通 TapTap 登录服务
- 参考集成指南(Unity、Android、iOS)完成对应平台或引擎的基础接入
权限说明
- Android
该模块依赖如下权限:
| 权限 | 使用目的 | 权限申请时机 |
|---|---|---|
| 网络权限 | 用于访问网络数据 | 用户首次使用该功能时会申请权限 |
该模块将在应用中添加如下配置:
<uses-permission android:name="android.permission.INTERNET"/>
SDK 获取
- Unity
- Android
- iOS
远程依赖
NPMJS 方式:在 Packages/manifest.json 中添加:
"dependencies":{
"com.taptap.sdk.core":"4.9.3",
"com.taptap.sdk.login":"4.9.3"
}
GitHub 方式:在 Packages/manifest.json 中添加:
"dependencies":{
"com.taptap.sdk.core":"https://github.com/taptap/tapsdk-unity-dist.git?path=/Core#4.9.3",
"com.taptap.sdk.login":"https://github.com/taptap/tapsdk-unity-dist.git?path=/Login#4.9.3"
}
本地文件导入
在 下载页 下载并导入以下 unitypackage 文件:
TapSDK_Core.unitypackage(TapTapSDK 核心模块,必选)TapSDK_Login.unitypackage(TapTapSDK 登录模块,必选)
在 app module 的 build.gradle 中添加对应依赖:
dependencies {
implementation 'com.taptap.sdk:tap-core:4.9.3'
implementation 'com.taptap.sdk:tap-login:4.9.3'
}
iOS 工程配置
在 iOS 项目或通过 Unity 项目导出 Xcode 工程时,需要添加 TapTap 客户端应用跳转配置,具体如下:
- Unity
- iOS
在 Assets/Plugins/iOS/Resource 目录下创建 TDS-Info.plist 文件,复制以下代码并且替换其中的 ClientId。
复制使用以下内容时,请删除空行以及注释,以免出现 XML 解析时报错,ApplicationException: expected a key node。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>taptap</key>
<dict>
<key>client_id</key>
<string>ClientId</string>
</dict>
</dict>
</plist>
-
打开
info.plist,添加如下配置(请替换clientID为你在控制台获取的 Client ID):
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>taptap</string>
<key>CFBundleURLSchemes</key>
<array>
<!-- 这里注意下,中括号需要去掉,最终是 Client ID 前拼接上 `tt` 的形式,例如:ttFwFdCxxxxxxxQDQwQN -->
<string>tt[clientID]</string>
</array>
</dict>
</array>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>tapiosdk</string>
<string>tapsdk</string>
<string>taptap</string>
</array> -
配置 openUrl
- Swift
- Objective-C
a) 如果项目中有
SceneDelegate.swift, 请在该文件中添加如下代码:import TapTapLoginSDK
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
for context in URLContexts {
/// 是否被登录模块处理
let hasIntercept = TapTapLogin.open(url: context.url)
}
}b) 如果项目中只有
AppDelegate.swift, 请在该文件中添加如下代码:import TapTapLoginSDK
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
return TapTapLogin.open(url: url)
}
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
return TapTapLogin.open(url: url)
}a) 如果项目中有 `Scenedelegate.m``,请添加如下代码:
#import "TapTapLoginSDK/TapTapLoginSDK-Swift.h"
#pragma mark - 处理外部 URL 打开(iOS 13+)
- (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts API_AVAILABLE(ios(13.0)){
for (UIOpenURLContext *context in URLContexts) {
/// 是否被登录模块处理
bool hasIntercept = [TapTapLogin openWithUrl:context.URL];
}
}b) 如果项目中只有 `AppDelegate.m``,请添加如下代码:
#import "TapTapLoginSDK/TapTapLoginSDK-Swift.h"
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [TapTapLogin openWithUrl:url];
}
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
return [TapTapLogin openWithUrl:url];
}
登录
当用户启动游戏时,可以先检查用户登录状态,如果玩家已经登录,则不显示登录按钮,让玩家直接进入游戏。
- Unity
- Android Java
- Android Kotlin
- iOS Swift
- iOS Objective-C
using TapSDK.Login;
using System.Threading.Tasks;
try
{
// 定义授权范围
List<string> scopes = new List<string>
{
TapTapLogin.TAP_LOGIN_SCOPE_PUBLIC_PROFILE
};
// 发起 Tap 登录
var userInfo = await TapTapLogin.Instance.LoginWithScopes(scopes.ToArray());
Debug.Log($"登录成功,当前用户 ID:{userInfo.unionId}");
}
catch (TaskCanceledException)
{
Debug.Log("用户取消登录");
}
catch (Exception exception)
{
Debug.Log($"登录失败,出现异常:{exception}");
}
import com.taptap.sdk.kit.internal.callback.TapTapCallback;
import com.taptap.sdk.kit.internal.exception.TapTapException;
import com.taptap.sdk.login.Scopes;
import com.taptap.sdk.login.TapTapAccount;
import com.taptap.sdk.login.TapTapLogin;
import androidx.annotation.NonNull;
// 定义授权范围
String[] scopes = new String[]{Scopes.SCOPE_PUBLIC_PROFILE};
TapTapLogin.loginWithScopes(activity, scopes, new TapTapCallback<TapTapAccount>() {
@Override
public void onSuccess(TapTapAccount tapTapAccount) {
// 登录成功
}
@Override
public void onFail(@NonNull TapTapException exception) {
// 登录失败
}
@Override
public void onCancel() {
// 登录取消
}
});
import com.taptap.sdk.login.TapTapLogin
import com.taptap.sdk.kit.internal.callback.TapTapCallback
import com.taptap.sdk.login.TapTapAccount
import com.taptap.sdk.login.Scopes
val scopes = mutableSetOf<String>()
scopes.add(Scopes.SCOPE_PUBLIC_PROFILE)
TapTapLogin.loginWithScopes(
activity,
scopes.toTypedArray(),
object : TapTapCallback<TapTapAccount> {
override fun onSuccess(result: TapTapAccount) {
// 成功
}
override fun onCancel() {
// 取消
}
override fun onFail(exception: TapTapException) {
// 失败
}
}
)
import TapTapLoginSDK
// 定义授权范围
var scopes: [Scope] = [Scope.publicProfile]
// 发起 Tap 登录
TapTapLogin.loginWithScopes(with: scopes) {[weak self] account, error, isCancel in
guard let self else { return }
if isCancel {
// 登录取消
} else if let error = error {
// 登录失败
NSLog("Tap登录失败:\(error.localizedDescription)")
} else if let account = account {
// 登录成功
// 登录 token
let token = account.accessToken
// 用户信息
let userInfo = account.userInfo
}
}
// SDK 默认会使用应用当前最上层的页面作为 SDK 登录弹窗的容器,如果应用需要指定,可参考下方示例
TapTapLogin.login(with:getAuthScopes(), viewController: self) { [weak self] account, error, isCancel in
guard let self else { return }
if isCancel {
// 登录取消
} else if let error = error {
// 登录失败
NSLog("Tap登录失败:\(error.localizedDescription)")
} else if let account = account {
// 登录成功
// 登录 token
let token = account.accessToken
// 用户信息
let userInfo = account.userInfo
}
}
#import "TapTapLoginSDK/TapTapLoginSDK-Swift.h"
// 定义授权范围
NSArray *scopes = @[@"public_profile"];
// 发起 Tap 登录
[TapTapLogin LoginWithScopes:scopes handler:^(BOOL isCancel, NSError * _Nullable error, TapTapAccount * _Nullable account) {
if (isCancel) {
// 登录取消
} else if (error != nil) {
NSLog(@"Tap 登录失败 ");
} else {
// 登录成功
// 登录 token
AccessToken *token = account.accessToken;
// 用户信息,包括 openid、unionid、用户昵称、用户头像
UserInfo *userInfo = account.userInfo;
}
}];
// SDK 默认会使用应用当前最上层的页面作为 SDK 登录弹窗的容器,如果应用需要指定,可参考下方示例
[TapTapLogin LoginWithScopes: scopes viewController:viewController handler:^(BOOL isCancel, NSError * _Nullable error, TapTapAccount * _Nullable account) {
if (isCancel) {
// 登录取消
} else if (error != nil) {
NSLog(@"Tap 登录失败 ");
} else {
// 登录成功
// 登录 token
AccessToken *token = account.accessToken;
// 用户信息,包括 openid、unionid、用户昵称、用户头像
UserInfo *userInfo = account.userInfo;
}
}];
不同的授权范围
TapTap 授权登录接口支持选择不同的授权范围且支持任意组合,但必须包含 public_profile 和 basic_info 中的一个,不然无法获得 openId 和 unionId。TapTap 授权登录接口可以传递 String 类型的数组作为参数,开发者可以根据自己业务需求添加不同的权限为数组的元素。
| 权限 | 说明 |
|---|---|
public_profile | 获得 openId、unionId、用户昵称、用户头像 |
user_friends | 获得访问 TapTap 好友相关数据的权限 |
basic_info | 获得 openId 和 unionId |
若游戏发起 TapTap 授权登录时只请求 basic_info 的权限,则用户可享受无感登录的特性,即用户不需要手动确认授权即可自动授权完成登录。
获取用户信息
TapTap 用户登录成功之后,开发者可以通过如下方式获取到 TapTap 授权结果的详细信息:
- Unity
- Android Java
- Android Kotlin
- iOS Swift
- iOS Objective-C
using TapSDK.Login;
using System.Threading.Tasks;
TapTapAccount taptapAccount = await TapTapLogin.Instance.GetCurrentTapAccount();
AccessToken accessToken = taptapAccount.accessToken;
string openId = taptapAccount.openId;
import com.taptap.sdk.login.TapTapAccount;
import com.taptap.sdk.login.TapTapLogin;
import com.taptap.sdk.login.AccessToken;
TapTapAccount taptapAccount = TapTapLogin.getCurrentTapAccount();
AccessToken accessToken = taptapAccount.getAccessToken();
String openId = taptapAccount.getOpenId();
import com.taptap.sdk.login.TapTapLogin
import com.taptap.sdk.login.AccessToken
import com.taptap.sdk.login.TapTapAccount
val taptapAccount = TapTapLogin.getCurrentTapAccount()
val accessToken = taptapAccount?.accessToken
val openId = taptapAccount?.openId
import TapTapLoginSDK
let taptapAccount = TapTapLogin.getCurrentTapAccount()
let accessToken = taptapAccount?.accessToken
let openId = taptapAccount?.userInfo?.openId
#import "TapTapLoginSDK/TapTapLoginSDK-Swift.h"
NSString * openId = nil;
TapTapAccount *taptapAccount = TapTapLogin.getCurrentTapAccount;
if (taptapAccount != nil){
AccessToken *accessToken = taptapAccount.accessToken;
UserInfo * userInfo = TapTapLogin.getCurrentTapAccount.userInfo;
if (userInfo != nil) {
openId = userInfo.openId;
}
}
其中 taptapAccount 可能会包含如下信息:
| 参数 | 说明 |
|---|---|
accessToken | 玩家在 TapTap 平台的用户 token 信息 |
name | 玩家在 TapTap 平台的昵称 |
avatar | 玩家在 TapTap 平台的头像 url |
openId | 通过用户信息和游戏信息生成的用户唯一标识,每个玩家在每个游戏中的 openId 都是不一样的 |
unionId | 通过用户信息加上厂商信息生成的用户唯一标识,一个玩家在同一个厂商的所有游戏中 unionId 都是一样的,不同厂商下 unionId 不同 |
openId 和 unionId 使用标准的 Base64(带 Padding)编码,包含的字符有 A-Za-z0-9+/=。openId 和 unionId 长度最大值为 50 个字符。
由于 unionId 与游戏所属厂商有强关联性,因此 unionId 适用于如下场景:厂商使用测试服进行付费删档等测试,正式服需要对于之前参与测试的老玩家进行返利等操作。因为同一个玩家在同一个厂商下的所有游戏中的 unionId 不变。
一个游戏在厂商转移后同一个用户的 unionId 会发生改变,如果游戏使用了 unionId,TDS 技术支持会在转移前通过工单和游戏开发者确认相关数据的处理方案,保证迁移前后用户数据不错乱。
检查登录状态和用户信息
登录状态和用户信息存在本地缓存中,重新登录将会重置,登出将会清除。
- Unity
- Android Java
- Android Kotlin
- iOS Swift
- iOS Objective-C
using TapSDK.Login;
try {
TapTapAccount account = await TapTapLogin.Instance.GetCurrentTapAccount();
if (account == null) {
// 用户未登录
} else {
// 用户已登录
}
} catch (Exception e) {
Debug.Log($"获取用户信息失败 {e.Message}");
}
import com.taptap.sdk.login.AccessToken;
import com.taptap.sdk.login.TapTapAccount;
import com.taptap.sdk.login.TapTapLogin;
TapTapAccount currentTapAccount = TapTapLogin.getCurrentTapAccount();
if (currentTapAccount != null) {
// 已登录
AccessToken accessToken = currentTapAccount.getAccessToken();
} else {
// 未登录
}
import com.taptap.sdk.login.TapTapLogin
import com.taptap.sdk.login.TapTapAccount
// 获取用户信息
when (TapTapLogin.getCurrentTapAccount() == null) {
true -> {
// 未登录
}
else -> {
// 已登录
}
}
import TapTapLoginSDK
if let account = TapTapLogin.getCurrentTapAccount() {
let token = account.accessToken
let profile = account.userInfo
if let token, let profile {
// 用户已登录
} else {
NSLog("Tap账户未登录")
}
} else {
NSLog("Tap账户未登录")
}
#import "TapTapLoginSDK/TapTapLoginSDK-Swift.h"
TapTapAccount *account = [TapTapLogin getCurrentTapAccount];
if (account != nil ){
AccessToken *token = account.accessToken;
UserInfo *userInfo = account.userInfo;
if (token != nil && userInfo != nil) {
// 用户已登录
} else {
// 用户未登录
}
} else {
// 用户未登录
}
登出
- Unity
- Android Java
- Android Kotlin
- iOS Swift
- iOS Objective-C
using TapSDK.Login;
TapTapLogin.Instance.Logout();
import com.taptap.sdk.login.TapTapLogin;
TapTapLogin.logout();
import com.taptap.sdk.login.TapTapLogin
TapTapLogin.logout()
import TapTapLoginSDK
TapTapLogin.logout()
#import "TapTapLoginSDK/TapTapLoginSDK-Swift.h"
[TapTapLogin logout];
Unity PC 登录配置
由于接入了 TapTap PC 端的游戏与未接入游戏在登录交互流程上存在明显差异,请开发者根据游戏的接入方式,选择对应的登录处理流程。
TapTap PC 端登录
接入 TapTap PC 端时, 需要使用启动校验功能,具体参考 文档
在使用 TapTap PC 端登录时,SDK 将以静默方式进行登录流程,不会弹出 UI 窗口。由于该流程为异步操作,建议开发者在发起登录前显示加载(Loading)弹窗,并在登录流程完成后关闭该弹窗,以提升用户体验。
普通 PC 登录
SDK 默认支持扫码登录,跳转浏览器登录需要额外配置,具体参考以下两节。

Windows 平台
如果想要在 Windows 使用跳转网页浏览器登录功能,需要在注册表添加相应配置:
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\open-taptap-{client_id}]
@="{游戏名称}"
"URL Protocol"="{程序.exe 安装路径}"
[HKEY_CLASSES_ROOT\open-taptap-{client_id}]
@="{游戏名称}"
[HKEY_CLASSES_ROOT\open-taptap-{client_id}]
[HKEY_CLASSES_ROOT\open-taptap-{client_id}\Shell\Open]
[HKEY_CLASSES_ROOT\open-taptap-{client_id}\Shell\Open\Command]
@="\"{程序.exe 安装路径}\" \"%1\""
macOS 平台
在 macOS 平台下,SDK 会自动配置 CFBundleURLTypes。
请通过以下步骤确认配置无误:
- 在 Unity 下打开
BuildSetting选择PC、Mac & Linux StandalonePlatform,Target Platform选择macOS。 - 勾选
Create XCode Project,选择输出XCode工程进行编译。 - 打开输出的
XCode Project,选择Target,点击Info,展开URL Types,检查是否自动添加以下URL Scheme:TapWeb : open-taptap-{clientId},如未添加,则手动添加:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>TapWeb</string>
<key>CFBundleURLSchemes</key>
<array>
<string>open-taptap-{client_id}</string>
</array>
</dict>
</array>