iOS-Swift-融云自定義消息及其他設置

總結所有步驟

1.自定義消息類型
2.自定義展示的消息Cell類
3.自定義消息內容的View(我這里使用xib确丢,大家參考就好)
4.融云服務器建立連接成功后注冊自定義的消息類型矩肩,會話頁面類注冊自定義消息的Cell
5.發(fā)送自定義消息
6.自定義消息的點擊事件
7.會話頁面類的一些處理(界面設置耕皮、擴展功能躺枕、長按消息撤回轉發(fā)家制、自定義地圖頁面)
1.自定義消息類型(UsersModel是自定義的用戶數據model)
let RCBusinessCardCellKey = "Kchat:businessCard" //個人名片
class BusinessCardMessage: RCMessageContent , NSCoding {
    
    var id: Int = -1                     //名片用戶id
    var title: String = ""               //名片昵稱
    var detail: String = ""              //名片用戶賬號(類似QQ)
    var image: String = ""               //名片頭像

    override init() {
        super.init()
    }
    ///初始化
    class func messageWithContent(_ model: UsersModel) -> BusinessCardMessage {
        let message = BusinessCardMessage()
        
        message.id = model.id
        message.title = model.nickname
        message.detail = model.kNumber
        message.image = model.headimgurl
        return message
    }
    
    ///消息是否存儲暂雹,是否計入未讀數
    override class func persistentFlag() -> RCMessagePersistent {
        return RCMessagePersistent.MessagePersistent_ISPERSISTED
    }
    
    // NSCoding
    required init?(coder: NSCoder) {
        super.init()
        self.id = coder.decodeInteger(forKey: "id")
        self.title = "\(coder.decodeObject(forKey: "title") ?? "")"
        self.detail = "\(coder.decodeObject(forKey: "detail") ?? "")"
        self.image = "\(coder.decodeObject(forKey: "image") ?? "")"
    }
    func encode(with coder: NSCoder) {
        coder.encode(self.id, forKey: "id")
        coder.encode(self.title, forKey: "title")
        coder.encode(self.detail, forKey: "detail")
        coder.encode(self.image, forKey: "image")
    }
}

//MARK:*******************代理方法*******************
extension BusinessCardMessage {
    ///將消息內容編碼成json
    override func encode() -> Data! {
        let dataDic: NSMutableDictionary = NSMutableDictionary()
        dataDic.setValue(self.id, forKey: "id")
        dataDic.setValue(self.title, forKey: "title")
        dataDic.setValue(self.detail, forKey: "detail")
        dataDic.setValue(self.image, forKey: "image")
        
        return try! JSONSerialization.data(withJSONObject: dataDic, options: .prettyPrinted)
    }
    ///將json解碼生成消息內容
    override func decode(with data: Data!) {
        guard let dic = try? JSONSerialization.jsonObject(with: data, options: .mutableLeaves) as? NSDictionary else {
            return
        }
        self.id = dic.intForKey("id")
        self.title = dic.stringForKey("title")
        self.detail = dic.stringForKey("detail")
        self.image = dic.stringForKey("image")
    }
    //最后一條消息是自定義消息的時候策治,可以更改在會話列表顯示的類型脓魏,為了區(qū)分消息類型
    override func conversationDigest() -> String! {
        return "[個人名片]"
    }
    //定義的消息類型名,需要在各個平臺上保持一致通惫,以保證消息互通,別以 RC 開頭茂翔,以免和融云系統(tǒng)沖突
    override class func getObjectName() -> String! {
        return RCBusinessCardCellKey
    }
}
2.自定義展示的消息Cell類
class BusinessCardMessageCell: RCMessageCell {
    
    static let cellHeight: CGFloat = 84        //消息高度
    var contentV: BusinessCardContentV?        //消息內容view
    
    //當應用自定義消息時,必須實現該方法來返回cell的Size
    override class func size(for model: RCMessageModel!, withCollectionViewWidth collectionViewWidth: CGFloat, referenceExtraHeight extraHeight: CGFloat) -> CGSize {
        return CGSize(width: collectionViewWidth, height: cellHeight + extraHeight)
    }
    //設置當前消息Cell的數據模型
    override func setDataModel(_ model: RCMessageModel!) {
        super.setDataModel(model)
        setContentV(model)
    }
    
    //設置消息UI
    func setContentV(_ model: RCMessageModel) {
        if contentV == nil {
            contentV = BusinessCardContentV().initContentV()
            contentV?.model = model.content
            
            //添加自定義消息點擊事件
            let tapGesture: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(clickAction))
            contentV?.addGestureRecognizer(tapGesture)
            //添加自定義消息長按事件
            let longGesture: UILongPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(longAction(_:)))
            contentV?.addGestureRecognizer(longGesture)
            
