腾讯云 自定义消息展示

最近在开发的过程中,有个需求就是自定义消息具体的需求看设计图效果,下方放出,并且记录一下开发过程,仅供学习参考

1.设计效果图展示

截屏2020-06-17 上午9.51.36.png

截屏2020-06-17 上午9.51.53.png

2.集成腾讯云SDK

具体的配置,我就不讲了,可以去看看官方文档,里面有详细介绍,
我的项目中主要是pod了下面的库:
#腾讯云即时通讯
pod 'TXIMSDK_TUIKit_iOS'

3.自定义消息其实没什么难度,就是创建一个继承至TUIMessageCell试图 把数据赋值上去

  • 我的项目中需要自定义好多种,但是都是换汤不换药,会了一种其他的都简单,难点都不在这里,下面我贴出我的其中的一种自定义试图代码
class WMFinshWishCell: TUIMessageCell {
    
    
    lazy var bgView:UIView = {
        let view = UIView()
        view.backgroundColor = UIColor.white
        view.layer.cornerRadius = 5
        view.layer.masksToBounds = true
        return view
    }()
    lazy var titleLabel:YYLabel = {
        let view = YYLabel()
        view.font = WMFontBold(14)
        view.textColor = color("#333333")
        view.numberOfLines = 0
        return view
    }()
    lazy var timeLabel:YYLabel = {
        let view = YYLabel()
        view.font = WMFont(11)
        view.textColor = color("#999999")
        return view
    }()
    
    lazy var wishButton:UIButton = {
        let view = UIButton()
        view.layer.cornerRadius = 3
        view.layer.masksToBounds = true
        view.setTitle("心愿", for: .normal)
        view.setTitle("约会", for: .selected)
        view.titleLabel?.font = WMFont(11.5)
        view.setBackgroundImage(UIImage(color: UIColor(hexString: "#E8B916")!), for: .normal)
        view.setBackgroundImage(UIImage(color: UIColor(hexString: "#FB5798")!), for: .selected)
        return view
    }()
    
    lazy var shopView:shopDetialView = {
        let view = shopDetialView()
        view.backgroundColor = color("#EEEEEE")
        view.layer.cornerRadius = 3
        view.layer.masksToBounds = true
        return view
    }()
    
    lazy var contentLabel:YYLabel = {
        let view = YYLabel()
        view.font = WMFont(10)
        view.textColor = color("#333333")
        view.numberOfLines = 0
        return view
    }()
    
    lazy var tipLabel:YYLabel = {
        let view = YYLabel()
        view.font = WMFont(10)
        view.textColor = color("#F14545")
        view.numberOfLines = 0
        return view
    }()
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        self.avatarView.isHidden = true
        
        //Tip:这里如果需要显示头像就添加到containview上、否则添加到self上
        addSubview(bgView)
        bgView.addSubview(titleLabel)
        bgView.addSubview(timeLabel)
        bgView.addSubview(wishButton)
        bgView.addSubview(shopView)
        bgView.addSubview(contentLabel)
        bgView.addSubview(tipLabel)
        
        bgView.snp.makeConstraints { (make) in
            make.left.equalTo(WMRatio(12))
            make.top.equalToSuperview()
            make.bottom.equalTo(-WMRatio(12))
            make.width.equalTo(iphone.width - WMRatio(24))
        }
    }
    
    override func fill(with data: TCommonCellData!) {
        super.fill(with: data)
        
        guard let data = data as? WMFinishWishCellData else {
            return
        }
        
        
        titleLabel.text = data.model?.title?.stringValue
        timeLabel.text = data.model?.time?.stringValue.transformTimeChuoToTime(dateFormat: "yyyy-MM-dd HH:mm")
        wishButton.isSelected = data.model?.type == 1 ? false : true
        shopView.shopImg.yy_setImage(with: URL(string: data.model?.shop_img?.stringValue ?? ""), placeholder: UIImage(named: ""))
        shopView.shopTitle.text = data.model?.shop_title?.stringValue
        shopView.priceLabel.text = data.model?.shop_price?.stringValue
        contentLabel.text = data.model?.content
        tipLabel.text = data.model?.tip?.stringValue
        
        titleLabel.frame = data.titleFram
        timeLabel.frame = data.timeFram
        wishButton.frame = data.wishFram
        shopView.frame = data.shopFram
        contentLabel.frame = data.contentFram
        tipLabel.frame = data.tipFram
      
    }

    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func awakeFromNib() {
        super.awakeFromNib()
        
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

       
    }

}

//MARK:设置商品详情试图
extension WMFinshWishCell {
    
    
    
    class shopDetialView:UIView{
        
        lazy var shopImg:UIImageView = {
            let view = UIImageView()
            return view
        }()
        lazy var shopTitle:UILabel = {
            let view = UILabel()
            view.font = WMFont(14)
            view.textColor = color("#333333")
            return view
        }()
        
