有的时候 官方提供的消息类型并不能满足我们的需求,所以我们要定义消息类型
融云官方文档
一. 先创建一个类继承RCMessageContent
class ChatRoomMessageContent: RCMessageContent {
}
二. 注册这个类
注意事项:
注册自定义消息代码必须在发送、接收该自定义消息之前
推荐将所有注册自定义消息代码放在 init 方法之后, connect 方法之前
注册的消息类型名, 必须多端一致, 否则消息无法互通
请勿使用 RC: 开头的类型名,以免和 SDK 默认的消息名称冲突
RCCoreClient.shared().registerMessageType(ChatRoomMessageContent.classForCoder())
三. 这个类如何实现
我项目里面用了SwiftyJSON
, 所以这个地方也用了
我列举了Int
、 String
、Bool
类型,如果要用到senderUserInfo
需要自己进行编解码。
import SwiftyJSONclass ChatRoomMessageContent: RCMessageContent {var gender: Int = 1var content: String = ""var isNew: Bool = false///初始化override init() {super.init()}class func messageWithContent(_ content: String) -> ChatRoomMessageContent {let message = ChatRoomMessageContent()message.content = contentreturn message}// NSCodingrequired init?(coder: NSCoder) {super.init()self.gender = coder.decodeInteger(forKey: "gender")self.content = "\(coder.decodeObject(forKey: "content") ?? "")"self.isNew = coder.decodeBool(forKey: "isNew")}override class func persistentFlag() -> RCMessagePersistent {return .MessagePersistent_ISPERSISTED}func encode(with coder: NSCoder) {coder.encode(self.gender, forKey: "gender")coder.encode(self.content, forKey: "content")coder.encode(self.isNew, forKey: "isNew")}
}extension ChatRoomMessageContent {///将消息内容编码成jsonoverride func encode() -> Data? {let dataDic: NSMutableDictionary = NSMutableDictionary()dataDic.setValue(self.gender, forKey: "gender")dataDic.setValue(self.content, forKey: "content")dataDic.setValue(self.isNew, forKey: "isNew")if senderUserInfo != nil {var userInfoDic = [String: Any]()userInfoDic["userId"] = senderUserInfo?.userIduserInfoDic["name"] = senderUserInfo?.nameuserInfoDic["portrait"] = senderUserInfo?.portraitUridataDic["senderUserInfo"] = userInfoDic}return try! JSONSerialization.data(withJSONObject: dataDic, options: .prettyPrinted)}///将json解码生成消息内容override func decode(with data: Data) {let json = JSON(data)gender = json["gender"].intValuecontent = json["content"].stringValueisNew = json["isNew"].boolValuelet userInfoDic = json["senderUserInfo"].dictionaryObjectlet userId = userInfoDic?["userId"] as? String ?? ""let name = userInfoDic?["name"] as? Stringlet portrait = userInfoDic?["portrait"] as? StringsenderUserInfo = RCUserInfo(userId: userId, name: name, portrait: portrait)}//最后一条消息是自定义消息的时候,可以更改在会话列表显示的类型,为了区分消息类型override func conversationDigest() -> String? {return "[房间自定义消息]"}//定义的消息类型名,需要在各个平台上保持一致,以保证消息互通,别以 RC 开头,以免和融云系统冲突override class func getObjectName() -> String {return "RC:RoomCustom"//⚠️不要和系统冲突}
}
四. 发送自定义消息
let messageContent = ChatRoomMessageContent()messageContent.gender = 1messageContent.content = "内容"messageContent.isNew = isNewif let user = UserInfoService.shared.userInfo {messageContent.gender = user.gender.rawValue}messageContent.senderUserInfo = viewModel.userInfolet message = RCMessage(type: .ConversationType_CHATROOM, targetId: "\(viewModel.targetId)", direction: .MessageDirection_SEND, content: messageContent)RCCoreClient.shared().send(message,pushContent: nil,pushData: nil) { message indebugPrint("消息已存入本地数据库\(String(describing: message))")
} successBlock: { message indebugPrint("成功-message:\(message)")
} errorBlock: { code, message indebugPrint("失败-code:\(code)------message:\(message)")
}
四. 接收
if let body = message.content as? ChatRoomMessageContent {print(body.gender)print(body.content)print(body.isNew)
}