【问题标题】:Can't remove messages from chat view controller when switching to another chat切换到另一个聊天时无法从聊天视图控制器中删除消息
【发布时间】:2017-10-23 20:38:52
【问题描述】:

下面是我的 viewDidAppear 函数,它仅在用户第一次打开聊天时成功加载所有以前的消息。之后,当用户退出聊天然后开始另一个聊天时,来自上一个聊天的消息会加载到顶部,特定于最近聊天的消息会添加到这些消息的末尾。显然不理想。单击chatVC的后退按钮退出时,我尝试从消息数组中删除所有消息(如下所示),但这会导致应用程序在尝试加载新聊天时崩溃。具体来说,它在覆盖 func collectionView(_ collectionView: JSQMessagesCollectionView!, messageDataForItemAt indexPath: IndexPath!) -> JSQMessageData! 上崩溃。 { 返回消息[indexPath.item] }(也如下所示)。

override func viewDidAppear(_ animated: Bool) {
    if presentedChatVCFromChatListVC{
        chatRef.child(chatListingID).child("messages").observe(.value, with: { snapshot in
            print("snapshot.value is \(snapshot.value)")
            for child in snapshot.children {
                let childData = child as! FIRDataSnapshot
                print("childData is \(childData)")
                if let dict = childData.value as? NSDictionary{
                    let mediaType = dict["MediaType"] as! String
                    let senderId = dict["senderId"] as! String
                    let senderName = dict["senderName"] as! String

                    self.observeUsers(senderId)
                    switch mediaType {

                    case "TEXT":

                        let text = dict["text"] as! String
                        self.messages.append(JSQMessage(senderId: senderId, displayName: senderName, text: text))
                        self.collectionView.reloadData()

                    case "PHOTO":

                        let photo = JSQPhotoMediaItem(image: nil)
                        let fileUrl = dict["fileUrl"] as! String
                        let downloader = SDWebImageDownloader.shared()
                        downloader.downloadImage(with: URL(string: fileUrl)!, options: [], progress: nil, completed: { (image, data, error, finished) in
                            DispatchQueue.main.async(execute: {
                                photo?.image = image
                                self.collectionView.reloadData()
                            })
                        })

                        self.messages.append(JSQMessage(senderId: senderId, displayName: senderName, media: photo))
                        if self.senderId == senderId {
                            photo?.appliesMediaViewMaskAsOutgoing = true
                        }else{
                            photo?.appliesMediaViewMaskAsOutgoing = false
                        }

                    case "VIDEO":

                        let fileUrl = dict["fileUrl"] as! String
                        let video = URL(string: fileUrl)!
                        let videoItem = JSQVideoMediaItem(fileURL: video, isReadyToPlay: true)
                        self.messages.append(JSQMessage(senderId: senderId, displayName: senderName, media: videoItem))

                        if self.senderId == senderId {
                            videoItem?.appliesMediaViewMaskAsOutgoing = true
                        } else {
                            videoItem?.appliesMediaViewMaskAsOutgoing = false
                        }

                    default:
                        print("unknown data type")

                    }
                }
                self.collectionView.reloadData()
            }
        })
    }else{
        chatRef.queryOrdered(byChild: "otherUserID").queryEqual(toValue: otherUID).observe(.value, with:{
                snapshot in
            print("snapshot.value is \(snapshot.value)")
            for child in snapshot.children {
                let childData = child as! FIRDataSnapshot
                print("childData is \(childData)")
                if let dict = childData.value as? NSDictionary{
                    let temp = dict["userID"] as! String
                    if temp == userID{
                        chatListingID = dict["chatRoomKey"] as! String
                        self.chatRef.child(chatListingID).child("messages").observe(.value, with:{
                            snapshot in
                            for child1 in snapshot.children {
                                let childData1 = child1 as! FIRDataSnapshot
                                print("childData1 is \(childData1)")
                                if let dict1 = childData1.value as? NSDictionary{
                                    let mediaType = dict1["MediaType"] as! String
                                    let senderId = dict1["senderId"] as! String
                                    let senderName = dict1["senderName"] as! String

                                    self.observeUsers(senderId)
                                    switch mediaType {

                                    case "TEXT":

                                        let text = dict1["text"] as! String
                                        self.messages.append(JSQMessage(senderId: senderId, displayName: senderName, text: text))
                                        self.collectionView.reloadData()

                                    case "PHOTO":

                                        let photo = JSQPhotoMediaItem(image: nil)
                                        let fileUrl = dict1["fileUrl"] as! String
                                        let downloader = SDWebImageDownloader.shared()
                                        downloader.downloadImage(with: URL(string: fileUrl)!, options: [], progress: nil, completed: { (image, data, error, finished) in
                                            DispatchQueue.main.async(execute: {
                                                photo?.image = image
                                                self.collectionView.reloadData()
                                            })
                                        })

                                        self.messages.append(JSQMessage(senderId: senderId, displayName: senderName, media: photo))
                                        if self.senderId == senderId {
                                            photo?.appliesMediaViewMaskAsOutgoing = true
                                        }else{
                                            photo?.appliesMediaViewMaskAsOutgoing = false
                                        }

                                    case "VIDEO":

                                        let fileUrl = dict1["fileUrl"] as! String
                                        let video = URL(string: fileUrl)!
                                        let videoItem = JSQVideoMediaItem(fileURL: video, isReadyToPlay: true)
                                        self.messages.append(JSQMessage(senderId: senderId, displayName: senderName, media: videoItem))

                                        if self.senderId == senderId {
                                            videoItem?.appliesMediaViewMaskAsOutgoing = true
                                        } else {
                                            videoItem?.appliesMediaViewMaskAsOutgoing = false
                                        }

                                    default:
                                        print("unknown data type")
                                    }
                                }
                            }
                        })
                    }
                }
            self.collectionView.reloadData()
            }
        })
    }
    observeTyping()
}
override func collectionView(_ collectionView: JSQMessagesCollectionView!, messageDataForItemAt indexPath: IndexPath!) -> JSQMessageData! {
    return messages[indexPath.item]
}
func backButtonDidClick(){
    self.messages.removeAll()
    dismiss(animated: true, completion: nil)
}

此外,在“self.messages.removeAll()”之后添加“self.collectionView.reloadData()”会导致进入另一个聊天时错误地开始空白。比崩溃好一点,但也不是很多。如何清除消息以便更改用户消息的人会导致聊天视图控制器仅加载该用户的消息,而不是先前加载的消息或根本不加载?

【问题讨论】:

    标签: swift firebase-realtime-database uicollectionview chat jsqmessagesviewcontroller


    【解决方案1】:

    这是因为您已将所有逻辑都放在viewDidAppear 中,此方法没有像您在这里假设的那样频繁调用。因此,当您在其他地方导航时,视图不会被破坏,因此当您返回视图时会更快。您应该将此逻辑移到另一个函数中。只将东西放在设置视图 I.E 的 viewDidAppear 中。设置背景颜色。您可能希望此逻辑出现在您的 viewDidLoad() 中,这将分配更多您正在寻找的行为。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-29
      相关资源
      最近更新 更多