            messageContentView?.addSubview(contentV!)
        }

        var locationX: CGFloat = 0.0
        //我方發(fā)送消息-右邊布局
        if model.messageDirection == .MessageDirection_SEND {
            locationX = messageContentView.bounds.width - contentV!.bounds.width
            contentV?.isSend = true
            
        //他方發(fā)送消息-左邊布局
        } else {
            contentV?.isSend = false
        }
        contentV?.setLocationX(x: locationX)
    }
    //MARK:-添加單擊手勢事件履腋,會話頁面的didTapMessageCell方法才會被執(zhí)行
    @objc func clickAction() {
        delegate.didTapMessageCell?(model)
    }
    //MARK:-添加長按手勢事件珊燎,會話頁面的didLongTouchMessageCell方法才會被執(zhí)行
    @objc func longAction(_ longGesture: UILongPressGestureRecognizer) {
        if longGesture.state != .began { return }
        delegate.didLongTouchMessageCell?(model, in: self)
    }
}
3.自定義消息內容的View(我這里使用xib,大家參考就好)
class BusinessCardContentV: UIView {
    @IBOutlet weak var bgImageV: UIImageView!
    @IBOutlet weak var contentViewLeft: NSLayoutConstraint!
    @IBOutlet weak var imageV: UIImageView!
    @IBOutlet weak var nameL: UILabel!
    @IBOutlet weak var detailL: UILabel!
    
    private var _model: RCMessageContent?
    var model: RCMessageContent? {
        set(newValue) {
            _model = newValue
            if newValue == nil { return }
            
            guard let messageModel = newValue as? BusinessCardMessage else {
                return
            }
            imageV.loadImage(imgUrl: messageModel.image, defaultImage: "morentu")
            imageV.setContentFit()
            nameL.text = messageModel.title
            detailL.text = messageModel.detail
        }
        get { return _model }
    }
    
    var isSend: Bool = false {
        didSet {
            //我方發(fā)送消息-右邊布局
            if isSend {
                bgImageV.image = UIImage(named: "liaotian27")
                contentViewLeft.constant = 15
                
            //他方發(fā)送消息-左邊布局
            } else {
                bgImageV.image = UIImage(named: "liaotian26")
                contentViewLeft.constant = 21
            }
        }
    }
    
    //初始化
    func initContentV() -> BusinessCardContentV {
        let contentV: BusinessCardContentV = Bundle.main.loadNibNamed("BusinessCardContentV", owner: nil, options: nil)?.first as! BusinessCardContentV
        contentV.frame = CGRect(x: 0, y: 0, width: 235, height: 84)
        return contentV
    }
}
4.融云服務器建立連接成功后注冊自定義的消息類型府树,會話頁面類注冊自定義消息的Cell
//融云服務器建立連接成功后注冊自定義的消息類型
RCIM.shared().registerMessageType(BusinessCardMessage.self)

//繼承RCConversationViewController的會話頁面注冊自定義消息的Cell
register(BusinessCardMessageCell.self, forMessageClass: BusinessCardMessage.self)
5.發(fā)送自定義消息
let message: BusinessCardMessage = BusinessCardMessage.messageWithContent(usersModel)
sendMessage(message, pushContent: "[個人名片]\(message.title)")
6.自定義消息的點擊事件
//MARK:-點擊消息
override func didTapMessageCell(_ model: RCMessageModel!) {
    super.didTapMessageCell(model)
    
    switch model.objectName {
    case RCBusinessCardCellKey:     //名片
        //添加你需要的操作
    default:
        break
    }
}
7.會話頁面類的一些處理(界面設置俐末、擴展功能、長按消息撤回轉發(fā)奄侠、自定義地圖頁面)
//重寫此方法卓箫,防止導航欄自定義按鈕被置nil
override func notifyUpdateUnreadMessageCount() { }

//MARK:-設置CollectionView的屬性
func setCollectionViewProperty() {
    conversationMessageCollectionView.backgroundColor = UIColor.BackgroundColor()
    conversationMessageCollectionView.showsVerticalScrollIndicator = false
    
    //修改背景顏色
    chatSessionInputBarControl.inputTextView.superview?.backgroundColor = RGBA(234, 237, 243, 1)
    chatSessionInputBarControl.pluginBoardView.contentView.backgroundColor = RGBA(234, 237, 243, 1)
    
    //修改輸入框
    chatSessionInputBarControl.inputTextView.layer.borderWidth = 0
    chatSessionInputBarControl.inputTextView.layer.cornerRadius = 6

    //去除發(fā)送地址功能
    chatSessionInputBarControl.pluginBoardView.removeItem(at: 1003)
    
    //添加擴展功能
    chatSessionInputBarControl.pluginBoardView.insertItem(with: UIImage(named: "liaotian23"), title: "名片", tag: 202)
    
    //自定義消息
    register(BusinessCardMessageCell.self, forMessageClass: BusinessCardMessage.self)
}

