好友(含聊天)开发指南
本文介绍如何在游戏中加入好友&聊天系统。
集成前准备
- 参考 开发者中心配置 创建应用、配置包名与签名证书
- 参考集成指南(Unity、Android、iOS)完成对应平台或引擎的基础接入
- 好友模块依赖于 TapTap 登录模块,开发者接入前应先完成 TapTap 登录的接入
权限说明
- Android
- iOS
| 权限 | 使用目的 | 权限申请时机 |
|---|---|---|
| 网络权限 | 用于访问网络数据 | 用户 首次使用该功能时会申请权限 |
| 网络状态权限 | 用于检查网络连接状态(如 Wi-Fi 或移动数据是否可用) | 用户首次使用该功能时会申请权限 |
| 读取外部存储权限 | 用于读取设备上的文件和媒体内容 | 用户首次使用相关功能时会申请权限 |
| 写入外部存储权限 | 用于保存文件到设备存储 | 用户首次使用文件保存功能时会申请权限 |
| 管理外部存储权限 | 用于管理设备上的文件 | 用户首次使用文件管理功能时会申请权限 |
| 前台服务权限 | 用于在应用处于后台时保持某些功能运行 | 应用需要在后台运行服务时 |
| 相机权限 | 用于拍摄照片和视频通话 | 用户首次使用相机相关功能时会申请权限 |
| 振动权限 | 用于消息通知时的振动提醒 | 应用需要使用振动提醒时 |
该模块将在应用中添加如下权限:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.VIBRATE" />
| 权限 | 使用目的 | 权限申请时机 |
|---|---|---|
| 相册权限 | 用于获取相册图片或保存聊天图片到相册中 | 用户首次使用该功能时会申请权限 |
| 相机权限 | 用于拍照获取图片 | 用户首次使用该功能时会申请权限 |
SDK 获取
- Unity
- Android
- iOS
远程依赖
NPMJS 方式:在 Packages/manifest.json 中添加:
"dependencies":{
"com.taptap.sdk.core":"4.10.7",
"com.taptap.sdk.login":"4.10.7",
"com.taptap.sdk.relation":"4.10.7"
}
GitHub 方式:在 Packages/manifest.json 中添加:
"dependencies":{
"com.taptap.sdk.core":"https://github.com/taptap/tapsdk-unity-dist.git?path=/Core#4.10.7",
"com.taptap.sdk.login":"https://github.com/taptap/tapsdk-unity-dist.git?path=/Login#4.10.7",
"com.taptap.sdk.relation":"https://github.com/taptap/tapsdk-unity-dist.git?path=/Relation#4.10.7"
}
本地文件导入
在 下载页 下载并导入以下 unitypackage 文件:
TapSDK_Core.unitypackage(TapTapSDK 核心模块,必选)TapSDK_Login.unitypackage(TapTapSDK 登录模块,必选)TapSDK_Relation.unitypackage(TapTapSDK 好友模块,必选)
在 app module 的 build.gradle 中添加对应依赖:
dependencies {
implementation 'com.taptap.sdk:tap-core:4.10.7'
implementation 'com.taptap.sdk:tap-login:4.10.7'
implementation 'com.taptap.sdk:tap-relation:4.10.7'
}
远程依赖
- 在工程 Podfile 文件中对应模块下添加依赖:
pod 'TapTapSDK/Relation', '~> 4.10.7'
- 执行
Pod install下载对应依赖文件
本地文件依赖
好友模块依赖于初始化和 TapTap 登录模块,使用本地文件方式添加依赖时,需先参考集成指南 和 TapTap 登录添加对应本地文件依赖项。
- 在下载页下载如下文件:
TapTapRelationSDK好友依赖库TapTapRelationResource.bundle好友资源文件bifrost_sdk.xcframework基础库TapTapProfileSDK用户名片依赖库TapTapProfileResource.bundle用户名片资源文件TapTapKingfisher基础库
- 在工程中添加
framework静态库,注意添加时选择 Embed 方式为 Do Not Embed,导入bundle资源文件
iOS 工程配置
在 iOS 项目或通过 Unity 项目导出 Xcode 工程时,由于使用好友服务需要相册、相机权限,所以需配置对应权限使用说明,配置方式如下:
- Unity
- iOS
在 Assets/Plugins/iOS/Resource 目录下创建 TDS-Info.plist 文件 (如果已创建,只需添加内容即可),配置相关权限并替换授权文案:
<?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>NSPhotoLibraryUsageDescription</key>
<string>需要访问相册以选择或保存图片</string>
<key>NSCameraUsageDescription</key>
<string>需要使用相机拍摄照片</string>
</dict>
</plist>
开发者需在工程的 info.plist 配置相关权限并替换授权文案:
<key>NSPhotoLibraryUsageDescription</key>
<string>需要访问相册以选择或保存图片</string>
<key>NSCameraUsageDescription</key>
<string>需要使用相机拍摄照片</string>
外部唤起工程配置
为了让玩家能够通过邀请上线或邀请组队等消息唤起游戏,开发者需要在工程中添加如下配置:
- Unity
- Android
- iOS
请在 Assets/Plugins 目录下创建 TDS-Info.json 文件,并将 client_id 对应值替换为游戏的 Client ID:
{
"app": {
"client_id": "游戏 Client ID"
}
}
在应用的 AndroidManifest.xml 中添加如下配置,并将 tds{clientId} 中的 {clientId} 替换为游戏的 Client ID:
<activity
android:name="com.taptap.sdk.relation.TapRelationRouterActivity"
android:exported="true"
android:noHistory="true"
android:theme="@android:style/Theme.Translucent.NoTitleBar">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="tds{clientId}"
android:host="invite_game" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="tds{clientId}"
android:host="invite_team" />
</intent-filter>
</activity>
-
在 Xcode 工程的
Info.plist中添加 URL Scheme:tds{clientId},并将{clientId}替换为游戏的 Client ID。 -
在 openURL 回调中添加 SDK 处理
- Swift
- Objective-C
a) 如果项目中有
SceneDelegate.swift,请在该文件中添加如下代码:import TapTapRelationSDKfunc scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {for context in URLContexts {/// 是否被好友模块处理if TapTapRelation.open(url: context.url) {return}}}b) 如果项目中只有
AppDelegate.swift,请在该文件中添加如下代码:import TapTapRelationSDKfunc application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {return TapTapRelation.open(url: url)}func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {return TapTapRelation.open(url: url)}a) 如果项目中有
SceneDelegate.m,请在该文件中添加如下代码:#import <TapTapRelationSDK/TapTapRelationSDK-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) {/// 是否被好友模块处理if ([TapTapRelation openWithUrl:context.URL]) {return;}}}b) 如果项目中只有
AppDelegate.m,请在该文件中添加如下代码:#import <TapTapRelationSDK/TapTapRelationSDK-Swift.h>- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {return [TapTapRelation openWithUrl:url];}- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options {return [TapTapRelation openWithUrl:url];}
注册好友数据回调
好友聊天 SDK 中包含多个监听回调,分别会在未登录/有新增粉丝/有新增消息时被调用。
- Unity
- Android Java
- Android Kotlin
- iOS Swift
- iOS Objective-C
using TapSDK.Relation;
RelationCallback callback = new RelationCallback();
TapTapRelation.RegisterRelationCallback(callback);
TapTapRelation.UnregisterRelationCallback(callback);
class RelationCallback : ITapTapRelationCallback
{
public RelationCallback(){}
public void OnMessengerCodeResult(int code)
{
// 处理好友聊天的状态码
// code 400001 需要用户登录
}
public void OnNewFansCountChanged(int code, int newFansCount)
{
// 新增粉丝数量变化
// newFansCount 新增粉丝数
}
public void OnUnreadMessageCountChanged(int code, int unreadMsgCount)
{
// 新增未读消息数量变化
// unreadMsgCount 新增未读消息数
}
}
import com.taptap.sdk.relation.TapTapRelationCallback;
import com.taptap.sdk.relation.TapTapRelation;
import com.taptap.sdk.relation.TapTapRelationMessengerCode;
TapTapRelationCallback callback = new TapTapRelationCallback(){
@Override
public void onMessengerCodeResult(int code) {
// 处理好友聊天的状态码
// code 400001 需要用户登录
}
@Override
public void onNewFansCountChanged(int code, int fansCount) {
// 新增粉丝数量变动
}
@Override
public void onUnreadMessageCountChanged(int code, int unreadMsgCount) {
// 新增消息数量变动
}
};
TapTapRelation.registerRelationCallback(callback);
TapTapRelation.unregisterRelationCallback(callback);
import com.taptap.sdk.relation.TapTapRelationCallback
import com.taptap.sdk.relation.TapTapRelation
import com.taptap.sdk.relation.TapTapRelationMessengerCode
private val callback = object : TapTapRelationCallback {
override fun onMessengerCodeResult(code: Int) {
when (code) {
// 未登录
NEED_LOGIN -> {
}
}
}
override fun onNewFansCountChanged(code: Int, fansCount: Int) {
}
override fun onUnreadMessageCountChanged(code: Int, unreadMsgCount: Int) {
}
}
TapTapRelation.registerRelationCallback(callback = callback)
TapTapRelation.unregisterRelationCallback(callback = callback)
import TapTapRelationSDK
class MyRelationDelegate: NSObject, TapTapRelationDelegate {
func onMessengerCodeResult(code: Int) {
// 处理好友聊天的状态码
// code 400001 需要用户登录
}
func onNewFansCountChanged(code: Int, fansCount: Int) {
// 新增粉丝数量变动
}
func onUnreadMessageCountChanged(code: Int, unreadMsgCount: Int) {
// 新增消息数量变动
}
}
let myRelationDelegate = MyRelationDelegate()
// 注册回调
TapTapRelation.registerRelationDelegate(delegate: myRelationDelegate)
// 移除回调
TapTapRelation.unregisterRelationDelegate(delegate: myRelationDelegate)
#import "TapTapRelationSDK/TapTapRelationSDK-Swift.h"
@interface GameMainController() <TapTapRelationDelegate>
@end
@implementation GameMainController
- (void) handleRelationDelegate {
// 注册好友回调
[TapTapRelation registerRelationDelegateWithDelegate:self];
// 移除好友回调
[TapTapRelation unregisterRelationDelegateWithDelegate:self];
}
- (void)onMessengerCodeResultWithCode:(NSInteger)code {
// 处理好友聊天的状态码
// code 400001 需要用户登录
}
- (void)onNewFansCountChangedWithCode:(NSInteger)code fansCount:(NSInteger)fansCount {
// 新增粉丝数量变动
}
- (void)onUnreadMessageCountChangedWithCode:(NSInteger)code unreadMsgCount:(NSInteger)unreadMsgCount {
// 新增消息数量变动
}
注册邀请回调
当玩家点击 TapTap 邀请消息并打开游戏时,SDK 会解析邀请信息,开发者可通过注册该回调获取发起邀请的用户和组队信息。示例如下:
- Unity
- Android Java
- Android Kotlin
- iOS Swift
- iOS Objective-C
using System;
using TapSDK.Relation;
class DemoRelationInviteCallback : ITapTapRelationInviteCallback
{
private Action<string> callback;
public DemoRelationInviteCallback(Action<string> callback)
{
this.callback = callback;
}
public void OnGameInviteReceived(string openId, string unionId)
{
callback($"收到邀请上线: openId={openId}, unionId={unionId}");
}
public void OnTeamInviteReceived(string openId, string unionId, string teamId)
{
callback($"收到邀请组队: openId={openId}, unionId={unionId}, teamId={teamId}");
}
}
var inviteCallback = new DemoRelationInviteCallback(msg =>
{
Debug.Log(msg);
});
TapTapRelation.RegisterRelationInviteCallback(inviteCallback);
TapTapRelation.UnregisterRelationInviteCallback(inviteCallback);
import android.util.Log;
import androidx.annotation.NonNull;
import com.taptap.sdk.relation.TapTapRelation;
import com.taptap.sdk.relation.TapTapRelationInviteCallback;
TapTapRelationInviteCallback inviteCallback = new TapTapRelationInviteCallback() {
@Override
public void onGameInviteReceived(@NonNull String openId, @NonNull String unionId) {
Log.d("Relation", "收到邀请上线: openId = " + openId + " unionId = " + unionId);
}
@Override
public void onTeamInviteReceived(@NonNull String openId, @NonNull String unionId, @NonNull String teamId) {
Log.d("Relation", "收到邀请组队: openId = " + openId + " unionId = " + unionId + " teamId = " + teamId);
}
};
TapTapRelation.registerRelationInviteCallback(inviteCallback);
TapTapRelation.unregisterRelationInviteCallback(inviteCallback);
import android.util.Log
import com.taptap.sdk.relation.TapTapRelation
import com.taptap.sdk.relation.TapTapRelationInviteCallback
private val inviteCallback = object : TapTapRelationInviteCallback {
override fun onGameInviteReceived(openId: String, unionId: String) {
Log.d("Relation", "收到邀请上线: openId=$openId, unionId=$unionId")
}
override fun onTeamInviteReceived(openId: String, unionId: String, teamId: String) {
Log.d("Relation", "收到组队邀请: openId=$openId, unionId=$unionId, teamId=$teamId")
}
}
TapTapRelation.registerRelationInviteCallback(inviteCallback)
TapTapRelation.unregisterRelationInviteCallback(inviteCallback)
import TapTapRelationSDK
class InviteCallback: NSObject, TapTapRelationInviteDelegate {
func onGameInviteReceived(openId: String, unionId: String) {
NSLog("收到邀请上线 openId = \(openId) unionId = \(unionId)")
}
func onTeamInviteReceived(openId: String, unionId: String, teamId: String) {
NSLog("收到组队邀请 openId = \(openId) unionId = \(unionId) teamId = \(teamId)")
}
}
let inviteDelegate = InviteCallback()
TapTapRelation.registerRelationInviteDelegate(delegate: inviteDelegate)
TapTapRelation.unregisterRelationInviteDelegate(delegate: inviteDelegate)
#import "TapTapRelationSDK/TapTapRelationSDK-Swift.h"
@interface TapSDKInviteCallback : NSObject <TapTapRelationInviteDelegate>
@end
@implementation TapSDKInviteCallback
- (void)onGameInviteReceivedWithOpenId:(NSString *)openId unionId:(NSString *)unionId {
NSLog(@"收到邀请上线: openId = %@, unionId = %@", openId, unionId);
}
- (void)onTeamInviteReceivedWithOpenId:(NSString *)openId unionId:(NSString *)unionId teamId:(NSString *)teamId {
NSLog(@"收到组队邀请 openId = %@, unionId = %@, teamId = %@", openId, unionId, teamId);
}
@end
TapSDKInviteCallback *inviteCallback = [TapSDKInviteCallback new];
[TapTapRelation registerRelationInviteDelegateWithDelegate:inviteCallback];
[TapTapRelation unregisterRelationInviteDelegateWithDelegate:inviteCallback];
准备阶段
进入聊天之前的一些准备工作。
注意:【好友实时消息/获取新增未读消息数/获取新增粉丝数】需要在调用 prepare 之后才可生效。
- Unity
- Android Java
- Android Kotlin
- iOS Swift
- iOS Objective-C
using TapSDK.Relation;
TapTapRelation.Prepare();
import com.taptap.sdk.relation.TapTapRelation;
TapTapRelation.prepare();
import com.taptap.sdk.relation.TapTapRelation
TapTapRelation.prepare()
import TapTapRelationSDK
TapTapRelation.prepare()
#import "TapTapRelationSDK/TapTapRelationSDK-Swift.h"
[TapTapRelation prepare];
开始聊天
打开聊天页面,根据初始化参数 screenOrientation 会有不同的动画表现。
- Unity
- Android Java
- Android Kotlin
- iOS Swift
- iOS Objective-C
using TapSDK.Relation;
TapTapRelation.StartMessenger();
import com.taptap.sdk.relation.TapTapRelation;
TapTapRelation.startMessenger();
import com.taptap.sdk.relation.TapTapRelation
TapTapRelation.startMessenger()
import TapTapRelationSDK
TapTapRelation.startMessenger()
#import "TapTapRelationSDK/TapTapRelationSDK-Swift.h"
[TapTapRelation startMessenger];
邀请好友上线
打开邀请好友页面,向选中好友发送邀请上线消息。
- Unity
- Android Java
- Android Kotlin
- iOS Swift
- iOS Objective-C
using TapSDK.Relation;
TapTapRelation.InviteGame();
import com.taptap.sdk.relation.TapTapRelation;
TapTapRelation.inviteGame();
import com.taptap.sdk.relation.TapTapRelation
TapTapRelation.inviteGame()
import TapTapRelationSDK
TapTapRelation.inviteGame()
#import "TapTapRelationSDK/TapTapRelationSDK-Swift.h"
[TapTapRelation inviteGame];
邀请好友组队
打开邀请好友页面,向选中好友发送邀请组队消息,需要传组队相关参数teamId。
- Unity
- Android Java
- Android Kotlin
- iOS Swift
- iOS Objective-C
using TapSDK.Relation;
string teamId = "";
TapTapRelation.InviteTeam(teamId);
import com.taptap.sdk.relation.TapTapRelation;
String teamId = "";
TapTapRelation.inviteTeam(teamId);
import com.taptap.sdk.relation.TapTapRelation
val teamId = ""
TapTapRelation.inviteTeam(teamId = teamId)
import TapTapRelationSDK
let teamId = ""
TapTapRelation.inviteTeam(teamId)
#import "TapTapRelationSDK/TapTapRelationSDK-Swift.h"
NSString * teamId = @"";
[TapTapRelation inviteTeam:teamId];
获取新增粉丝数
获取当前用户新增粉丝的数量,也可在callback中处理。
- Unity
- Android Java
- Android Kotlin
- iOS Swift
- iOS Objective-C
using TapSDK.Relation;
TapTapRelation.GetNewFansCount((count) =>
{
Log($"新粉丝数量: {count}");
});
import com.taptap.sdk.relation.TapTapRelation;
int fansCount = TapTapRelation.getNewFansCount();
import com.taptap.sdk.relation.TapTapRelation
val fansCount = TapTapRelation.getNewFansCount()
import TapTapRelationSDK
let fansCount = TapTapRelation.getNewFansCount()
#import "TapTapRelationSDK/TapTapRelationSDK-Swift.h"
NSInteger fansCount = [TapTapRelation getNewFansCount];
获取新增消息数
获取当前用户新增消息的数量,也可在callback中处理。
- Unity
- Android Java
- Android Kotlin
- iOS Swift
- iOS Objective-C
using TapSDK.Relation;
TapTapRelation.GetUnreadMessageCount((count) =>
{
Log($"未读消息数量: {count}");
});
import com.taptap.sdk.relation.TapTapRelation;
int unreadMessageCount = TapTapRelation.getUnreadMessageCount();
import com.taptap.sdk.relation.TapTapRelation
val unreadMessageCount = TapTapRelation.getUnreadMessageCount()
import TapTapRelationSDK
let unreadMessageCount = TapTapRelation.getUnreadMessageCount()
#import "TapTapRelationSDK/TapTapRelationSDK-Swift.h"
NSInteger unreadMessageCount = [TapTapRelation getUnreadMessageCount];
展示 TapTap 用户名片
展示指定用户的名片弹窗,可用于关注/取关用户,传入用户的openId或者unionId。
- Unity
- Android Java
- Android Kotlin
- iOS Swift
- iOS Objective-C
using TapSDK.Relation;
string openId = "";
string unionId = "";
TapTapRelation.ShowTapUserProfile(openId, unionId);
import com.taptap.sdk.relation.TapTapRelation;
// openId unionId二选一即可
String openId = "";
String unionId = "";
TapTapRelation.showTapUserProfile(openId, unionId);
import com.taptap.sdk.relation.TapTapRelation
// openId unionId二选一即可
val openId = "";
val unionId = "";
TapTapRelation.showTapUserProfile(openId = openId, unionId = unionId)
import TapTapRelationSDK
let openId = ""
let unionId = ""
// openId unionId二选一即可
TapTapRelation.showTapUserProfile(openId: openId)
TapTapRelation.showTapUserProfile(unionId: unionId)
#import "TapTapRelationSDK/TapTapRelationSDK-Swift.h"
// openId unionId二选一即可
NSString * openId = @"";
NSString * unionId = @"";
[TapTapRelation showTapUserProfileWithOpenId:openId unionId:unionId];