好友模式
阅读本文前请先完成 SDK 初始化。
好友通知设置
好友模块默认会向游戏推送好友状态及申请的通知,如果游戏需要关闭,可调用如下接口:
- Unity
- Android
- iOS
try {
await TDSFriends.DisableFriendNotification();
TapLog("关闭推送通知成功");
} catch (Exception e) {
TapLog($"关闭推送通知失败: ${e}");
}
TDSFriends.disableFriendNotification(new Callback<Void>() {
@Override
public void onSuccess(Void result) {
toast("消息推送关闭成功");
}
@Override
public void onFail(TDSFriendError error) {
toast("消息推送关闭失败 " + error.detailMessage);
}
});
void (^callback)(BOOL succeeded, NSError * error) = ^(BOOL succeeded, NSError * _Nullable error){
if (succeeded) {
[LogHelper log:LogInfoTypeDisplay :[NSString stringWithFormat:@"设置成功"]];
} else {
[LogHelper log:LogInfoTypeError :[NSString stringWithFormat:@"设置失败"]];
}
};
[TDSFriends disableFriendNotificationWithCallback:callback];
当关闭通知后,如果需要再次开启,可调用如下接口:
- Unity
- Android
- iOS
try {
await TDSFriends.EnableFriendNotification();
TapLog("开启推送通知成功");
} catch (Exception e) {
TapLog($"开启推送通知失败: ${e}");
}
TDSFriends.enableFriendNotification(new Callback<Void>() {
@Override
public void onSuccess(Void result) {
toast("消息推送关闭成功");
}
@Override
public void onFail(TDSFriendError error) {
toast("消息推送关闭失败 " + error.detailMessage);
}
});
void (^callback)(BOOL succeeded, NSError * error) = ^(BOOL succeeded, NSError * _Nullable error){
if (succeeded) {
[LogHelper log:LogInfoTypeDisplay :[NSString stringWithFormat:@"设置成功"]];
} else {
[LogHelper log:LogInfoTypeError :[NSString stringWithFormat:@"设置失败"]];
}
};
[TDSFriends enableFriendNotificationWithCallback:callback];
响应好友变化通知
好友模块支持客户端监听好友状态变化,在游戏中实时给玩家提示。 你需要在调用上线接口前注册好友状态变更监听实例,这样,玩家上线后就能收到相应通知:
- Unity
- Android
- iOS
TDSFriends.FriendStatusChangedDelegate = new TDSFriendStatusChangedDelegate {
// 新增好友(触发时机同「已发送的好友申请被接受」)
OnFriendAdd = friendInfo => {},
// 新增好友申请
OnNewRequestComing = req => {},
// 已发送的好友申请被接受
OnRequestAccepted = req => {},
// 已发送的好友申请被拒绝
OnRequestDeclined = req => {},
// 好友上线
OnFriendOnline = userId => {},
// 好友下线
OnFriendOffline = userId => {},
// 好友富信息变更
OnRichPresenceChanged = (userId, richPresence) => {},
// 当前玩家成功上线(长连接建立成功)
OnConnected = () => {},
// 当前玩家长连接断开,SDK 会自动重试,开发者通常无需额外处理
OnDisconnected = () => {},
// 当前连接异常
OnConnectionError = (code, message) => {},
};
TDSFriends.registerFriendStatusChangedListener(new FriendStatusChangedListener() {
// 新增好友(触发时机同「已发送的好友申请被接受」)
@Override
public void onFriendAdd(TDSFriendInfo friendInfo) {}
// 新增好友申请
@Override
public void onNewRequestComing(TDSFriendshipRequest request) {}
// 通过分享链接进入游戏时触发此回调
// 开发者可以在此回调中直接调用 handFriendInvitationLink
// 或通过 parseFriendInvitationLink 解析链接,获取相关参数再执行自定义的逻辑
@Override
public void onReceivedInvitationLink(String url) {}
// 已发送的好友申请被接受
@Override
public void onRequestAccepted(TDSFriendshipRequest request) {}
// 已发送的好友申请被拒绝
@Override
public void onRequestDeclined(TDSFriendshipRequest request) {}
// 好友上线
@Override
public void onFriendOnline(String userId) {}
// 好友下线
@Override
public void onFriendOffline(String userId) {}
// 好友富信息变更
@Override
public void onRichPresenceChanged(String userId, TDSRichPresence richPresence) {}
// 当前玩家成功上线(长连接建立成功)
@Override
public void onConnected() {}
// 当前玩家长连接断开,SDK 会自动重试,开发者通常无需额外处理
@Override
public void onDisconnected() {}
// 当前连接异常
@Override
public void onConnectError(int code, String msg){});
}
[TDSFriends registerNotificationDelegate:self];
// 新增好友(触发时机同「已发送的好友申请被接受」)
- (void)onFriendAdd:(TDSFriendInfo *)info {}
// 新增好友申请
- (void)onNewRequestComing:(TDSFriendshipRequest *)request {}
// 已发送的好友申请被接受
- (void)onRequestAccepted:(TDSFriendshipRequest *)request {}
// 已发送的好友申请被拒绝
- (void)onRequestDeclined:(TDSFriendshipRequest *)request {}
// 好友上线
- (void)onFriendOnline:(NSString *)userId {}
// 好友下线
- (void)onFriendOffline:(NSString *)userId {}
// 好友富信息变更
- (void)onRichPresenceChanged:(NSString *)userId dictionary:(NSDictionary * _Nullable)dictionary {}
// 当前玩家成功上线(长连接建立成功)
- (void)onConnected {}
// 当前玩家长连接断开,SDK 会自动重试,开发者通常无需额外处理
- (void)onDisconnected {}
// 当前连接异常
- (void)onDisconnectedWithError:(NSError * _Nullable)error {}
上述事件中的「好友」,均指「好友模式」下的「好友」。 目前 SDK 暂不支持监听关注模式下的事件。
如果想要停止监听:
- Unity
- Android
- iOS
TDSFriends.FriendStatusChangedDelegate = null;
TDSFriends.removeFriendStatusChangedListener();
[TDSFriends unregisterNotificationDelegate];
玩家上线
玩家成功登录后,需要调用该接口建立和好友服务云端的长连接。 长连接建立后,如果网络临时中断,SDK 会在网络恢复后自动重连。
- Unity
- Android
- iOS
await TDSFriends.Online();
TDSFriends.online(new Callback<Void>() {
@Override
public void onSuccess(Void result) {
// 成功
}
@Override
public void onFail(TDSFriendError error) {
// 处理异常
}
});
建立长连接后,如果玩家通过好友邀请链接打开游戏,那么 Android SDK 也会自动发送对应的好友申请。
[TDSFriends online];
玩家下线
玩家登出后,需要调用此接口断开和云端的长连接。
- Unity
- Android
- iOS
await TDSFriends.Offline();
TDSFriends.offline();
[TDSFriends offline];
根据昵称查询好友
在不知道玩家 objectId 的情况下,可以通过玩家昵称查询好友。
例如,搜索昵称为 Tarara
的好友:
- Unity
- Android
- iOS
ReadOnlyCollection<TDSFriendInfo> friendInfos = await TDSFriends.SearchUserByName("Tarara");
foreach (TDSFriendInfo info in friendInfos) {
// 玩家信息
TDSUser user = info.User;
// 富信息数据,详见后文
Dictionary<string, string> richPresence = info.RichPresence;
// 好友是否在线
bool online = info.Online;
}
TDSFriends.searchUserByName("Tarara", new ListCallback<TDSFriendInfo>() {
@Override
public void onSuccess(List<TDSFriendInfo> friendInfoList) {
for (TDSFriendInfo info : friendInfoList) {
// 玩家信息
TDSUser user = info.getUser();
// 富信息数据,详见后文
TDSRichPresence richPresence = info.getRichPresence();
// 好友是否在线
boolean online = info.isOnline();
}
}
@Override
public void onFail(TDSFriendError error) {
toast("Failed search friend by nickname" + error.detailMessage);
}
});
TDSFriendQueryOption *option = [TDSFriendQueryOption new];
option.from = 0;
option.limit = 100;
[TDSFriends searchUserWithNickname:@"Tarara" option:option
callback:^(NSArray<TDSFriendInfo *> * _Nullable friendInfos, NSError * _Nullable error) {
if (friendInfos) {
for (TDSFriendInfo *info in friendInfos) {
// 玩家信息
TDSUser *user = info.user;
// 富信息数据,详见后文
NSDictionary *richPresence = info.richPresence;
// 好友是否在线
BOOL online = info.online;
}
} else if (error) {
// 处理错误
}
}];
注意,使用这一功能的前提是内建账户系统中设置了 nickname
(昵称)字段。
参见内建账户系统文档。
好友码
每个已登录玩家都有一个好友码,可以分享给其他玩家用于添加好友。
访问 TDSUser
的 shortId
属性可获取好友码:
- Unity
- Android
- iOS
// currentUser 是已登录的 TDSUser
string shortId = currentUser["shortId"];
String shortId = currentUser.getString("shortId");
NSString *shortId = currentUser[@"shortId"];
可以通过好友码查询玩家:
- Unity
- Android
- iOS
TDSFriendInfo friendInfo = await TDSFriends.SearchUserByShortCode(shortId);
TDSFriends.searchUserByShortCode(shortId, new Callback<TDSFriendInfo>() {
@Override
public void onSuccess(TDSFriendInfo friendInfo) { /* 略(参见上节) */ }
@Override
public void onFail(TDSFriendError error) { /* 略(参见上节) */ }
});
[TDSFriends searchUserWithShortCode:shortId
callback:^(TDSFriendInfo * _Nullable friendInfo, NSError * _Nullable error) {
// 略(参见上节)
}];
根据 objectId 查询好友
除了昵称、好友码外,还可以根据 objectId 查找好友。
查询 objectId 为 5b0b97cf06f4fd0abc0abe35
的好友:
- Unity
- Android
- iOS
TDSFriendInfo friendInfo = await TDSFriends.SearchUserById("5b0b97cf06f4fd0abc0abe35");
TDSFriends.searchUserById("5b0b97cf06f4fd0abc0abe35", new Callback<TDSFriendInfo>() {
@Override
public void onSuccess(TDSFriendInfo tdsFriendInfo) {
/* 略(参见上节) */
}
@Override
public void onFail(TDSFriendError tdsFriendError) {
/* 略(参见上节) */
}
});
[TDSFriends searchUserWithObjectId:@"5b0b97cf06f4fd0abc0abe35"
callback:^(TDSFriendInfo * _Nullable friendInfo, NSError * _Nullable error) {
// 略(参见上节)
}];
富信息
富信息用于呈现玩家状态等信息,如在线状态、正在使用哪个英雄、正处于哪个游戏模式等。
在控制台添加富信息相关配置后,可以根据已配置的富信息字段,设置对应的富信息内容:
- Unity
- Android
- iOS
await TDSFriends.SetRichPresence("score", "60");
TDSFriends.setRichPresence("score", "60", new Callback<Void>() {
@Override
public void onSuccess(Void result) {
toast("Succeed to set rich presence.");
}
@Override
public void onFail(TDSFriendError error) {
toast("Failed to set rich presence: " + error.detailMessage);
}
});
[TDSFriends setRichPresenceWithKey:@"score" value:@"60"
callback:^(BOOL succeeded, NSError * _Nullable error) {
if (succeeded) {
// Succeed to set rich presence.
} else if (error) {
// Failed to set rich presence.
}
}];
这里 score
是在控制台配置的富信息字段。
富信息的字段有两种类型:
variable
类型,值是字符串。例如,之前的代码实例中,score
在控制台配置为variable
类型,因此客户端设置富信息字段的值时填了60
,云端返回给客户端的富信息为"score": "60"
,在游戏界面该玩家的好友会看到当前玩家的富信息显示为「得分 60」之类。这里,开发者需要自行实现将score
显示为「得分」等本地化内容的逻辑。token
类型,值是以#
开头的字符串。例如,下面的代码实例中display
字段的类型是token
,客户端设置富信息字段的值时填了#matching
,这个值在云端会进行多语言匹配,返回给客户端的富信息会直接替换为本地化的内容:"display": "匹配中"
。注意,如果多语言匹配失败则会返回空字符串("display": " "
)。
需要一次性配置多个字段时,可以传入一组字段:
- Unity
- Android
- iOS
Dictionary<string, string> info = new Dictionary<string, string>();
info.Add("score", "60");
info.Add("display", "#matching");
await TDSFriends.SetRichPresences(info);
Map<String,String> info = new HashMap<>();
info.put("score", "60");
info.put("display", "#matching");
TDSFriends.setRichPresence(info, new Callback<Void>() {
// 略
});
[TDSFriends setRichPresencesWithDictionary:@{
@"score" : @"60",
@"display" : @"#matching",
} callback:^(BOOL succeeded, NSError * _Nullable error) {
// 略
}];
控制台最多配置 20 个富信息字段,字段名(key)长度不超过 128 bytes,字段值(value)长度不超过 256 bytes。
如需清除当前玩家的某项富信息,可以调用以下接口:
- Unity
- Android
- iOS
TDSFriends.ClearRichPresence("score");
TDSFriends.clearRichPresence("score", new Callback<Void>() {
// 略
});
[TDSFriends clearRichPresenceWithKey:@"score"
callback:^(BOOL succeeded, NSError * _Nullable error) {
// 略
}];
同样,可以批量清除一组富信息:
- Unity
- Android
- iOS
IEnumerable<string> keys = new string[] {"score", "display"}
await TDSFriends.ClearRichPresences(keys);
List<String> keys = new ArrayList<>();
keys.add("score");
keys.add("display");
TDSFriends.clearRichPresence(keys, new Callback<Void>() {
// 略
});
[TDSFriends clearRichPresencesWithKeys:@[@"score", @"display"]
callback:^(BOOL succeeded, NSError * _Nullable error) {
// 略
});
设置和清除富信息接口有调用频率限制,每 30s 最多各触发一次。
富信息提供了 REST API 接口。 开发者可以自行编写程序或脚本调用这些接口在服务端进行管理性质的操作。
添加好友
可以通过指定好友码添加相应玩家为好友。
- Unity
- Android
- iOS
await TDSFriends.AddFriendByShortCode(shortId);
TDSFriends.addFriendByShortCode(shortId, null, new Callback<Void>() {
@Override
public void onSuccess(Void result) {
toast("Applied or added.");
}
@Override
public void onFail(TDSFriendError error) {
toast("Failed to add a friend: " + error.detailMessage);
}
});
[TDSFriends addFriendWithShortCode:shortId callback:^(BOOL succeeded, NSError * _Nullable error) {
if (succeeded) {
// Applied or added.
} else if (error) {
// Failed to add a friend.
}
}];
如果当前玩家已经在对方的好友列表中,那么对方会直接成为当前玩家的好友。 否则,会向对方发送好友申请。
添加好友时可以指定额外的属性,例如,将对方放入 coworkers
(同事)分组:
- Unity
- Android
- iOS
Dictionary<string, object> attrs = new Dictionary<string, object> {
{ "group", "coworkers" }
};
await TDSFriends.AddFriendByShortCode(shortId, attrs);
Map<String, Object> attrs = new HashMap<String, Object>();
attrs.put("group", "coworkers");
TDSFriends.addFriendByShortCode(shortId, attrs, new Callback<Boolean>() {
// 略(参见上面的例子)
});
NSDictionary *attributes = @{
@"group" : @"coworkers",
};
[TDSFriends addFriendWithShortCode:shortId attributes:attributes
callback:^(BOOL succeeded, NSError * _Nullable error) {
// 略(参见上面的例子)
}];
此外,也可以通过指定某个 TDSUser
的 objectId
来添加他为好友。
比如,假设 Tarara 的 objectId
是 5b0b97cf06f4fd0abc0abe35
,可以通过以下代码添加她为好友:
- Unity
- Android
- iOS
await TDSFriends.AddFriend("5b0b97cf06f4fd0abc0abe35");
TDSFriends.addFriend("5b0b97cf06f4fd0abc0abe35", new Callback<Void>() {
// 略(参见上面的例子)
});
[TDSFriends addFriendWithUserId:@"5b0b97cf06f4fd0abc0abe35"
callback:^(BOOL succeeded, NSError * _Nullable error) {
// 略(参见上面的例子)
}];
通过 objectId
添加好友同样可以指定额外属性:
- Unity
- Android
- iOS
Dictionary<string, object> attrs = new Dictionary<string, object> {
{ "group", "coworkers" }
};
await TDSFriends.AddFriend("5b0b97cf06f4fd0abc0abe35", attrs);
Map<String, Object> attrs = new HashMap<String, Object>();
attrs.put("group", "coworkers");
TDSFriends.addFriend("5b0b97cf06f4fd0abc0abe35", attrs, new Callback<Void>() {
// 略(参见上面的例子)
});
NSDictionary *attributes = @{
@"group" : @"coworkers",
};
[TDSFriends addFriendWithUserId:@"5b0b97cf06f4fd0abc0abe35" attributes:attributes callback:^(BOOL succeeded, NSError * _Nullable error) {
// 略(参见上面的例子)
}];
删除好友
成为好友的两个玩家,之后也可以单方面删除好友。 例如,和 Tarara 成为好友后,当前玩家又改变主意,不想和 Tarara 做朋友了:
- Unity
- Android
- iOS
await TDSFriends.DeleteFriend("5b0b97cf06f4fd0abc0abe35");
TDSFriends.deleteFriend("5b0b97cf06f4fd0abc0abe35", new Callback<Boolean>() {
@Override
public void onSuccess(Boolean ok) {
toast("Deleted.");
}
@Override
public void onFail(TDSFriendError error) {
toast("Failed to delete a friend: " + error.detailMessage);
}
});
[TDSFriends deleteFriendWithUserId:@"5b0b97cf06f4fd0abc0abe35" callback:^(BOOL succeeded, NSError * _Nullable error) {
if (succeeded) {
// Deleted.
} else if (error) {
// Failed to delete a friend.
}
}];
拉黑
添加黑名单用户
将用户加入黑名单,无论双方是否是好友,都可以进行该操作。拉黑后,双方之间进行中的好友申请都会被删除,且双方无法再发起以及接受对方的好友申请。查询好友列表时也无法查到已在黑名单中的好友,黑名单用户最多 100 人。
假设 Tarara 的 objectId 是 5b0b97cf06f4fd0abc0abe35
,可以这样将 Tarara 加到黑名单:
- Unity
- Android
- iOS
await TDSFriends.BlockFriend("5b0b97cf06f4fd0abc0abe35");
TDSFriends.blockFriend("5b0b97cf06f4fd0abc0abe35", new Callback<Void>(){
@Override
public void onSuccess(Void result) {
// block user succeed.
}
@Override
public void onFail(TDSFriendError error) {
// Failed to block.
}
});
[TDSFriends blockFriendWithUserId:@"5b0b97cf06f4fd0abc0abe35" callback:^(BOOL succeeded, NSError * _Nullable error) {
if (succeeded) {
// block user succeed.
} else if (error) {
// Failed to block.
}
}];
移除黑名单用户
从黑名单移除用户,如果目标用户曾经是当前用户的好友,则恢复进入当前用户好友列表。
- Unity
- Android
- iOS
await TDSFriends.UnblockFriend("5b0b97cf06f4fd0abc0abe35");
TDSFriends.unblockFriend("5b0b97cf06f4fd0abc0abe35", new Callback<Void>() {
@Override
public void onSuccess(Void result) {
// unblock succeed.
}
@Override
public void onFail(TDSFriendError error) {
// Failed to unblock.
}
});
[TDSFriends unblockFriendWithUserId:@"5b0b97cf06f4fd0abc0abe35" callback:^(BOOL succeeded, NSError * _Nullable error) {
if (succeeded) {
// unblock succeed.
} else if (error) {
// Failed to unblock.
}
}];
查询黑名单列表
分页查询黑名单用户列表。
- Unity
- Android
- iOS
var from = 0;
var limit = 100;
ReadOnlyCollection<TDSFriendInfo> friendInfos = await TDSFriends.QueryBlockList(from, limit);
foreach (TDSFriendInfo info in friendInfos) {
// 玩家信息
TDSUser user = info.User;
// 富信息数据
Dictionary<string, string> richPresence = info.RichPresence;
// 好友是否在线
bool online = info.Online;
}
其中:
from
为获取列表的起始位置,第一页为 0,下一页为上一次获取数据的总数量。limit
为每页获取数据的数量。
TDSFriends.queryBlockList(0, 10, new ListCallback<TDSFriendInfo>() {
@Override
public void onSuccess(List<TDSFriendInfo> result) {
System.out.println("query blockList data, data = " + result);
}
@Override
public void onFail(TDSFriendError error) {
System.out.println("query blockList failed, error = " + error);
}
});
其中:
from
为获取列表的起始位置,第一页为 0,下一页为上一次获取数据的总数量。limit
为每页获取数据的数量。callback
为异步处理回调,包含黑名单用户列表的数据信息。
TDSFriendQueryOption *option = [TDSFriendQueryOption new];
option.from = 0;
option.limit = 100;
[TDSFriends queryBlockListWithOption:option
callback:^(NSArray<TDSFriendInfo *> * _Nullable friendInfos, NSError * _Nullable error) {
if (friendInfos) {
for (TDSFriendInfo *info in friendInfos) {
// 玩家信息
TDSUser *user = info.user;
// 富信息数据
NSDictionary *richPresence = info.richPresence;
// 好友是否在线
BOOL online = info.online;
}
} else if (error) {
// 处理错误
}
}];
其中:
option
为查询时的条件配置,包括:from
每页的开始位置;limit
查询数据数量。callback
为异步处理结果回调。
查询好友申请列表
好友申请有三种状态:
pending
,对方没有回应,还处于等待中。好友申请创建之后默认是此状态。accepted
,对方已经接受,现在双方成为好友。declined
,对方已经拒绝。
SDK 提供了查询好友申请的接口。
例如,查询处于 pending
状态的前 20 条申请:
- Unity
- Android
- iOS
var from = 0;
var limit = 100;
ReadOnlyCollection<LCFriendshipRequest> requests = await TDSFriends.QueryFriendRequestList (
LCFriendshipRequest.STATUS_PENDING, from, limit
);
LCFriendshipRequest.STATUS_PENDING
即表示好友申请状态为 pending
。
类似地,LCFriendshipRequest.STATUS_ACCEPTED
和 LCFriendshipRequest.STATUS_DECLINED
分别表示好友申请状态为 accepted
和 declined
。
LCFriendshipRequest.STATUS_ANY
则表示任意状态。
int from = 0;
int limit = 100;
TDSFriends.queryFriendRequestList(LCFriendshipRequest.STATUS_PENDING, from, limit,
new ListCallback<LCFriendshipRequest>(){
@Override
public void onSuccess(List<LCFriendshipRequest> requests) {
// requests 就是处于 pending 状态中的好友申请列表
}
@Override
public void onFail(TDSFriendError error) {
toast("Failed to query friendship requests: " + error.detailMessage);
}
});
上述代码示例中的 LCFriendshipRequest.STATUS_PENDING
即表示好友申请状态为 pending
。
类似地,LCFriendshipRequest.STATUS_ACCEPTED
和 LCFriendshipRequest.STATUS_DECLINED
分别表示好友申请状态为 accepted
和 declined
。
LCFriendshipRequest.STATUS_ANY
则表示任意状态。
TDSFriendQueryOption *option = [TDSFriendQueryOption new];
option.from = 0;
option.limit = 100;
[TDSFriends queryFriendRequestWithStatus:TDSUserFriendshipRequestStatusPending
option:option
callback:^(NSArray<LCFriendshipRequest *> * _Nullable requests, NSError * _Nullable error) {
// requests 就是处于 pending 状态中的好友申请列表
}];
上述代码示例中的 TDSUserFriendshipRequestStatusPending
即表示好友申请状态为 pending
。
类似地,TDSUserFriendshipRequestStatusAccepted
和 TDSUserFriendshipRequestStatusDeclined
分别表示好友申请状态为 accepted
和 declined
。
TDSUserFriendshipRequestStatusAny
则表示任意状态。
如果希望返回结果中携带好友申请发起人的富信息,那么可以使用以下接口:
- Unity
- Android
- iOS
ReadOnlyCollection<TDSFriendshipRequest> requests = await TDSFriends.QueryFriendRequestWithFriendStateList (
LCFriendshipRequest.STATUS_PENDING, from, limit
);
foreach (TDSFriendshipRequest request in requests) {
// 好友申请(参见 QueryFriendRequestList)
LCFriendshipRequest req = request.FriendshipRequest;
// 申请发起人的富信息
TDSFriendInfo info = request.FriendInfo;
}
TDSFriends.queryFriendRequestWithFriendStateList(LCFriendshipRequest.STATUS_PENDING,
from, limit, new ListCallback<TDSFriendshipRequest>() {
@Override
public void onSuccess(List<TDSFriendshipRequest> requests) {
for (TDSFriendshipRequest request : requests) {
// 好友申请(参见 queryFriendRequestList)
LCFriendshipRequest req = request.getLcFriendshipRequest();
// 申请发起人的富信息
TDSFriendInfo info = request.getFriendInfo();
}
}
@Override
public void onFail(TDSFriendError error) {
// 处理错误
}
});
TDSFriendQueryOption *option = [TDSFriendQueryOption new];
option.from = 0;
option.limit = 100;
[TDSFriends queryFriendRequestAndStateWithStatus:TDSUserFriendshipRequestStatusPending
option:option
callback:^(NSArray<TDSFriendshipRequest *> * _Nullable requests, NSError * _Nullable error) {
for (TDSFriendshipRequest *request in requests) {
// 好友申请(参见 queryFriendRequestWithStatus)
LCFriendshipRequest *req = request.lcFriendshipRequest;
// 申请发起人的富信息
TDSFriendInfo *info = request.friendInfo;
}
}];
处理好友申请
对于新的好友请求,玩家可以同意或者拒绝,也可以什么都不做,无视这些请求,甚至直接删除。
- Unity
- Android
- iOS
// LCFriendshipRequest request
// 接受
await TDSFriends.AcceptFriendshipRequest(request);
// 接受并添加额外属性
Dictionary<string, object> attrs = new Dictionary<string, object> {
{ "group", "coworkers" }
};
await TDSFriends.AcceptFriendshipRequest(request, attrs);
// 拒绝
await TDSFriends.DeclineFriendshipRequest(request);
// 删除
await request.Delete();
// LCFriendshipRequest request
// 接受
TDSFriends.acceptFriendRequest(request, new Callback<Void>() {
@Override
public void onSuccess(Void result) {
toast("Accepted.");
}
@Override
public void onFail(TDSFriendError error) {
toast("Failed to delete a friend: " + error.detailMessage);
}
});
// 接受并添加额外属性
Map<String, Object> attrs = new HashMap<String, Object>();
attrs.put("group", "coworkers");
TDSFriends.acceptFriendRequest(request, attrs, new Callback<Void>() {
// 略
});
// 拒绝
TDSFriends.declineFriendRequest(request, new Callback<Void>() {
// 略
});
// 删除
TDSFriends.deleteFriendRequest(request, new Callback<Void>() {
// 略
});
// LCFriendshipRequest request
// 接受
[TDSFriends acceptFriendRequest:request attributes:nil
callback:^(BOOL succeeded, NSError * _Nullable error) {
if (succeeded) {
// Accepted.
} else if (error) {
// Failed to accept a friend request.
}
}];
// 接受并添加额外属性
NSDictionary *attributes = @{
@"group" : @"coworkers",
};
[TDSFriends acceptFriendRequest:request attributes:attributes
callback:^(BOOL succeeded, NSError * _Nullable error) {
// 略
}];
// 拒绝
[TDSFriends declineFriendRequest:request
callback:^(BOOL succeeded, NSError * _Nullable error) {
// 略
}];
[TDSFriends deleteFriendRequest:request
callback:^(BOOL succeeded, NSError * _Nullable error) {
// 略
}];
注意:
- 对方拒绝了当前玩家发起的好友申请之后,玩家通过之前接口的添加好友接口再次发送申请时会收到报错,表明对方不想和当前玩家成为好友。
- 对方删除了当前玩家发起的好友请求后,当前玩家还可以再次发起申请。
查询好友列表
玩家可以查询自己的好友列表。查询时可以限定返回结果数量及起始位置:
- Unity
- Android
- iOS
var from = 0;
var limit = 100;
ReadOnlyCollection<TDSFriendInfo> friendInfos = await TDSFriends.QueryFriendList(from, limit);
foreach (TDSFriendInfo info in friendInfos) {
// 玩家信息
TDSUser user = info.User;
// 富信息数据
Dictionary<string, string> richPresence = info.RichPresence;
// 好友是否在线
bool online = info.Online;
}
int from = 0;
int limit = 100;
TDSFriends.queryFriendList(from, limit,
new ListCallback<TDSFriendInfo>(){
@Override
public void onSuccess(List<TDSFriendInfo> friendInfoList) {
for (TDSFriendInfo info : friendInfoList) {
// 玩家信息
TDSUser user = info.getUser();
// 富信息数据
TDSRichPresence richPresence = info.getRichPresence();
// 好友是否在线
boolean online = info.isOnline();
}
}
@Override
public void onFail(TDSFriendError error) {
toast("Failed to query friend list" + error.detailMessage);
}
});
TDSFriendQueryOption *option = [TDSFriendQueryOption new];
option.from = 0;
option.limit = 100;
[TDSFriends queryFriendWithOption:option
callback:^(NSArray<TDSFriendInfo *> * _Nullable friendInfos, NSError * _Nullable error) {
if (friendInfos) {
for (TDSFriendInfo *info in friendInfos) {
// 玩家信息
TDSUser *user = info.user;
// 富信息数据
NSDictionary *richPresence = info.richPresence;
// 好友是否在线
BOOL online = info.online;
}
} else if (error) {
// 处理错误
}
}];
查询是否好友
可以通过指定某个 TDSUser
的 objectId
来查询他是否是当前玩家的好友。
比如,假设 Tarara 的 objectId
是 5b0b97cf06f4fd0abc0abe35
:
- Unity
- Android
- iOS
bool isFriend = await TDSFriends.CheckFriendship("5b0b97cf06f4fd0abc0abe35");
TDSFriends.checkFriendship("5b0b97cf06f4fd0abc0abe35", new Callback<Boolean>() {
@Override
public void onSuccess(Boolean isFriend) {
if (isFriend) {
toast("Tarara is my friend.");
} else {
toast("Tarara is not my friend.");
}
}
@Override
public void onFail(TDSFriendError error) {
toast("Failed to query friendship: " + error.detailMessage);
}
});
[TDSFriends checkFriendshipWithUserId:@"5b0b97cf06f4fd0abc0abe35"
callback:^(NSNumber * _Nullable isFriend, NSError * _Nullable error) {
if (error) {
// 处理错误
}
if (isFriend.boolValue) {
NSLog(@"Tarara is my friend.");
} else {
NSLog(@"Tarara is not my friend.");
}
}];
分享链接
落地页
使用分享链接功能需要首先部署落地页网站。 落地页网站可以部署在云引擎或其他支持部署纯静态网站的服务器上。 如果计划部署在云引擎上,需注意云引擎的免费实例会自动休眠,请购买标准实例使用。
我们提供了开源的落地页示例项目,修改相应配置后可直接构建、部署、使用。
注意,示例项目中的 GAME_ANDROID_LINK
环境变量格式为 scheme://host/path
。
host
和 path
的值需和 Android 的 AndroidManifest.xml
中的值保持一致。
例如,假设 AndroidManifest.xml
中的相关配置如下:
<activity
android:name="com.tapsdk.friends.TDSFriendsRouterPageActivity"
android:allowTaskReparenting="true"
android:configChanges="keyboardHidden|orientation"
android:exported="true"
android:launchMode="singleTask"
android:screenOrientation="nosensor"
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:host="游戏应用ID"
android:path="/friends"
android:scheme="tapsdk" />
<!-- scheme不能出现大写或者下划线,<a href="[scheme]://[host]/[path]?[query]">启动应用程序</a> -->
</intent-filter>
</activity>
那么落地页项目中 GAME_ANDROID_LINK
的值为 tapsdk://游戏应用ID/friends
。
落地页网站的地址需要在客户端配置:
- Unity
- Android
- iOS
TDSFriends.SetShareLink("https://please-replace-with-your-domain.example.com");
TDSFriends.setShareLink("https://please-replace-with-your-domain.example.com");
[TDSFriends setShareLink:@"https://please-replace-with-your-domain.example.com"];
如果落地页部署在云引擎网站上,那么地址就是 https://你的云引擎自定义域名
。
生成链接
部署完落地页网站并在客户端配置好相应地址后,调用以下接口即可生成好友邀请页网址:
- Unity
- Android
- iOS
string inviteUrl = await TDSFriends.GenerateFriendInvitationLink();
TDSFriends.generateFriendInvitationLink(new Callback<String>() {
@Override
public void onSuccess(String inviteUrl) {
System.out.println("share this link to invite your friends: " + inviteUrl);
}
@Override
public void onFail(TDSFriendError error) {
System.out.println("Failed to generate invite link: " + error.detailMessage);
}
});
NSError *error;
NSString *inviteUrl = [TDSFriends generateFriendInvitationLinkWithError:&error];
分享链接中传递的用户名称默认为玩家昵称(nickname
),
因此,默认情况下,使用分享链接的前提是内建账户系统中设置了 nickname
(昵称)字段。
参见内建账户系统文档。
如果希望使用其他名称,可以在调用上述接口时另行指定。
另外,还可以传入其他信息,这些信息会作为 URL 查询参数拼接在好友邀请页网址后面。
例如,昵称为 Tarara 的玩家,邀请好友时希望使用「她姥姥」这个名称,邀请链接希望附加 ref=taptap
这个参数,可以这样调用:
- Unity
- Android
- iOS
Dictionary<string, object> parameters = new Dictionary<string, object> {
{ "ref", "taptap" }
};
string inviteUrl = await TDSFriends.GenerateFriendInvitationLink("她姥姥", parameters);
Map<String, Object> parameters = new HashMap<String, Object>();
parameters.put("ref", "taptap");
TDSFriends.generateFriendInvitationLink("她姥姥", parameters, new Callback<String>() {
// 略
});
NSError *error;
TDSFriendLinkOption *option = [TDSFriendLinkOption new];
option.roleName = @"她姥姥";
option.queries = @{
@"ref" : @"taptap",
};
NSString *inviteUrl = [TDSFriends generateFriendInvitationLinkWithOption:option error:&error];
处理链接
玩家通过邀请链接打开游戏后,开发者需要调用该接口。 调用该接口后,SDK 会自动向对应的玩家发起好友申请。
- Unity
- Android
- iOS
public class DeepLinkManager : MonoBehaviour
{
// 略
private async void onDeepLinkActivated(string url) {
await TDSFriends.HandleFriendInvitationLink(url);
}
}
public class FriendsActivity extends AppCompatActivity {
// 略
public void onHandleLink(View view) {
TDSFriends.handFriendInvitationLink(url, new Callback<Void>() {
@Override
public void onSuccess(Void result) {
// 略
}
@Override
public void onFail(TDSFriendError error) {
// 略
}
});
}
}
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options {
return [TDSFriends handleFriendInvitationLink:url
callback:^(BOOL succeeded, TDSFriendsLinkInfo * _Nullable linkInfo, NSError * _Nullable error) {
if (error) {
// handle error
}
}];
/* 如果需要延迟发送好友申请请求,可调用该接口, delay 单位为 秒
return [TDSFriends handleFriendInvitationLink:url delay: 1
callback:^(BOOL succeeded, TDSFriendsLinkInfo * _Nullable linkInfo, NSError * _Nullable error) {
if (error) {
// handle error
}
}];*/
}
开发者也可以通过 SDK 提供的接口解析链接,获取玩家的 objectId、名称、传入的其他参数,定制相应的逻辑。
- Unity
- Android
- iOS
public class DeepLinkManager : MonoBehaviour
{
// 略
private async void onDeepLinkActivated(string url) {
TDSFriendLinkInfo invitation = TDSFriends.ParseFriendInvitationLink(url);
string userObjectId = invitation.Identity;
string name = invitation.RoleName;
Dictionary<string, string> parameters = invitation.Queries;
await TDSFriends.Follow(userObjectId);
}
}
TDSFriendLinkInfo linkInfo = TDSFriends.parseFriendInvitationLink("url");
String userObjectId = linkInfo.getIdentity();
String name = linkInfo.getRoleName();
Map<String, String> parameters = linkInfo.getQueries();
TDSFriendLinkInfo *linkInfo = [TDSFriends parseFriendInvitationLink:(NSURL *)url];
NSString *userObjectId = linkInfo.identity;
NSString *name = linkInfo.roleName;
NSDictionary *parameters = linkInfo.queries;