You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

解决Type 'ChatViewController'不遵循MessagesDataSource协议问题

解决MessageKit中MessagesDataSource协议适配错误及重复声明问题

问题现象

  • 运行代码时触发错误:Type 'ChatViewController' does not conform to protocol 'MessagesDataSource'
  • 使用Xcode自动修复的「添加协议存根」功能后,出现新错误:Invalid redeclaration of 'currentSender()'

问题原因

MessageKit版本更新后,MessagesDataSource协议对currentSender的要求从实例方法改为了计算属性。你原有代码实现的是旧版本要求的func currentSender() -> SenderType方法,而自动修复生成的是新版本要求的var currentSender: SenderType属性,二者名称冲突导致重复声明错误。

解决步骤

  1. 删除原有代码中的func currentSender() -> SenderType方法
  2. 保留自动生成的var currentSender: MessageKit.SenderType计算属性,将原方法内的逻辑迁移到该属性的getter中

修改后的完整扩展代码

extension ChatViewController: MessagesDataSource, MessagesLayoutDelegate, MessagesDisplayDelegate {
    // 替换原方法为计算属性,适配新版MessageKit协议要求
    var currentSender: MessageKit.SenderType {
        guard let sender = selfSender else {
            fatalError("Self Sender is nil, email should be cached")
        }
        return sender
    }
    
    func messageForItem(at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> MessageType {
        return messages[indexPath.section]
    }
    
    func numberOfSections(in messagesCollectionView: MessagesCollectionView) -> Int {
        return messages.count
    }
    
    func configureMediaMessageImageView(_ imageView: UIImageView, for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) {
        guard let message = message as? Message else {
            return
        }
        
        switch message.kind {
        case .photo(let media):
            guard let imageUrl = media.url else {
                return
            }
            
            imageView.sd_setImage(with: imageUrl)
            
        default:
            break
        }
    }
    
    func backgroundColor(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> UIColor {
        let sender = message.sender
        if sender.senderId == selfSender?.senderId {
            return .link
        }
        
        return .secondarySystemBackground
    }
    
    func configureAvatarView(_ avatarView: AvatarView, for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) {
        let sender = message.sender
        if sender.senderId == selfSender?.senderId {
            if let currentUserImageUrl = self.senderPhotoUrl {
                avatarView.sd_setImage(with: currentUserImageUrl)
            } else {
                guard let email = UserDefaults.standard.value(forKey: Keys.email.rawValue) as? String else {
                    return
                }
                
                let safeEmail = DatabaseManager.safeEmail(emailAddress: email)
                let path = "images/\(safeEmail)_profile_picture.png"
                
                StorageManager.shared.downloadURL(for: path) { [weak self] result in
                    switch result {
                    case .success(let url):
                        DispatchQueue.main.async {
                            self?.senderPhotoUrl = url
                            avatarView.sd_setImage(with: url)
                        }
                    case .failure(let error):
                        print("Failed to download image url: \(error)")
                    }
                }
            }
        } else {
            if let otherUserImageUrl = self.otherUserPhotoUrl {
                avatarView.sd_setImage(with: otherUserImageUrl)
            } else {
                let email = self.otherUserEmail
                
                let safeEmail = DatabaseManager.safeEmail(emailAddress: email)
                let path = "images/\(safeEmail)_profile_picture.png"
                
                StorageManager.shared.downloadURL(for: path) { [weak self] result in
                    switch result {
                    case .success(let url):
                        DispatchQueue.main.async {
                            self?.otherUserPhotoUrl = url
                            avatarView.sd_setImage(with: url)
                        }
                    case .failure(let error):
                        print("Failed to download image url: \(error)")
                    }
                }
            }
        }
    }
}

补充说明

  • 此适配方案针对MessageKit 4.x及以上版本,这些版本将currentSender从方法改为了计算属性
  • 若你使用的是旧版本MessageKit,需检查是否遗漏了其他协议必填方法,但从自动修复的结果判断,你当前使用的是新版本

内容的提问来源于stack exchange,提问作者user21138718

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 19:27:22