iOS端集成
互動消息是用于加強直播間消息溝通、提升交互體驗的服務(wù)。提供了豐富、易集成的SDK,可在用戶開發(fā)的直播應(yīng)用中輕松集成評論、彈幕、點贊等能力。本文介紹iOS端集成互動消息的操作步驟。
前提條件
客戶端集成前,請確保已經(jīng)完成服務(wù)端集成,并提供客戶端訪問的獲取鑒權(quán)Token的接口。服務(wù)端集成指引請參見服務(wù)端集成。
環(huán)境要求
Xcode 12.0及以上版本,推薦使用最新正式版本
CocoaPods 1.9.3及以上版本
真機調(diào)試需iOS 10.0及以上版本
集成SDK
在Podfile文件中添加依賴,SDK名稱及版本依賴如下:
pod 'AliVCInteractionMessage', '~> 1.3.2'
執(zhí)行
pod install --repo-update
。
使用SDK
SDK使用需遵循如下操作順序:
初始化
登錄
相關(guān)操作
登出
反初始化
其中相關(guān)操作包含群組操作和消息操作,詳細說明如下:
群組操作
創(chuàng)建群組(需要以管理員身份進行登錄才能操作)
關(guān)閉群組(僅限群主/群管理員操作)
進入群組
離開群組
查詢?nèi)航M信息
修改群組信息(僅限群主/群管理員操作)
查詢?nèi)航M最近成員列表
查詢?nèi)航M全部成員(僅限群主/群管理員操作)
對群組進行禁言(僅限群主/群管理員操作)
對群組取消禁言(僅限群主/群管理員操作)
對群組的用戶進行禁言(僅限群主/群管理員操作)
對群組的用戶取消禁言(僅限群主/群管理員操作)
查詢?nèi)航M內(nèi)被禁言的用戶列表(僅限群主/群管理員操作)
消息操作
單發(fā)消息
群發(fā)消息
查詢最近群發(fā)消息列表
查詢?nèi)咳喊l(fā)消息(僅限群主/群管理員操作)
刪除/撤回群消息
查詢歷史消息
引入頭文件
在調(diào)用API之前,請確保已經(jīng)引入頭文件。
#import <AliVCInteractionMessage/AliVCInteractionMessage.h>
初始化
在使用SDK前需要進行初始化,可以在相關(guān)業(yè)務(wù)模塊的主入口設(shè)置。
// setup初始化
AliVCIMEngineConfig *config = [AliVCIMEngineConfig new];
config.deviceId = @"xxxx"; // 設(shè)備id,可以使用該系統(tǒng)方法進行獲?。篬[UIDevice currentDevice] identifierForVendor].UUIDString;
config.appId = @"APP_ID"; // 開通應(yīng)用后可以在控制臺上拷貝
config.appSign = @"APP_SIGN"; // 開通應(yīng)用后可以在控制臺上拷貝
config.logLevel = AliVCIMLogLevelDebug; // 在Debug時設(shè)置
int ret = [[AliVCIMEngine sharedEngine] setup:config]; // 初始化返回非0,表示初始化失敗,其中1001:重復(fù)初始化、1002:創(chuàng)建底層引擎失敗、-1:底層重復(fù)初始化、-2:初始化配置信息有誤
NSLog(@"API - setup result: %d", ret);
// 添加監(jiān)聽
[[AliVCIMEngine sharedEngine] addListener:self];
// 處理回調(diào)事件 AliVCIMEngineListenerProtocol
- (void)onIMEngineConnecting {
NSLog(@"Event - onIMEngineConnecting");
}
- (void)onIMEngineConnectSuccess {
NSLog(@"Event - onIMEngineConnectSuccess");
}
- (void)onIMEngineConnectFailed:(NSError *)error {
NSLog(@"Event - onIMEngineConnectFailed error: %@", error);
}
- (void)onIMEngineDisconnect:(AliVCIMEngineDisconnectType)type {
NSLog(@"Event - onIMEngineDisconnect: %d", type);
}
- (void)onIMEngineTokenExpired:(AliVCIMFetchAuthTokenBlock)fetchAuthTokenBlock {
NSLog(@"Event - onIMEngineTokenExpired");
// 需要你的服務(wù)端集成后,并提供給客戶端的獲取鑒權(quán)信息接口,客戶端通過該接口返回后獲取nonce和token
if (fetchAuthTokenBlock) {
AliVCIMAuthToken *auth = [AliVCIMAuthToken new];
auth.timestamp = 22123123; // 服務(wù)端返回timestamp值
auth.nonce = @"xxx"; // 服務(wù)端返回nonce值
auth.role = @"admin"; // admin角色,可以創(chuàng)建/關(guān)閉群組,如果不需要可以設(shè)置為空
auth.token = @"xxx" // 服務(wù)端返回token值
fetchAuthTokenBlock(auth, nil);
}
}
登錄
登錄需要鑒權(quán)信息,請確保提交,通過服務(wù)端獲取到鑒權(quán)信息,包括:timestamp、nonce、token等值。
AliVCIMUser *user = [AliVCIMUser new];
user.userId = @"abc"; // 當前app登錄的用戶id,最長64位,僅限于A~Z,a~z, 0~9及“-”, 不能包含其他字符
user.userExtension = @"{}"; // 用戶擴展信息,可以是頭像、昵稱等封裝為json字符串
AliVCIMAuthToken *auth = [AliVCIMAuthToken new];
auth.timestamp = 122222; // 服務(wù)端返回timestamp值
auth.nonce = @"xxx"; // 服務(wù)端返回nonce值
auth.role = @"admin"; // admin角色,可以創(chuàng)建/關(guān)閉群組,如果不需要可以設(shè)置為空
auth.token = @"xxx"; // 服務(wù)端返回token值
AliVCIMLoginReq *req = [AliVCIMLoginReq new];
req.currentUser = user;
req.authToken = auth;
[[AliVCIMEngine sharedEngine] login:req completed:^(NSError * _Nullable error) {
NSLog(@"API - login result: %@", error ? error.description : @"success");
if (!error) {
// 登錄成功
}
}];
群組操作
// 必須確保已經(jīng)初始化,否則會返回空值
AliVCIMGroupManager *groupManager = [[AliVCIMEngine sharedEngine] getGroupManager];
// 在適當?shù)臅r機(例如進入房間后,且完成登錄后)添加群組操作事件監(jiān)聽器
[[[AliVCIMEngine sharedEngine] getGroupManager] addListener:self];
// 如不需要時,需要移除監(jiān)聽器
[[[AliVCIMEngine sharedEngine] getGroupManager] removeListener:self];
// 處理群組事件 AliVCIMGroupListenerProtocol
- (void)imGroup:(NSString *)groupId onJoined:(AliVCIMUser *)user {
// 有人進入群組
NSLog(@"Event - imGroup:%@ onJoin: %@", groupId, user);
}
- (void)imGroup:(NSString *)groupId onLeaved:(AliVCIMUser *)user {
// 有人離開了群組
NSLog(@"Event - imGroup:%@ onLeave: %@", groupId, user);
}
- (void)imGroup:(NSString *)groupId onExited:(int)reason {
// 群組被關(guān)閉了
NSLog(@"Event - imGroup:%@ onExited: %d", groupId, reason);
}
- (void)imGroup:(NSString *)groupId onInfoChanged:(AliVCIMGroupInfoStatus *)status {
// 群組的信息發(fā)生了變化
NSLog(@"Event - imGroup:%@ onInfoChanged: %@", groupId, status);
}
- (void)imGroup:(NSString *)groupId onMuteChanged:(AliVCIMGroupMuteStatus *)status {
// 群組的禁言狀態(tài)發(fā)生了變化
NSLog(@"Event - imGroup:%@ onMuteChanged: %@", groupId, status);
}
需要以管理員身份進行登錄才能調(diào)用成功。
AliVCIMCreateGroupReq *req = [AliVCIMCreateGroupReq new];
req.groupId = nil; // 群組id,為空時,系統(tǒng)創(chuàng)建新群組后會返回唯一id;不為空時,groupId最長64位,僅限于A~Z,a~z, 0~9及“-”, 不能包含其他字符
req.groupName = @"xxx"; // 群組昵稱,一定要設(shè)置,否則會失敗
req.groupMeta = @"xxx"; // 群組擴展信息,如果有多個字段可以考慮封裝為json字符串
[[[AliVCIMEngine sharedEngine] getGroupManager] createGroup:req completed:^(AliVCIMCreateGroupRsp * _Nullable rsp, NSError * _Nullable error) {
if (rsp) {
// 成功
NSLog(@"API - createGroup rsp: %@", rsp);
}
}];
僅限群主/管理員調(diào)用,否則會調(diào)用失敗。
AliVCIMCloseGroupReq *req = [AliVCIMCloseGroupReq new];
req.groupId = @"xxx"; // 群組id
[[[AliVCIMEngine sharedEngine] getGroupManager] closeGroup:req completed:^(NSError * _Nullable error) {
}];
AliVCIMJoinGroupReq *req = [AliVCIMJoinGroupReq new];
req.groupId = @"xxx"; // 群組id
[[[AliVCIMEngine sharedEngine] getGroupManager] joinGroup:req completed:^(AliVCIMJoinGroupRsp * _Nullable rsp, NSError * _Nullable error) {
if (rsp) {
// 成功
NSLog(@"API - joinGroup rsp: %@", rsp);
}
}];
AliVCIMLeaveGroupReq *req = [AliVCIMLeaveGroupReq new];
req.groupId = @"xxx"; // 群組id
[[[AliVCIMEngine sharedEngine] getGroupManager] leaveGroup:req completed:^(NSError * _Nullable error) {
}];
AliVCIMQueryGroupReq *req = [AliVCIMQueryGroupReq new];
req.groupId = @"xxx"; // 群組id
[[[AliVCIMEngine sharedEngine] getGroupManager] queryGroup:req completed:^(AliVCIMQueryGroupRsp * _Nullable rsp, NSError * _Nullable error) {
if (rsp) {
// 成功
NSLog(@"API - queryGroup rsp: %@", rsp);
}
}];
支持修改群擴展信息和設(shè)置管理員,僅限群主/群管理員調(diào)用,否則會調(diào)用失敗。
AliVCIMModifyGroupReq *req = [AliVCIMModifyGroupReq new];
req.groupId = @"xxx"; // 群組id
req.groupMeta = @"xxx"; // 添加群拓展信息;若需要清空,則不需要設(shè)置,同時設(shè)置req.forceUpdateGroupMeta=YES;
req.admins = @[@"xxx"]; // 指定群管理員ID列表,最多設(shè)置3個管理員;若需要清空列表,則配置空列表(不需要設(shè)置即可),同時設(shè)置req.forceUpdateAdmins=YES;
[[[AliVCIMEngine sharedEngine] getGroupManager] modifyGroup:req completed:^(NSError * _Nullable error) {
}];
AliVCIMListRecentGroupUserReq *req = [AliVCIMListRecentGroupUserReq new];
req.groupId = @"xxx"; // 群組id
[[[AliVCIMEngine sharedEngine] getGroupManager] listRecentGroupUser:req completed:^(AliVCIMListRecentGroupUserRsp * _Nullable rsp, NSError * _Nullable error) {
if (rsp) {
// 成功
NSLog(@"API - listRecentGroupUser rsp: %@", rsp);
}
}];
僅限群主/群管理員調(diào)用,否則會調(diào)用失敗。
AliVCIMListGroupUserReq *req = [AliVCIMListGroupUserReq new];
req.groupId = @"xxx"; // 群組id
req.nextPageToken = @"xxx"; //不傳時表示第一頁,遍歷時服務(wù)端會返回下一頁Token,客戶端獲取下一頁時應(yīng)帶上
req.pageSize = 10;
req.sortType = AliVCIMSortType_ASC;
[[[AliVCIMEngine sharedEngine] getGroupManager] listGroupUser:req completed:^(AliVCIMListGroupUserRsp * _Nullable rsp, NSError * _Nullable error) {
if (rsp) {
// 成功
NSLog(@"API - listGroupUser rsp: %@", rsp);
}
}];
僅限群主/群管理員調(diào)用,否則會調(diào)用失敗。
AliVCIMMuteAllReq *req = [AliVCIMMuteAllReq new];
req.groupId = @"xxx"; // 群組id
[[[AliVCIMEngine sharedEngine] getGroupManager] muteAll:req completed:^(NSError * _Nullable error) {
}];
僅限群主/群管理員調(diào)用,否則會調(diào)用失敗。
AliVCIMCancelMuteAllReq *req = [AliVCIMCancelMuteAllReq new];
req.groupId = @"xxx"; // 群組id
[[[AliVCIMEngine sharedEngine] getGroupManager] cancelMuteAll:req completed:^(NSError * _Nullable error) {
}];
僅限群主/群管理員調(diào)用,否則會調(diào)用失敗。
AliVCIMMuteUserReq *req = [AliVCIMMuteUserReq new];
req.groupId = @"xxx"; // 群組id
req.userList = @[@"xxx"]; // 需要禁言的用戶id列表
[[[AliVCIMEngine sharedEngine] getGroupManager] muteUser:req completed:^(NSError * _Nullable error) {
}];
僅限群主/群管理員調(diào)用,否則會調(diào)用失敗。
AliVCIMCancelMuteUserReq *req = [AliVCIMCancelMuteUserReq new];
req.groupId = @"xxx"; // 群組id
req.userList = @[@"xxx"]; // 需要取消禁言的用戶id列表
[[[AliVCIMEngine sharedEngine] getGroupManager] cancelMuteUser:req completed:^(NSError * _Nullable error) {
}];
僅限群主/群管理員調(diào)用,否則會調(diào)用失敗。
AliVCIMListMuteUsersReq *req = [AliVCIMListMuteUsersReq new];
req.groupId = @"xxx"; // 群組id
[[[AliVCIMEngine sharedEngine] getGroupManager] listMuteUsers:req completed:^(AliVCIMListMuteUsersRsp * _Nullable rsp, NSError * _Nullable error) {
if (rsp) {
// 成功
NSLog(@"API - listMuteUsers rsp: %@", rsp);
}
}];
消息操作
// 必須確保已經(jīng)初始化,否則會返回空值
AliVCIMMessageManager *messageManager = [[AliVCIMEngine sharedEngine] getMessageManager];
// 在適當?shù)臅r機(例如進入房間后,且完成登錄后)添加消息操作事件監(jiān)聽器
[[[AliVCIMEngine sharedEngine] getMessageManager] addListener:self];
// 如不需要時,需要移除監(jiān)聽器
[[[AliVCIMEngine sharedEngine] getMessageManager] removeListener:self];
// 處理消息事件 AliVCIMMessageListenerProtocol
- (void)onIMReceivedC2CMessage:(AliVCIMMessage *)message {
// 收到其他用戶發(fā)來的單聊消息
NSLog(@"Event - onIMReceivedC2CMessage: %@", message);
}
- (void)onIMReceivedGroupMessage:(AliVCIMMessage *)message {
// 收到群聊消息
NSLog(@"Event - onIMReceivedGroupMessage: %@", message);
}
- (void)onIMDeleteMessage:(NSString *)messageId groupId:(NSString *)groupId {
// 消息被撤回/刪除
NSLog(@"Event - onIMDeleteMessage:%@ groupId: %@", messageId, groupId);
AliVCIMSendMessageToUserReq *req = [AliVCIMSendMessageToUserReq new];
req.reveiverId = @"xxx"; // 接受者id,需確保對方在線,否則會返回錯誤碼424,此時建議待對方上線后再重發(fā)
req.data = @"xxx"; // 發(fā)送消息內(nèi)容,如果是結(jié)構(gòu)化可考慮使用json字符串
req.type = 88888; // 自定義消息類型,需大于10000
req.skipAudit = YES; // 跳過安全審核,YES:發(fā)送的消息不經(jīng)過阿里云安全審核服務(wù)審核;NO:發(fā)送的消息經(jīng)過阿里云安全審核服務(wù)審核,審核失敗則不發(fā)送。
req.level = AliVCIMMessageLevel_Normal; // 消息分級,需要高可靠時,使用AliVCIMMessageLevel_High
[[[AliVCIMEngine sharedEngine] getMessageManager] sendC2CMessage:req completed:^(AliVCIMSendMessageToUserRsp * _Nullable rsp, NSError * _Nullable error) {
if (rsp) {
// 成功
NSLog(@"API - sendC2CMessage rsp: %@", rsp);
}
}];
//需確保已經(jīng)加入群成功(即在joinGroup回調(diào)成功之后),再發(fā)送群組消息,否則會返回錯誤碼425
AliVCIMSendMessageToGroupReq *req = [AliVCIMSendMessageToGroupReq new];
req.groupId = @"xxx"; // 群組id
req.data = @"xxx"; // 發(fā)送消息內(nèi)容,如果是結(jié)構(gòu)化可考慮使用json字符串
req.type = 99999; // 自定義消息類型,需大于10000
req.skipMuteCheck = YES; // 跳過禁言檢測,YES:忽略被禁言用戶,還可發(fā)消息;NO:當被禁言時,消息無法發(fā)送
req.skipAudit = YES; // 跳過安全審核,YES:發(fā)送的消息不經(jīng)過阿里云安全審核服務(wù)審核;NO:發(fā)送的消息經(jīng)過阿里云安全審核服務(wù)審核,審核失敗則不發(fā)送。
req.level = AliVCIMMessageLevel_Normal; // 消息分級,需要高可靠時,使用AliVCIMMessageLevel_High
req.noStorage = YES; // YES:表示該消息不需要存儲,也無法拉取查詢;NO:消息進行存儲,可以拉取查詢。如果在直播間的彈幕場景,需要設(shè)置為NO
req.repeatCount = 1; // 本消息重復(fù)數(shù)量,默認1。內(nèi)容完成一樣的消息可以使用該字段進行聚合,并發(fā)送一次即可。
[[[AliVCIMEngine sharedEngine] getMessageManager] sendGroupMessage:req completed:^(AliVCIMSendMessageToGroupRsp * _Nullable rsp, NSError * _Nullable error) {
if (rsp) {
// 成功
NSLog(@"API - sendGroupMessage rsp: %@", rsp);
}
}];
AliVCIMDeleteMessageReq *req = [AliVCIMDeleteMessageReq new];
req.groupId = @"xxx"; // 群組id
req.messageId = @"yyy"; // 消息id
NSLOG(@"API - deleteMessage req: %@", req);
[[[AliVCIMEngine sharedEngine] getMessageManager] deleteMessage:req completed:^(NSError * _Nullable error) {
NSLOG(@"API - deleteMessage result: %@", error ? error.description : @"success");
}];
AliVCIMListRecentMessageReq *req = [AliVCIMListRecentMessageReq new];
req.groupId = @"xxx"; // 群組id
[[[AliVCIMEngine sharedEngine] getMessageManager] listRecentMessage:req completed:^(AliVCIMListRecentMessageRsp * _Nullable rsp, NSError * _Nullable error) {
if (rsp) {
// 成功
NSLog(@"API - listRecentMessage rsp: %@", rsp);
}
}];
僅限群主/群管理員調(diào)用,否則會調(diào)用失敗。
AliVCIMListMessageReq *req = [AliVCIMListMessageReq new];
req.groupId = @"xxx"; // 群組id
req.nextPageToken = @"xxx"; //不傳時表示第一頁,遍歷時服務(wù)端會返回下一頁Token,客戶端獲取下一頁時應(yīng)帶上
req.type = 99999; // 自定義消息類型,需大于10000
req.sortType = AliVCIMSortType_ASC;
req.pageSize = 20;
[[[AliVCIMEngine sharedEngine] getMessageManager] listMessage:req completed:^(AliVCIMListMessageRsp * _Nullable rsp, NSError * _Nullable error) {
if (rsp) {
// 成功
NSLog(@"API - listMessage rsp: %@", rsp);
}
}];
AliVCIMListHistoryMessageReq *req = [[AliVCIMListHistoryMessageReq alloc] init];
req.groupId = gid; // 群id
req.nextPageToken = @"xxx"; //不傳時表示第一頁,遍歷時服務(wù)端會返回下一頁Token,客戶端獲取下一頁時應(yīng)帶上
req.type = 99999; // 自定義消息類型,需大于10000
req.sortType = AliVCIMSortType_ASC;
req.pageSize = 20;
req.beginTime = 0; // 按時間范圍遍歷,開始時間,單位秒,為0時表示最早時間
req.endTime = 0; // 按時間范圍遍歷,結(jié)束時間,單位秒,為0時表示最晚時間
NSLOG(@"API - listHistoryMessage req: %@", req);
[[[AliVCIMEngine sharedEngine] getMessageManager] listHistoryMessage:req completed:^(AliVCIMListHistoryMessageRsp * _Nullable rsp, NSError * _Nullable error) {
NSLOG(@"API - listHistoryMessage result: %@", error ? error.description : @"success");
if (rsp) {
NSLOG(@"API - listHistoryMessage rsp: %@", rsp);
}
}];
登出
[[AliVCIMEngine sharedEngine] logout:^(NSError * _Nullable error) {
NSLog(@"API - logout result: %@", error ? error.description : @"success");
}];
反初始化
登出后如無需再進行登錄,可以進行反初始化操作,SDK會對底層操作實例進行釋放。
int ret = [[AliVCIMEngine sharedEngine] destroy];
NSLog(@"API - destroy result: %d", ret);