李洪強iOS開發之-環信04_消息


李洪強iOS開發之-環信04_消息


消息:IM 交互實體,在 SDK 中對應的類型是 EMMessage。EMMessage 由 EMMessageBody 組成。

 

構造文字消息

EMTextMessageBody *body = [[EMTextMessageBody alloc] initWithText:@"要發送的消息"]; NSString *from = [[EMClient sharedClient] currentUsername];   //生成Message EMMessage *message = [[EMMessage alloc] initWithConversationID:@"6001" from:from to:@"6001" body:body ext:messageExt]; message.chatType = EMChatTypeChat;// 設置為單聊消息 //message.chatType = EMChatTypeGroupChat;// 設置為群聊消息 //message.chatType = EMChatTypeChatRoom;// 設置為聊天室消息

構造圖片消息

EMImageMessageBody *body = [[EMImageMessageBody alloc] initWithData:data displayName:@"image.png"]; NSString *from = [[EMClient sharedClient] currentUsername];   //生成Message EMMessage *message = [[EMMessage alloc] initWithConversationID:@"6001" from:from to:@"6001" body:body ext:messageExt]; message.chatType = EMChatTypeChat;// 設置為單聊消息 //message.chatType = EMChatTypeGroupChat;// 設置為群聊消息 //message.chatType = EMChatTypeChatRoom;// 設置為聊天室消息

構造位置消息

EMLocationMessageBody *body = [[EMLocationMessageBody alloc] initWithLatitude:39 longitude:116 address:@"地址"]; NSString *from = [[EMClient sharedClient] currentUsername];   // 生成message EMMessage *message = [[EMMessage alloc] initWithConversationID:@"6001" from:from to:@"6001" body:body ext:messageExt]; message.chatType = EMChatTypeChat;// 設置為單聊消息 //message.chatType = EMChatTypeGroupChat;// 設置為群聊消息 //message.chatType = EMChatTypeChatRoom;// 設置為聊天室消息

構造語音消息

EMVoiceMessageBody *body = [[EMVoiceMessageBody alloc] initWithLocalPath:@"audioPath" displayName:@"audio"]; body.duration = duration; NSString *from = [[EMClient sharedClient] currentUsername];   // 生成message EMMessage *message = [[EMMessage alloc] initWithConversationID:@"6001" from:from to:@"6001" body:body ext:messageExt]; message.chatType = EMChatTypeChat;// 設置為單聊消息 //message.chatType = EMChatTypeGroupChat;// 設置為群聊消息 //message.chatType = EMChatTypeChatRoom;// 設置為聊天室消息

構造視頻消息

EMVideoMessageBody *body = [[EMVideoMessageBody alloc] initWithLocalPath:@"videoPath" displayName:@"video.mp4"]; NSString *from = [[EMClient sharedClient] currentUsername];   // 生成message EMMessage *message = [[EMMessage alloc] initWithConversationID:@"6001" from:from to:@"6001" body:body ext:messageExt]; message.chatType = EMChatTypeChat;// 設置為單聊消息 //message.chatType = EMChatTypeGroupChat;// 設置為群聊消息 //message.chatType = EMChatTypeChatRoom;// 設置為聊天室消息

構造文件消息

EMFileMessageBody *body = [[EMFileMessageBody alloc] initWithLocalPath:@"filePath" displayName:@"file"]; NSString *from = [[EMClient sharedClient] currentUsername];   // 生成message EMMessage *message = [[EMMessage alloc] initWithConversationID:@"6001" from:from to:@"6001" body:body ext:messageExt]; message.chatType = EMChatTypeChat;// 設置為單聊消息 //message.chatType = EMChatTypeGroupChat;// 設置為群聊消息 //message.chatType = EMChatTypeChatRoom;// 設置為聊天室消息

構造透傳消息

SDK 提供的一種特殊類型的消息,即 CMD,不會存 db,也不會走 APNS 推送,類似一種指令型的消息。比如您的服務器要通知客戶端做某些操作,您可以服務器和客戶端提前約定好某個字段,當客戶端收到約定好的字段時,執行某種特殊操作。

EMCmdMessageBody *body = [[EMCmdMessageBody alloc] initWithAction:action]; NSString *from = [[EMClient sharedClient] currentUsername];   // 生成message EMMessage *message = [[EMMessage alloc] initWithConversationID:@"6001" from:from to:@"6001" body:body ext:messageExt]; message.chatType = EMChatTypeChat;// 設置為單聊消息 //message.chatType = EMChatTypeGroupChat;// 設置為群聊消息 //message.chatType = EMChatTypeChatRoom;// 設置為聊天室消息

