融云 swift 自定义消息类型
有的时候 官方提供的消息类型并不能满足我们的需求,所以我们要定义消息类型
融云官方文档
一. 先创建一个类继承RCMessageContent
class ChatRoomMessageContent: RCMessageContent {
}
二. 注册这个类
注意事项:
注册自定义消息代码必须在发送、接收该自定义消息之前
推荐将所有注册自定义消息代码放在 init 方法之后, connect 方法之前
注册的消息类型名, 必须多端一致, 否则消息无法互通
请勿使用 RC: 开头的类型名,以免和 SDK 默认的消息名称冲突
RCCoreClient.shared().registerMessageType(ChatRoomMessageContent.classForCoder())
三. 这个类如何实现
我项目里面用了SwiftyJSON
, 所以这个地方也用了
我列举了Int
、 String
、Bool
类型,如果要用到senderUserInfo
需要自己进行编解码。
import SwiftyJSON
class ChatRoomMessageContent: RCMessageContent {
var gender: Int = 1
var content: String = ""
var isNew: Bool = false
///初始化
override init() {
super.init()
}
class func messageWithContent(_ content: String) -> ChatRoomMessageContent {
let message = ChatRoomMessageContent()
message.content = content
return message
}
// NSCoding
required 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 {
///将消息内容编码成json
override 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?.userId
userInfoDic["name"] = senderUserInfo?.name
userInfoDic["portrait"] = senderUserInfo?.portraitUri
dataDic["senderUserInfo"] = userInfoDic
}
return try! JSONSerialization.data(withJSONObject: dataDic, options: .prettyPrinted)
}
///将json解码生成消息内容
override func decode(with data: Data) {
let json = JSON(data)
gender = json["gender"].intValue
content = json["content"].stringValue
isNew = json["isNew"].boolValue
let userInfoDic = json["senderUserInfo"].dictionaryObject
let userId = userInfoDic?["userId"] as? String ?? ""
let name = userInfoDic?["name"] as? String
let portrait = userInfoDic?["portrait"] as? String
senderUserInfo = 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 = 1
messageContent.content = "内容"
messageContent.isNew = isNew
if let user = UserInfoService.shared.userInfo {
messageContent.gender = user.gender.rawValue
}
messageContent.senderUserInfo = viewModel.userInfo
let message = RCMessage(type: .ConversationType_CHATROOM, targetId: "\(viewModel.targetId)", direction: .MessageDirection_SEND, content: messageContent)
RCCoreClient.shared().send(message,
pushContent: nil,
pushData: nil) { message in
debugPrint("消息已存入本地数据库\(String(describing: message))")
} successBlock: { message in
debugPrint("成功-message:\(message)")
} errorBlock: { code, message in
debugPrint("失败-code:\(code)------message:\(message)")
}
四. 接收
if let body = message.content as? ChatRoomMessageContent {
print(body.gender)
print(body.content)
print(body.isNew)
}