        lazy var priceLabel:UILabel = {
            let view = UILabel()
            view.font = WMFont(14)
            view.textColor = color("#F14545")
            return view
        }()
        
        
        override init(frame: CGRect) {
            super.init(frame: frame)
            
            addSubview(shopImg)
            addSubview(shopTitle)
            addSubview(priceLabel)
           
            shopImg.snp.makeConstraints { (make) in
                make.left.top.bottom.equalToSuperview()
                make.height.width.equalTo(WMRatio(50))
            }
            
            shopTitle.snp.makeConstraints { (make) in
                make.left.equalTo(shopImg.snp.right).offset(WMRatio(8))
                make.top.equalTo(shopImg.snp.top).offset(WMRatio(5))
                make.right.equalToSuperview().offset(-WMRatio(12))
            }
            
            priceLabel.snp.makeConstraints { (make) in
                 make.left.equalTo(shopImg.snp.right).offset(WMRatio(8))
                 make.top.equalTo(shopTitle.snp.bottom).offset(8)
            }
            
        }
        
        required init?(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        
    }
    
}

4.实现代理方法TUIChatControllerDelegate

  • 主要是两个代理方法 一个是 func chatController(_ controller: TUIChatController!, onShowMessageData cellData: TUIMessageCellData!) -> TUIMessageCell! 另一个 func chatController(_ controller: TUIChatController!, onNewMessage msg: TIMMessage!) -> TUIMessageCellData! ,具体的代码实现在下面
//因为我的项目种自定义的消息太多,所以下面的代码中我删掉了一部分,和项目代码不一样,但实现方法都一样 ,在这个过程中 我 遇到了一个问题 就是 传数据的时候,因为有好多种类型,我需要传一个style,但是腾讯云外接的只有一个data,我把自己的model已经生成了data了,然后把它放在字典里,再转换成data,但是这样写会崩溃,报错说里面不是json,当然,你也可以把数据全部转换成json字符串写,也没问题,但是我懒得改了就直接用NSKeyedUnarchiver归档解档存取数据了,具体的看你们自己,想用什么用什么

func chatController(_ controller: TUIChatController!, onNewMessage msg: TIMMessage!) -> TUIMessageCellData! {
        
        let elem = msg.getElem(0)
        if (elem?.isKind(of: TIMCustomElem.self))!{
            let customElem = elem as? TIMCustomElem
            guard let dict = NSKeyedUnarchiver.unarchiveObject(with: customElem!.data) as? Dictionary<String, Any>  else {
                return nil
            }
            let style = Number(dict)["type"].intValue
            let itemData = dict["model"] as! Data
            if (style == 2) {
                let cellData = WMFinishWishCellData(direction: msg.isSelf() ? TMsgDirection.MsgDirectionOutgoing : TMsgDirection.MsgDirectionIncoming)
                let obj = try? JSONDecoder().decode(WMFinishWishCellData.finshwishModel.self, from: itemData)
                cellData.model = obj
                return cellData
            }
            else{
                return nil
            }
        }
        return nil
    }
    
    func chatController(_ controller: TUIChatController!, onShowMessageData cellData: TUIMessageCellData!) -> TUIMessageCell! {
        
      
        if cellData.isKind(of: WMFinishWishCellData.self) {
            let cell = WMFinshWishCell(style: .default, reuseIdentifier: "finshCell2")
            cell.fill(with: cellData)
            return cell
        }
        return nil
    }

5.以上就已经实现了自定义消息 ,讲讲实现过程中遇到的问题

  其实自定义消息没什么难点,但是我的项目中,我遇到了几个问题:
1.有些消息只可以自己看的到,对方看不到。
2.可以自动发送一条文本消息。
3.对方在我这边发送了一个赴约申请时,他那边需要收到的是同意拒绝消息。
4.删除上一条消息。

6.问题的解决方式

1.在你继承TUIMessageCellData的数据中多传一个isSend值判断是不是发送方是的话就做处理,这个在文章第4点第一个代理方法中判断 返回nil  数据不传出去
        if obj?.isSend?.intValue == 0 {
                    return nil
                }
2.发送一个通知,在源码中监听发送
 NotificationCenter.default.post(name: NSNotification.Name(rawValue: "发送默认消息"), object: nil, userInfo: ["text":"已帮你完成心愿"])
3.监听消息的接收,开始我用的是代理的方法func chatController(_ controller: TUIChatController!, onNewMessage msg: TIMMessage!) -> TUIMessageCellData!,但是发现有个问题就是第一次他会加载所有的聊天记录,这显然不是我想要的,所以我们监听源码中的接收消息的通知 根据内容做判断
 //监听收到的信息
        NotificationCenter.default.addObserver(self, selector: #selector(onReserveNewsMsg(notic:)), name: NSNotification.Name(rawValue: "TUIKitNotification_TIMMessageListener"), object: nil),实现监听方法
4.这里我从源码里面去写了一个删除数据的方法 外接出来 ,在TUIMessageController类中实现- (void)onDeleteOld:(TUIMessageCellData *)data方法,实现内容如下:
-(void)onDeleteOld:(TUIMessageCellData *)data
{
    
    _menuUIMsg = data;
    TIMMessage *imMsg = _menuUIMsg.innerMessage;
    if(imMsg == nil){
        return;
    }
    if([imMsg remove]){
        [self.tableView beginUpdates];
        NSInteger index = [_uiMsgs indexOfObject:_menuUIMsg];
        [_uiMsgs removeObjectAtIndex:index];
        [_heightCache removeObjectAtIndex:index];
        [self.tableView deleteRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:index inSection:0]] withRowAnimation:UITableViewRowAnimationFade];

        [self.tableView endUpdates];
    }
}

7.总结

自定义消息没多大难度,看你们的需求,理解里面的执行步骤,一步一步来,先完善发送方,再来接收方,你就会发现,其实蛮简单!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342