構造擴展消息

當 SDK 提供的消息類型不滿足需求時,開發者可以通過擴展自 SDK 提供的文本、語音、圖片、位置等消息類型,從而生成自己需要的消息類型。

這里是擴展自文本消息,如果這個自定義的消息需要用到語音或者圖片等,可以擴展自語音、圖片消息,亦或是位置消息。

// 以單聊消息舉例
EMTextMessageBody *body = [[EMTextMessageBody alloc] initWithText:@"要發送的消息"]; NSString *from = [[EMClient sharedClient] currentUsername];   //生成Message EMMessage *message = [[EMMessage alloc] initWithConversationID:@"6001" from:from to:@"6001" body:body ext:messageExt]; message.chatType = EMChatTypeChat;// 設置為單聊消息 //message.chatType = EMChatTypeGroupChat;// 設置為群聊消息 //message.chatType = EMChatTypeChatRoom;// 設置為聊天室消息 message.ext = @{@"key":@"value"}; // 擴展消息部分

插入消息

EMTextMessageBody *body = [[EMTextMessageBody alloc] initWithText:@"要發送的消息"]; NSString *from = [[EMClient sharedClient] currentUsername];   //生成Message EMMessage *message = [[EMMessage alloc] initWithConversationID:@"6001" from:from to:@"6001" body:body ext:messageExt]; message.chatType = EMChatTypeChat;// 設置為單聊消息 //message.chatType = EMChatTypeGroupChat;// 設置為群聊消息 //message.chatType = EMChatTypeChatRoom;// 設置為聊天室消息   [[EMClient sharedClient].chatManager importMessages:@[message]];

更新消息屬性

/*!
 *  更新消息到 DB
 *
 *  @param aMessage  消息
 *
 *  @result 是否成功
 */
- (BOOL)updateMessage:(EMMessage *)aMessage;   //調用:[[EMClient sharedClient].chatManager updateMessage:aMessage];

會話:操作聊天消息 EMMessage 的容器,在 SDK 中對應的類型是 EMConversation。

新建/獲取一個會話

根據 conversationId 創建一個 conversation。

[[EMClient sharedClient].chatManager getConversation:@"8001" type:EMConversationTypeChat createIfNotExist:YES]; //EMConversationTypeChat 單聊會話 //EMConversationTypeGroupChat 群聊會話 //EMConversationTypeChatRoom 聊天室會話
  • getConversation:創建與8001的會話
  • type:會話類型
  • createIfNotExist:不存在是否創建

刪除會話

 

刪除單個會話

[[EMClient sharedClient].chatManager deleteConversation:@"8001" deleteMessages:YES];
  • deleteConversation: 刪除與8001的會話
  • deleteMessages: 刪除會話中的消息

根據 conversationId 批量刪除會話

[[EMClient sharedClient].chatManager deleteConversations:@[@"8001",@"8002"] deleteMessages:YES];
  • deleteConversations: 要刪除的會話
  • deleteMessages: 刪除會話中的消息

獲取會話列表

SDK中提供了三種獲取會會話列表的方法。

獲取或創建

EMConversation *conversation = [[EMClient sharedClient].chatManager getConversation:@"8001" type:EMConversationTypeChat createIfNotExist:YES];
  • getConversation: 獲取或創建與8001的會話
  • type:EMConversationTypeChat: 會話類型

獲取內存中所有會話

NSArray *conversations = [[EMClient sharedClient].chatManager getAllConversations];

獲取 DB 中的所有會話

NSArray *conversations = [[EMClient sharedClient].chatManager loadAllConversationsFromDB];

獲取會話未讀消息數

[EMConversation unreadMessagesCount];

消息檢索

可以通過關鍵字、消息類型、開始結束時間檢索某個會話中的消息。

/*!
 *  從數據庫獲取指定類型的消息,取到的消息按時間排序,如果參考的時間戳為負數,則從最新消息向前取,如果 aLimit 是負數,則獲取所有符合條件的消息
 *
 *  @param aType        消息類型
 *  @param aTimestamp   參考時間戳
 *  @param aLimit       獲取的條數
 *  @param aSender      消息發送方,如果為空則忽略
 *  @param aDirection   消息搜索方向
 *
 *  @result 消息列表<EMMessage>
 */
