单纯 TapTap 用户认证
如果你仅仅只需要接入 TapTap 这一种登录方式,确认不使用 TDS 其他云服务,可以看本篇文档。请注意,如果刚开始只选择接入「TapTap 登录」,后面又需要使用其他云服务的话,后期可能有一定的升级成本。
使用原来 TapSDK v1.x 版本的开发者,也可以参考 1.x 升级 3.x 指南 完成 TapSDK 的升级。
环境要求
- 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"/>
集成前准备
SDK 获取
单纯接入「TapTap 登录」,需要依赖 TapLogin
和 TapCommon
模块。请先 下载 TapSDK,并添加相关依赖。
- 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"
在项目的 Packages/manifest.json
文件中添加以下依赖:
"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",
}
在 Unity 顶部菜单中选择 Window > Package Manager 可查看已经安装在项目中的包。
方法二:手动导入
在 下载页 找到 TapSDK Unity 下载地址,下载
TapSDK-UnityPackage.zip
。在 Unity 项目中依次转到 Assets > Import Packages > Custom Packages,从解压后的
TapSDK-UnityPackage.zip
中,选择希望在游戏中使用的 TapSDK 包导入,其中:TapTap_Common.unitypackage
TapSDK 基础库,必选。TapTap_Login.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>
如果是手动下载 unitypackage
进行 SDK 导入,需要将 Assets/TapTap/Common/Plugins/iOS/TapTap.Common.dll
设置为只支持 iOS。
iOS 配置
在 Assets/Plugins/iOS/Resource
目录下创建 TDS-Info.plist
文件,复制以下代码并且替换其中的 ClientId
。如果游戏使用了 TapTap 内嵌动态或数据分析服务,需要配置相关权限并替换授权文案:
复制使用以下内容时,请删除空行以及注释,以免出现 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>
<!--使用内嵌动态服务,需要相册、相机、麦克风权限-->
<key>NSPhotoLibraryUsageDescription</key>
<string>说明为何应用需要此项权限</string>
<key>NSCameraUsageDescription</key>
<string>说明为何应用需要此项权限</string>
<key>NSMicrophoneUsageDescription</key>
<string>说明为何应用需要此项权限</string>
<!--使用数据分析服务需要 IDFA 权限。如应用程序不想弹框,可以设置 TapDB.AdvertiserIDCollectionEnabled(false)-->
<key>NSUserTrackingUsageDescription</key>
<string>说明为何应用需要此项权限</string>
</dict>
</plist>
下载 TapSDK Android,解压后选择需要用到的 SDK 包导入到项目
project/app/libs
目录下。打开项目的
project/app/build.gradle
文件,添加 gradle 配置如下:
dependencies {
...
// 导入 libs 目录下所有 aar 的包:
implementation fileTree(dir: 'libs', include: ['*.aar'])
// 如果需要单独导入 libs 目录下的指定包,请按照如下方式:
implementation files('libs/TapCommon_3.29.4.aar') // TapTap 基础库
implementation files('libs/TapLogin_3.29.4.aar') // TapTap 登录
}
旧版 Android 额外配置
如果
targetSdkVersion < 29
,还需要添加如下配置:manifest
节点添加xmlns:tools="http://schemas.android.com/tools"
application
节点添加tools:remove="android:requestLegacyExternalStorage"
导入 SDK
在 Xcode 选择工程,到 Build Setting > Other Linker Flags 添加
-ObjC
和-Wl -ld_classic
。下载 TapSDK iOS,解压后选择需要导入的资源文件,直接拖拽到项目目录即可。
视需要导入下载的资源文件:
必选:TapTap 启动器、基础库、登录
TapBootstrapSDK.framework
TapCommonSDK.framework
// 3.29.4 版本需要添加 LibProtocolBuffers
LibProtocolBuffers.framework
TapLoginSDK.framework
LeanCloudObjc.framework
TapCommonResource.bundle
TapLoginResource.bundle
提示因 3.29.4 中引入的 libProtocolBuffers.framework 内部使用了 Swift 开发,所以如果当前工程未使用 Swift 开发,还需要在工程中建立一个空 Swift 文件,来添加 Xcode 对 Swift 基础库的支持
请仔细核对下面依赖库是否都添加成功:
// 必选
WebKit.framework
Security.framework
SystemConfiguration.framework
CoreTelephony.framework
SystemConfiguration.framework
libc++.tbd
// TapTap 内嵌动态
AVFoundation.framework
CoreTelephony.framework
MobileCoreServices.framework
Photos.framework
SystemConfiguration.framework
WebKit.framework
// 数据分析
// 如果不需要获取 IDFA 则不要添加 `AppTrackingTransparency` 和 `AdSupport` 两个系统库
AppTrackingTransparency.framework
AdSupport.framework
CoreMotion.framework
Security.framework
SystemConfiguration.framework
libresolv.tbd
libsqlite3.0.tbd
libz.tbd
配置权限
如果游戏使用了 TapTap 内嵌动态或数据分析服务,那么需要在 info.plist
配置相关权限并替换授权文案:
<!--使用内嵌动态服务,需要相册、相机、麦克风权限-->
<key>NSPhotoLibraryUsageDescription</key>
<string>说明为何应用需要此项权限</string>
<key>NSCameraUsageDescription</key>
<string>说明为何应用需要此项权限</string>
<key>NSMicrophoneUsageDescription</key>
<string>说明为何应用需要此项权限</string>
<!--使用数据分析服务需要 IDFA 权限。如应用程序不想弹框,可以设置 TapDB.AdvertiserIDCollectionEnabled(false)-->
<key>NSUserTrackingUsageDescription</key>
<string>说明为何应用需要此项权限</string>
配置跳转 TapTap 应用
用户无 TapTap 应用时,默认会通过 WebView 登录。
打开
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:
a) 如果项目中有
SceneDelegate.m
,请先删除,然后请添加如下代码到AppDelegate.m
文件:- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [TDSHandleUrl handleOpenURL:url];
}
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
return [TDSHandleUrl handleOpenURL:url];
}b) 删除
info.plist
里面的 Application Scene Manifestc) 删除
AppDelegate.m
文件中的两个管理Scenedelegate
生命周期代理方法#pragma mark - UISceneSession lifecycle
- (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options {
return [[UISceneConfiguration alloc] initWithName:@"Default Configuration" sessionRole:connectingSceneSession.role];
}
- (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet<UISceneSession *> *)sceneSessions {
}d) 在
AppDelegate.h
中添加UIWindow
@property (strong, nonatomic) UIWindow *window;
安装插件
- 下载 TapSDK UE4,TapSDK-UE4-xxx.zip 解压后将
TapLogin
、TapCommon
文件夹 Copy 到项目的Plugins
目录中 - 重启 Unreal Editor
- 打开 编辑 > 插件 > 项目 > TapTap,开启
TapLogin
模块
添加依赖
在 Project.Build.cs 中添加所需模块:
PublicDependencyModuleNames.AddRange(new string[] { "Core",
"CoreUObject",
"Engine",
"Json",
"InputCore",
"JsonUtilities",
"SlateCore",
"TapCommon",
"TapLogin"
});
导入头文件
#include "TapUELogin.h"
#include "TapUECommon.h"
点击展开 iOS 配置
在 项目设置 > Platform > iOS > Additional Plist data 中可以填入一个字符串,复制以下代码并且替换其中的 ClientID
以及授权文案。
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>taptap</string>
<key>CFBundleURLSchemes</key>
<array>
<!-- 这里注意下,花括号需要去掉,最终是 ClientID 前拼接上 `tt` 的形式,例如:ttFwFdCxxxxxxxQDQwQN -->
<string>tt{ClientID}</string>
</array>
</dict>
</array>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>tapiosdk</string>
<string>tapsdk</string>
<string>taptap</string>
</array>
初始化
游戏 适用地区 在开启应用配置时选定。
TapTap 开发者中心适用地区为中国大陆。
出海游戏请前往 TapTap.io 开发者中心 开启游戏服务,适用地区为其他国家或地区。
单纯 TapTap 登录初始化时需要区分适用于中国大陆还是其他国家或地区。
- Unity
- Android
- iOS
- UE4
// 适用于中国大陆
TapLogin.Init(string clientID);
// 适用于其他国家或地区
TapLogin.Init(string clientID, bool isCn, bool roundCorner);
参数说明
参数 | 描述 |
---|---|
clientID | TapTap 开发者中心对应应用的 Client ID |
isCn | 中国大陆为 true,其他国家或地区为 false |
roundCorner | 网页登录时边框是否使用圆角,使用圆⻆边框为 true,使用直⻆边框为 false |
// 适用于中国大陆
TapLoginHelper.init(Context context, String clientID);
// 适用于其他国家或地区
LoginSdkConfig config = new LoginSdkConfig();
config.regionType = RegionType.IO;
TapLoginHelper.init(Context context, String clientID, config);
参数说明
参数 | 描述 |
---|---|
context | 上下文,一般是当前 Application |
clientID | TapTap 开发者中心对应应用的 Client ID |
// 适用于中国大陆
[TapLoginHelper initWithClientID:clientID];
// 适用于其他国家或地区
TTSDKConfig *config = [[TTSDKConfig alloc] init];
config.regionType = RegionTypeIO;
config.roundCorner = YES;
[TapLoginHelper initWithClientID:clientID config:config];
参数说明
参数 | 描述 |
---|---|
clientID | TapTap 开发者中心对应应用的 Client ID |
regionType | 适用地区。适用于中国大陆为 RegionTypeCN ,适用于其他国家或地区为 RegionTypeIO |
roundCorner | 是否为圆角 |
配置跳转 TapTap 应用
用户无 TapTap 应用时,默认会打开 WebView 登录
打开 info.plist,添加如下配置,然后请替换 clientID 为你在控制台获取的 clientID
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>taptap</string>
<key>CFBundleURLSchemes</key>
<array>
<string>tt[clientID]</string>
</array>
</dict>
</array>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>tapiosdk</string>
<string>tapsdk</string>
<string>taptap</string>
</array>
如果项目中有 SceneDelegate.m,请先删除,然后添加如下代码到 AppDelegate.m 文件中。
#import <TapCommonSDK/TapCommonSDK.h>
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [TDSHandleUrl handleOpenURL:url];
}
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
return [TDSHandleUrl handleOpenURL:url];
}
并在 AppDelegate.h 中添加 UIWindow,然后删除 info.plist 里面的 Application Scene Manifest
@property (strong, nonatomic) UIWindow *window;
FTULoginConfig Config;
Config.ClientID = ClientID;
Config.RegionType = RegionType;
TapUELogin::Init(Config);
参数说明
参数 | 描述 |
---|---|
clientID | TapTap 开发者中心对应应用的 Client ID |
RegionType | 适用地区。适用于中国大陆为 ERegionType::CN ,适用于其他国家或地区为 ERegionType::Global |
TapTap 登录并获取登录结果
当用户启动游戏时,可以先检查用户登录状态,如果玩家已经登录,则不显示登录按钮,让玩家直接进入游戏。
- Unity
- Android
- iOS
- UE4
try
{
// 在 iOS、Android 系统下,会唤起 TapTap 客户端或以 WebView 方式进行登录
// 在 Windows、macOS 系统下显示二维码(默认)和跳转链接(需配置)
var accessToken = await TapLogin.Login();
Debug.Log($"TapTap 登录成功 accessToken: {accessToken.ToJson()}");
}
catch (Exception e)
{
if (e is TapException tapError) // using TapTap.Common
{
Debug.Log($"encounter exception:{tapError.code} message:{tapError.message}");
if (tapError.code == (int)TapErrorCode.ERROR_CODE_BIND_CANCEL) // 取消登录
{
Debug.Log("登录取消");
}
}
}
// 获取 TapTap Profile 可以获得当前用户的一些基本信息,例如名称、头像。
var profile = await TapLogin.FetchProfile();
Debug.Log($"TapTap 登录成功 profile: {profile.ToJson()}");
// 实例化监听
TapLoginHelper.TapLoginResultCallback loginCallback = new TapLoginHelper.TapLoginResultCallback() {
@Override
public void onLoginSuccess(AccessToken token) {
Log.d(TAG, "TapTap authorization succeed");
// 开发者调用 TapLoginHelper.getCurrentProfile() 可以获得当前用户的一些基本信息,例如名称、头像。
Profile profile = TapLoginHelper.getCurrentProfile();
}
@Override
public void onLoginCancel() {
Log.d(TAG, "TapTap authorization cancelled");
}
@Override
public void onLoginError(AccountGlobalError globalError) {
Log.d(TAG, "TapTap authorization failed. cause: " + globalError.getMessage());
}
};
// 注册监听
TapLoginHelper.registerLoginCallback(loginCallback);
// 登录
TapLoginHelper.startTapLogin(MainActivity.this, TapLoginHelper.SCOPE_PUBLIC_PROFILE);
[TapLoginHelper registerLoginResultDelegate:delegator];
if ([TapLoginHelper currentProfile]) {
// 当前已经登录
} else {
[TapLoginHelper startTapLogin:@[@"public_profile"]];
}
// delegator
- (void)onLoginCancel {
// 登录取消
}
- (void)onLoginError:(nonnull NSError *)error {
// 登录失败
}
- (void)onLoginSuccess:(nonnull TTSDKAccessToken *)token {
// 登录成功
}
// 权限参考 TUType::PermissionScope
TapUELogin::Login({TUType::PermissionScope::Profile}, [](const TUAuthResult& Result) {
if (Result.GetType() == TUAuthResult::Success) {
// 登录成功
TSharedPtr<FTULoginProfileModel> Profile = TapUELogin::GetProfile();
}
else if (Result.GetType() == TUAuthResult::Cancel) {
// 登录取消
}
else {
// 登录失败
}
});
这里获取的 TapTapAccount
根据游戏申请的授权范围有所差异。
其中可能会包含如下信息:
参数 | 说明 |
---|---|
accessToken | 用户访问凭证 |
openid | 通过用户信息和游戏信息生成的用户唯一标识,每个玩家在每个游戏中的 openid 都是不一样的 |
unionid | 通过用户信息加上厂商信息生成的用户唯一标识,一个玩家在同一个厂商的所有游戏中 unionid 都是一样的,不同厂商下 unionid 不同 |
name | 玩家在 TapTap 平台的昵称 |
avatar | 玩家在 TapTap 平台的头像 url |
email | 用户在 TapTap 平台注册使用的邮箱 |
openid
和 unionid
使用标准的 Base64(带 Padding)编码,包含的字符有 A-Za-z0-9+/=
。openid
和 unionid
长度最大值为 50 个字符。
由于 unionid
与游戏所属厂商有强关联性,因此 unionid
适用于如下场景:厂商使用测试服进行付费删档等测试,正式服需要对于之前参与测试的老玩家进行返利等操作。因为同一个玩家在同一个厂商下的所有游戏中的 unionid
不变。
一个游戏在厂商转移后同一个用户的 unionid
会发生改变,如果游戏使用了 unionid
,TDS 技术支持会在转移前通过工单和游戏开发者确认相关数据的处理方案,保证迁移前后用户数据不错乱。
开发者可以合理使用这些信息。
检查登录状态和用户信息
登录状态和用户信息存在本地缓存中,重新登录将会重置,登出将会清除。
- Unity
- Android
- iOS
- UE4
// 获取登录状态
try
{
var accesstoken = await TapLogin.GetAccessToken();
Debug.Log("已登录");
// 直接进入游戏
}
catch (Exception e)
{
Debug.Log("当前未登录");
// 开始登录
}
// 获取用户信息
await TapLogin.GetProfile();
// 获取实时更新的用户信息
await TapLogin.FetchProfile();
// 获取登录状态
TapLoginHelper.getCurrentAccessToken();
// 获取用户信息
TapLoginHelper.getCurrentProfile();
// 获取实时更新的用户信息
TapLoginHelper.fetchProfileForCurrentAccessToken(new ApiCallback<Profile>() {
@Override
public void onSuccess(Profile data) {
}
@Override
public void onError(Throwable error) {
}
});
// 获取登录状态
[TapLoginHelper currentAccessToken];
// 获取用户信息
[TapLoginHelper currentProfile];
// 获取实时更新的用户信息
[TapLoginHelper fetchProfileForCurrentAccessToken:^(TTSDKProfile *_Nonnull profile, NSError *_Nonnull error) {}];
// 获取登录状态
TSharedPtr<FTUAccessToken> AccessToken = TapUELogin::GetAccessToken();
if (AccessToken.IsValid())
{
// 已登录,直接进入游戏
}
else
{
// 未登录
}
// 获取用户信息
// 注意:如果登录的权限没有 TUType::Profile,那么获取不到用户信息
TSharedPtr<FTULoginProfileModel> Profile = TapUELogin::GetProfile();
if (Profile.IsValid())
{
// 获取成功
}
else
{
// 获取失败
}
// 获取实时更新的用户信息
// 注意:如果登录的权限没有 TUType::Profile,那么获取不到用户信息
TapUELogin::FetchProfile([](TSharedPtr<FTULoginProfileModel> ModelPtr, const FTUError& Error) {
if (ModelPtr.IsValid())
{
// 请求成功
}
else
{
// 请求失败
}
});
登出
- Unity
- Android
- iOS
- UE4
TapLogin.Logout();
TapLoginHelper.logout();
[TapLoginHelper logout];
TapUELogin::Logout();
Unity PC 登录配置
Unity SDK 自 3.5.2 起支持在 Windows、macOS 下让玩家扫码或跳转网页浏览器完成 TapTap 登录。
SDK 默认支持扫码登录,跳转浏览器登录需要额外配置。
升级到内建账户系统
前面说过,如果前期开发时只把「TapTap 登录」作为一个第三方渠道进行了接入,后期要使用内建账户系统,或者老的 v1.x 版本的游戏要升级到 3.x 版本并使用其他服务,这时候会有「一定的开发成本」。这里我们就来具体说说这种情况下该如何处理。
首先按照前述初始化和一键完成 TapTap 登录的提示,完成内建账户系统的 TapTap 用户登录,这时候开发者可以得到一个 TDSUser 实例。
登录成功后获得当前授权用户的
Profile
信息。请注意,这里的Profile
信息和游戏之前得到的Profile
信息应该是完全一样的,游戏开发者应该可以据此找到游戏服务器上持久化保存的玩家信息,也可以将当前的 TDSUser 与原来的游戏玩家信息绑定在一起。对于游戏来说,最后是否需要将 TDSUser 与游戏内玩家账户进行绑定,是完全由开发者自己决定的:- 不绑定是可行的,因为 TapSDK 内部会缓存当前用户的登录状态,需要的时候总能得到之前登录的 TDS 账户;
- 绑定带来的好处则是使用上更加简单,同时也可以将 TDS 账户信息扩展到更多的第三方平台。