//MARK:-擴展功能板的點擊回調
override func pluginBoardView(_ pluginBoardView: RCPluginBoardView!, clickedItemWithTag tag: Int) {
    super.pluginBoardView(pluginBoardView, clickedItemWithTag: tag)

    weak var weakSelf = self
    switch tag {
    case 202:  //名片
        //添加你需要的操作
    default: break
    }
}

//MARK:-長按消息的回調
override func didLongTouchMessageCell(_ model: RCMessageModel!, in view: UIView!) {
    super.didLongTouchMessageCell(model, in: view)
}
override func getLongTouchMessageCellMenuList(_ model: RCMessageModel!) -> [UIMenuItem]! {
    var menuItems: [UIMenuItem] = super.getLongTouchMessageCellMenuList(model)
    
    //設置某個類型不可撤回,為名片消息添加轉發(fā)功能
    switch model.objectName {
    case RCXXXXXXXXCellKey:
        for i in 0 ..< menuItems.count {
            if menuItems[i].title != "撤回" { continue }
            menuItems.remove(at: i)
            break
        }
        
    case RCBusinessCardCellKey:
        let transmitItem: UIMenuItem = UIMenuItem(title: "轉發(fā)", action: #selector(transmitMessageAction))
        menuItems.insert(transmitItem, at: 0)
        transmitMessage = model
    default:
        break
    }
    return menuItems
}

//MARK:-轉發(fā)消息
@objc func transmitMessageAction() {
    //添加你需要的操作垄潮,如跳轉到列表頁面選擇好友或者群來轉發(fā)
}

//MARK:-點擊位置消息跳轉到自定義地圖頁面(自定義類繼承RCLocationViewController烹卒,方便自定義UI)
override func presentLocationViewController(_ locationMessageContent: RCLocationMessage!) {
    let vc = RCIMLocationVC()
    vc.location = locationMessageContent.location
    vc.locationName = locationMessageContent.locationName
    pushViewControllerHideBar(vc, animated: true)
}

以上是我對接融云時候需要做的一些處理闷盔,大家對上述處理方式存在疑問或存在隱藏bug,請不吝留言旅急,如果對你有用的話逢勾,點個贊哦。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末藐吮,一起剝皮案震驚了整個濱河市溺拱,隨后出現的幾起案子,更是在濱河造成了極大的恐慌谣辞,老刑警劉巖迫摔,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異泥从,居然都是意外死亡句占,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進店門躯嫉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來纱烘,“玉大人,你說我怎么就攤上這事祈餐±奚叮” “怎么了?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵昼弟,是天一觀的道長啤它。 經常有香客問我,道長舱痘,這世上最難降的妖魔是什么变骡? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮芭逝,結果婚禮上塌碌,老公的妹妹穿的比我還像新娘。我一直安慰自己旬盯,他們只是感情好台妆,可當我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著胖翰,像睡著了一般接剩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上萨咳,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天懊缺,我揣著相機與錄音,去河邊找鬼培他。 笑死鹃两,一個胖子當著我的面吹牛遗座,可吹牛的內容都是我干的。 我是一名探鬼主播俊扳,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼途蒋,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了馋记?” 一聲冷哼從身側響起号坡,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎抗果,沒想到半個月后筋帖,有當地人在樹林里發(fā)現了一具尸體奸晴,經...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡冤馏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了寄啼。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片逮光。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖墩划,靈堂內的尸體忽然破棺而出涕刚,到底是詐尸還是另有隱情,我是刑警寧澤乙帮,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布杜漠,位于F島的核電站,受9級特大地震影響察净,放射性物質發(fā)生泄漏驾茴。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一氢卡、第九天 我趴在偏房一處隱蔽的房頂上張望锈至。 院中可真熱鬧,春花似錦译秦、人聲如沸峡捡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽们拙。三九已至,卻和暖如春阁吝,著一層夾襖步出監(jiān)牢的瞬間砚婆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工求摇, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留射沟,地道東北人殊者。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像验夯,于是被迫代替她去往敵國和親猖吴。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,722評論 2 345