- (NSArray *)loadMoreMessagesWithType:(EMMessageBodyType)aType before:(long long)aTimestamp limit:(int)aLimit from:(NSString*)aSender direction:(EMMessageSearchDirection)aDirection;   /*! * 從數據庫獲取包含指定內容的消息,取到的消息按時間排序,如果參考的時間戳為負數,則從最新消息向前取,如果 aLimit 是負數,則獲取所有符合條件的消息 * * @param aKeywords 搜索關鍵字,如果為空則忽略 * @param aTimestamp 參考時間戳 * @param aLimit 獲取的條數 * @param aSender 消息發送方,如果為空則忽略 * @param aDirection 消息搜索方向 * * @result 消息列表<EMMessage> */ - (NSArray *)loadMoreMessagesContain:(NSString*)aKeywords before:(long long)aTimestamp limit:(int)aLimit from:(NSString*)aSender direction:(EMMessageSearchDirection)aDirection;   /*! * 從數據庫獲取指定時間段內的消息,取到的消息按時間排序,為了防止占用太多內存,用戶應當制定加載消息的最大數 * * @param aStartTimestamp 毫秒級開始時間 * @param aEndTimestamp 結束時間 * @param aMaxCount 加載消息最大數 * * @result 消息列表<EMMessage> * */ - (NSArray *)loadMoreMessagesFrom:(long long)aStartTimestamp to:(long long)aEndTimestamp maxCount:(int)aMaxCount;

登錄成功之后才能進行聊天操作。發消息時,單聊和群聊調用的是統一接口,區別只是要設置下 message.chatType。

發送消息

/*!
 @property
 @brief 發送消息
 @discussion
    異步方法
 */
- (void)asyncSendMessage:(EMMessage *)aMessage progress:(void (^)(int progress))aProgress completion:(void (^)(EMMessage *message, EMError *error))aProgressCompletion;   //調用:[[EMClient sharedClient].chatManager asyncSendMessage:message progress:nil completion:^(EMMessage *aMessage, EMError *aError) {}]; 

接收消息

注冊消息回調

//消息回調:EMChatManagerChatDelegate
//注冊消息回調 [[EMClient sharedClient].chatManager addDelegate:self delegateQueue:nil]; //移除消息回調 [[EMClient sharedClient].chatManager removeDelegate:self];

在線普通消息會走以下回調:

/*!
 @method
 @brief 接收到一條及以上非cmd消息
 */
- (void)didReceiveMessages:(NSArray *)aMessages;

透傳(cmd)在線消息會走以下回調:

/*!
 @method
 @brief 接收到一條及以上cmd消息
 */
- (void)didReceiveCmdMessages:(NSArray *)aCmdMessages;

解析普通消息

