firebaseswift3uicollectionviewjsqmessagesviewcontroller

Collection view not scroll smoothly when fetch data from firebase using Swift?


I am making the Chat app using JSQMessage library and Firebase back-end service. I got the problem when user send a lot of media messages like image or video. I also use SDWebImage library but it can not solve the problem. When i run my app in simulator, the collection view scroll smoothly but when i try in real device, it's terrible. So please help me to fix this. Appreciate your contribution.

This is the code where i fetch data

databaseReference.child("Message").child(fromId).child(toId).queryLimited(toLast: UInt(numberMess)).observe(.childAdded, with: { (snapshot) in

        if let dict = snapshot.value as? [String : Any] {
            let receiverId = dict["ReceiverId"] as? String ?? ""
            let senderId = dict["SenderId"] as? String ?? ""
            let time = dict["Time"] as? NSNumber ?? 0
            let mediatype = dict["MediaType"] as? String ?? ""
            let status = dict["Status"] as? String ?? ""
            let sendername = dict["SenderName"] as? String ?? ""
            let receivername = dict["ReceiverName"] as? String ?? ""

            if mediatype == "Text" {
                let text = dict["Text"] as! String
                let newJSQMess = JSQMessage(senderId: senderId, displayName: sendername, text: text)

                let newMess = Messages(TextString: text, SenderIdString: senderId, SenderNameString: sendername, ReceiverNameString: receivername, ReceiverIdString: receiverId, TimeNumber: time)

                if newMess.SenderId == self.senderId! {
                    newMess.ChatId = newMess.ReceiverId
                } else {
                    newMess.ChatId = newMess.SenderId
                }

                newMess.Status = status

                if newMess.ChatId == self.receiverId! {
                    self.Array_Messages.append(newJSQMess!)
                    self.ClassMessages.append(newMess)
                    DispatchQueue.main.async {
                        self.finishReceivingMessage()
                        self.collectionView.reloadData()
                    }
                }
            }

            else if mediatype == "Photo" {
                let photo = JSQPhotoMediaItem(image: nil)
                let PhotoUrl = dict["PhotoUrl"] as? String ?? ""

                let downloader = SDWebImageDownloader.shared()
                downloader.downloadImage(with: URL(string: PhotoUrl), options: [], progress: nil, completed: { (image, data, error, finished) in
                    DispatchQueue.main.async(execute: {
                        photo?.image = image
                        self.collectionView.reloadData()
                    })
                })
                self.showMediaData(senderId: senderId, displayName: sendername, text: "", ReceiverId: receiverId, Receivername: receivername, TimeNumber: time, media: photo!, Status: status, PhotoUrlString: PhotoUrl, ThumnailUrlString: "", VideoUrlString: "", StatusString: status)
            }

            else if mediatype == "Video" {
                let thumnailImage = dict["ThumnailImageUrl"] as! String
                let thumnailImageUrl = URL(string: thumnailImage)
                let data = try? Data(contentsOf: thumnailImageUrl!)

                let videoUrl = dict["VideoUrl"] as? String ?? ""
                let video = URL(string: videoUrl)

                let videoItem = JSQVideoMediaItem(fileURL: video!, isReadyToPlay: true, thumbnailImage: UIImage.sd_image(with: data!))

                self.showMediaData(senderId: senderId, displayName: sendername, text: "", ReceiverId: receiverId, Receivername: receivername, TimeNumber: time, media: videoItem, Status: status, PhotoUrlString: "", ThumnailUrlString: thumnailImage, VideoUrlString: videoUrl, StatusString: status)
            }
        }
    })    

// show media in chat log
        private func showMediaData(senderId: String, displayName: String, text: String, ReceiverId: String, Receivername : String, TimeNumber: NSNumber, media: JSQMediaItem, Status : String, PhotoUrlString : String, ThumnailUrlString : String, VideoUrlString : String, StatusString : String) {
            let newJSQMedia = JSQMessage(senderId: senderId, displayName: displayName, media: media)
            let newMess = Messages(TextString: text, SenderIdString: senderId, SenderNameString: displayName, ReceiverNameString: Receivername, ReceiverIdString: ReceiverId, TimeNumber: TimeNumber)

            if newMess.SenderId == self.senderId! {
                newMess.ChatId = newMess.ReceiverId
                media.appliesMediaViewMaskAsOutgoing = true
            } else {
                newMess.ChatId = newMess.SenderId
                media.appliesMediaViewMaskAsOutgoing = false
            }

            newMess.PhotoUrl = PhotoUrlString
            newMess.Status = StatusString

            if newMess.ChatId == self.receiverId! {
                self.Array_Messages.append(newJSQMedia!)
                self.ClassMessages.append(newMess)
                self.finishReceivingMessage()
                DispatchQueue.main.async() {
                    self.collectionView.reloadData()
                }
            }
        }

Solution

  • I found the solution for my bug. Seem the collectionView is reload a lot of time depend on number of sending message. So the solution is quite easy, just remove the collectionView reload data