聊天消息无法正确更新

时间:2018-07-07 16:50:28

标签: ios swift firebase google-cloud-firestore

这是chatViewController的完整代码。每次单击“发送”按钮时,文本消息都会重复一些,并飞出文本框,如下图所示。

Look at this picture

但是,当我退出聊天并重新输入时,那些开箱即用的消息都消失了。这不是因为Array中的消息重复,我认为应该是由于Cache问题或更新机制错误。 每当我关闭聊天并重新输入时,不存在跳出文本框聊天的功能,一切都很好。如果我未单击“发送消息”,则消息全部重新加载正常。

仅当我单击发送消息时,会有一些(不是全部)消息重复出现并跳出框外。当我退出聊天并重新输入时,开箱即用的聊天将消失,并且一切正常。

我咨询了其他看过我的代码的程序员,并说这很可能是因为当您单击发送按钮时,它将获取完整的数据集,并且当您在屏幕上显示时,屏幕上的旧数据(即使您已删除)他们从您的数组)弄乱了新数据。我问他们如何解决这个问题,他们不确定,因为他们是Android开发人员。

我正在思考的思路:缓存旧消息,添加新消息,但确保它们与缓存中的旧消息不冲突?

import UIKit
    import Firebase
    import FirebaseStorage
    import FirebaseDatabase
    import FirebaseFirestore
    import CoreData

class ChatViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {


    @IBOutlet weak var collectionView: UICollectionView!
    @IBOutlet weak var messageText: UITextField!

    @IBAction func back(_ sender: Any) {
        back()
    }
    @IBOutlet weak var profileImage: UIImageView!
    @IBOutlet weak var usernameLabel: UILabel!
    @IBAction func sendTextMessage(_ sender: Any) {
    chats.removeAll()
    self.sendDataToDatabase(message: messageText.text!)
    messageText.text = nil
    self.loadPosts()
    self.loadPostsReceivedMessage()
        delayCompletionHandler {
          self.collectionView.reloadData()
        }
    }
    let cellIdentifier = "chatNow"
    var chats = [Chat]()
    var posts = [Post]()
    var receiverIDNumber = ""
    var profileImageUrl = ""
    var senderString = ""
    var conversationsCounterInt = 0
    var timestamp = String(Int(Date().timeIntervalSince1970))
    let db = Firestore.firestore()

    override func viewDidLoad() {
        super.viewDidLoad()
        let yourNibName = UINib(nibName: "ChatCollectionViewCell", bundle: nil)
        collectionView.register(yourNibName, forCellWithReuseIdentifier: cellIdentifier)
        self.collectionView.dataSource = self
        self.collectionView.delegate = self
        print(receiverIDNumber)
        usernameLabel.text! = receiverIDNumber
        setUpProfile()
        set()
       print("is there anything"+profileImageUrl)
        //Making circular profile picture
        profileImage.layer.borderWidth = 1.0
        profileImage.layer.masksToBounds = false
        profileImage.layer.borderColor = UIColor.white.cgColor
        profileImage.layer.cornerRadius = profileImage.frame.size.width / 2
        profileImage.clipsToBounds = true
        print("waka"+senderString)
        self.loadPosts()
        self.loadPostsReceivedMessage()
        delayCompletionHandler {
            self.collectionView.reloadData()
        }
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        navigationItem.title = "Chat"
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


    func back() {
        let storyboard = UIStoryboard(name: "Main" , bundle: nil)
        let tabViewController = storyboard.instantiateViewController(withIdentifier: "tab")
        present(tabViewController, animated: true,completion: nil)
    }


    func set() {
        let uid = Auth.auth().currentUser?.uid
        let ref = Database.database().reference()
        ref.child("users").child(uid!).observeSingleEvent(of: .value, with: { (snapshot) in
            if let dic = snapshot.value as? [String: AnyObject] {
                self.senderString = dic["username"] as! String
                print("this"+self.senderString)
            }
        })
    }


   func sendDataToDatabase(message: String){
        let ref = Database.database().reference()
        let senderIDNumber = Auth.auth().currentUser?.uid
        let timeStampString = String(Int(Date().timeIntervalSince1970))
    db.collection("chats").addDocument(data: ["message": messageText.text!, "senderID": senderIDNumber!,"receiverID": receiverIDNumber,"timestamp": timeStampString,"profileUrl": profileImageUrl, "sender": self.senderString])
    { err in
        if let err = err {
            print("Error writing document: \(err)")
        } else {
            print("Document successfully written!")
        }
    }
    }


    func logout(){
        let storyboard = UIStoryboard(name: "Main" , bundle: nil)
        let loginViewController = storyboard.instantiateViewController(withIdentifier: "login")
        present(loginViewController, animated: true,completion: nil)
    }


    func delayCompletionHandler(completion:@escaping (() -> ())) {
        let delayInSeconds = 0.3
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + delayInSeconds) {
            completion()
        }
    }


    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int{
        return chats.count
    }

  func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell{
     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as! ChatCollectionViewCell    
         let senderIDNumber = Auth.auth().currentUser?.uid

    //Setup the messageReceived and messageSent
            if chats[indexPath.row].senderID == senderIDNumber {
            if let chatsText = chats[indexPath.row].message{
                let size = CGSize(width: 250, height: 1000)
                let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin)
                let estimatedFrame = NSString(string: chatsText).boundingRect(with: size, options: options, attributes: [NSAttributedStringKey.font : UIFont.systemFont(ofSize: 18)], context: nil)
                cell.messageSend.frame = CGRect(x:8,y:0,width:estimatedFrame.width + 16, height:estimatedFrame.height + 20)
                cell.textBubbleView.frame = CGRect(x:0,y:0,width:estimatedFrame.width + 16 + 8, height:estimatedFrame.height + 20)
             //showOutgoingMessage(text: chats[indexPath.row].message)
                cell.messageSend.text = chats[indexPath.row].message
        }
            }
        else {
                cell.messageReceived.text = chats[indexPath.row].message
                let chatsText = chats[indexPath.row].message
                let size = CGSize(width: 250, height: 1000)
                let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin)
                let estimatedFrame = NSString(string: chatsText!).boundingRect(with: size, options: options, attributes: [NSAttributedStringKey.font : UIFont.systemFont(ofSize: 18)], context: nil)
                cell.messageReceived.frame = CGRect(x:view.frame.width - estimatedFrame.width - 30,y:0,width:estimatedFrame.width + 16, height:estimatedFrame.height + 20)
                cell.textBubbleView.frame = CGRect(x:view.frame.width - estimatedFrame.width - 30,y:0,width:estimatedFrame.width + 16 + 4, height:estimatedFrame.height + 20)
        }
        return cell
    }

    func collectionView(_ collectionView: UICollectionView,
    layout collectionViewLayout: UICollectionViewLayout,
    sizeForItemAt indexPath: IndexPath) -> CGSize {
    if let chatsText = chats[indexPath.row].message {
        let size = CGSize(width: 250, height: 1000)
            let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin)
            let estimatedFrame = NSString(string: chatsText).boundingRect(with: size, options: options, attributes: [NSAttributedStringKey.font : UIFont.systemFont(ofSize: 18)], context: nil)
            return CGSize(width: view.frame.width, height: estimatedFrame.height + 20)
        }

        return CGSize(width: view.frame.width, height: 200)
    }



    //Get Message sent
    func loadPosts() {
        let senderIDNumber = Auth.auth().currentUser?.uid
    let chatsRef = db.collection ("chats").order (by: "timestamp", descending: false)
       let sentListener = chatsRef.whereField ("senderID", isEqualTo: senderIDNumber!)
        .whereField ("receiverID", isEqualTo: receiverIDNumber)
        .addSnapshotListener() {
            querySnapshot,
            error in
            guard let documentChanges = querySnapshot?.documentChanges else {
                print ("Error fetching documents: \(error!)")
                return
            }
            for documentChange in documentChanges {
                if (documentChange.type == .added) {
                    let data = documentChange.document.data ()
                    print("Message send: \(data)")
                    let messageText = data["message"] as? String
                    let senderIDNumber = data["senderID"] as? String
                    let receiverIDNumber = data["receiverID"] as? String
                    let timestamp = data["timestamp"] as? String
                    guard let sender = data["sender"] as? String else {return}
                   // let conversationsCounter = document.data()["conversationsCounter"] as? Int
                    guard let profileUrl = data["profileUrl"] as? String else { return}
                    let chat = Chat(messageTextString: messageText!, senderIDNumber: senderIDNumber!, receiverIDNumber: receiverIDNumber!, timeStampString: timestamp!, profileImageUrl: profileUrl, senderString: sender)
    self.chats.append(chat)
    print(self.chats)
            }
                }
                   }
    }


    //Get message received
    func loadPostsReceivedMessage() {
                let chatsRef = db.collection("chats").order(by: "timestamp", descending: false)
                print("thecurrentreceiver"+senderString)
                print("thecurrentsender"+receiverIDNumber)
            let receivedListener = chatsRef.whereField("receiverID", isEqualTo: senderString).whereField("sender", isEqualTo: receiverIDNumber)
            .addSnapshotListener() {
                querySnapshot,
                error in
                guard let documentChanges = querySnapshot?.documentChanges else {
                    print ("Error fetching documents: \(error!)")
                    return
                }
                for documentChange in documentChanges {
                    if (documentChange.type == .added) {
                        let data = documentChange.document.data ()
                        print("Message received: \(data)")
                        let messageText = data["message"] as? String
                        let senderIDNumber = data["senderID"] as? String
                        let receiverIDNumber = data["receiverID"] as? String
                        let timestamp = data["timestamp"] as? String
                        guard let sender = data["sender"] as? String else {return}
                        // let conversationsCounter = document.data()["conversationsCounter"] as? Int
                        guard let profileUrl = data["profileUrl"] as? String else { return}
                        let chat = Chat(messageTextString: messageText!, senderIDNumber: senderIDNumber!, receiverIDNumber: receiverIDNumber!, timeStampString: timestamp!, profileImageUrl: profileUrl, senderString: sender)
                        self.chats.append(chat)
                        print(self.chats)
                        self.chats.sort{$0.timestamp < $1.timestamp}
                        }
                }
    }
    }



    func setUpProfile() {
        guard let url = URL(string:  profileImageUrl) else { return}
        let task = URLSession.shared.dataTask(with: url){ data, reponse, error in
            if error != nil {
                print(error!)
            } else{
                DispatchQueue.main.async(execute: {
                self.profileImage.image = UIImage(data: data!)
                })

            }

        }
        task.resume()

    }

}

0 个答案:

没有答案
相关问题