// 收到消息的回調,帶有附件類型的消息可以用 SDK 提供的下載附件方法下載(后面會講到)
- (void)didReceiveMessages:(NSArray *)aMessages { for (EMMessage *message in aMessages) { EMMessageBody *msgBody = message.body; switch (msgBody.type) { case EMMessageBodyTypeText: { // 收到的文字消息 EMTextMessageBody *textBody = (EMTextMessageBody *)msgBody; NSString *txt = textBody.text; NSLog(@"收到的文字是 txt -- %@",txt); } break; case EMMessageBodyTypeImage: { // 得到一個圖片消息body EMImageMessageBody *body = ((EMImageMessageBody *)msgBody); NSLog(@"大圖remote路徑 -- %@" ,body.remotePath); NSLog(@"大圖local路徑 -- %@" ,body.localPath); // // 需要使用sdk提供的下載方法后才會存在 NSLog(@"大圖的secret -- %@" ,body.secretKey); NSLog(@"大圖的W -- %f ,大圖的H -- %f",body.size.width,body.size.height); NSLog(@"大圖的下載狀態 -- %lu",body.downloadStatus);     // 縮略圖sdk會自動下載 NSLog(@"小圖remote路徑 -- %@" ,body.thumbnailRemotePath); NSLog(@"小圖local路徑 -- %@" ,body.thumbnailLocalPath); NSLog(@"小圖的secret -- %@" ,body.thumbnailSecretKey); NSLog(@"小圖的W -- %f ,大圖的H -- %f",body.thumbnailSize.width,body.thumbnailSize.height); NSLog(@"小圖的下載狀態 -- %lu",body.thumbnailDownloadStatus); } break; case EMMessageBodyTypeLocation: { EMLocationMessageBody *body = (EMLocationMessageBody *)msgBody; NSLog(@"緯度-- %f",body.latitude); NSLog(@"經度-- %f",body.longitude); NSLog(@"地址-- %@",body.address); } break; case EMMessageBodyTypeVoice: { // 音頻sdk會自動下載 EMVoiceMessageBody *body = (EMVoiceMessageBody *)msgBody; NSLog(@"音頻remote路徑 -- %@" ,body.remotePath); NSLog(@"音頻local路徑 -- %@" ,body.localPath); // 需要使用sdk提供的下載方法后才會存在(音頻會自動調用) NSLog(@"音頻的secret -- %@" ,body.secretKey); NSLog(@"音頻文件大小 -- %lld" ,body.fileLength); NSLog(@"音頻文件的下載狀態 -- %lu" ,body.downloadStatus); NSLog(@"音頻的時間長度 -- %lu" ,body.duration); } break; case EMMessageBodyTypeVideo: { EMVideoMessageBody *body = (EMVideoMessageBody *)msgBody;   NSLog(@"視頻remote路徑 -- %@" ,body.remotePath); NSLog(@"視頻local路徑 -- %@" ,body.localPath); // 需要使用sdk提供的下載方法后才會存在 NSLog(@"視頻的secret -- %@" ,body.secretKey); NSLog(@"視頻文件大小 -- %lld" ,body.fileLength); NSLog(@"視頻文件的下載狀態 -- %lu" ,body.downloadStatus); NSLog(@"視頻的時間長度 -- %lu" ,body.duration); NSLog(@"視頻的W -- %f ,視頻的H -- %f", body.thumbnailSize.width, body.thumbnailSize.height);   // 縮略圖sdk會自動下載 NSLog(@"縮略圖的remote路徑 -- %@" ,body.thumbnailRemotePath); NSLog(@"縮略圖的local路徑 -- %@" ,body.thumbnailLocalPath); NSLog(@"縮略圖的secret -- %@" ,body.thumbnailSecretKey); NSLog(@"縮略圖的下載狀態 -- %lu" ,body.thumbnailDownloadStatus); } break; case EMMessageBodyTypeFile: { EMFileMessageBody *body = (EMFileMessageBody *)msgBody; NSLog(@"文件remote路徑 -- %@" ,body.remotePath); NSLog(@"文件local路徑 -- %@" ,body.localPath); // 需要使用sdk提供的下載方法后才會存在 NSLog(@"文件的secret -- %@" ,body.secretKey); NSLog(@"文件文件大小 -- %lld" ,body.fileLength); NSLog(@"文件文件的下載狀態 -- %lu" ,body.downloadStatus); } break;   default: break; } } }

解析透傳消息

- (void)didReceiveCmdMessages:(NSArray *)aCmdMessages{ for (EMMessage *message in aCmdMessages) { EMCmdMessageBody *body = (EMCmdMessageBody *)message.body; NSLog(@"收到的action是 -- %@",body.action); } }

解析消息擴展屬性

- (void)didReceiveCmdMessages:(NSArray *)aCmdMessages{ for (EMMessage *message in aCmdMessages) { // cmd消息中的擴展屬性 NSDictionary *ext = message.ext; NSLog(@"cmd消息中的擴展屬性是 -- %@",ext) } } // 收到消息回調 - (void)didReceiveMessages:(NSArray *)aMessages{ for (EMMessage *message in aMessages) { // 消息中的擴展屬性 NSDictionary *ext = message.ext; NSLog(@"消息中的擴展屬性是 -- %@",ext); } }

自動下載消息中的附件

SDK 接收到消息后,會默認下載:圖片消息的縮略圖,語音消息的語音,視頻消息的視頻第一幀。

請先判斷你要下載附件沒有下載成功之后,在調用以下下載方法,否則SDK下載方法會再次從服務器上獲取附件。

[[EMClient sharedClient].chatManager asyncDownloadMessageThumbnail:message progress:nil completion:^(EMMessage *message, EMError *error) { if (!error) { NSLog(@"下載成功,下載后的message是 -- %@",aMessage); } }];

下載消息中的原始附件

[[EMClient sharedClient].chatManager asyncDownloadMessageAttachments:message progress:nil completion:^(EMMessage *message, EMError *error) { if (!error) { NSLog(@"下載成功,下載后的message是 -- %@",aMessage); } }];

消息已送達回執

SDK提供了已送達回執,當對方收到您的消息后,您會收到以下回調。

/*!
 @method
 @brief 接收到一條及以上已送達回執
 */
- (void)didReceiveHasDeliveredAcks:(NSArray *)aMessages;

消息已讀回執

已讀回執需要開發者主動調用的。當用戶讀取消息后,由開發者主動調用方法。

發送已讀回執

// 發送已讀回執。在這里寫只是為了演示發送,在APP中具體在哪里發送需要開發者自己決定。
[[EMClient sharedClient].chatManager asyncSendReadAckForMessage:message];

接收已讀回執

/*!
 *  接收到一條及以上已讀回執
 *
 *  @param aMessages  消息列表<EMMessage>
 */
- (void)didReceiveHasReadAcks:(NSArray *)aMessages;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM