Taylor Simpson Taylor Simpson - 4 months ago 22
Swift Question

Issue with Duplicate Messages When navigating back to ViewController

I have a ViewController that shows the user more information, then they click on a button and it sends them to my messageView which is a JSQ ViewController. The JSQViewController uses the collection View classes. When the user navigates back to the more information view and then hits the button to navigate to the message view again, the collection view duplicates my chat bubbles. I think I need to reset something to nil, but I am not sure what to set and where to set it. Here is my code:

import UIKit
import Firebase
import JSQMessagesViewController


// MARK: Properties
var messages = [JSQMessage]()
var outgoingBubbleImageView: JSQMessagesBubbleImage!
var incomingBubbleImageView: JSQMessagesBubbleImage!
let rootReference = FIRDatabase.database().referenceFromURL("myHTTPSLINK")
var messageReference: FIRDatabaseReference!
var dataBaseMessageRef: FIRDatabaseReference!


class ChatViewController: JSQMessagesViewController{


var userContacedID: String = ""

var userToBeChatted : String = ""

var userIsTypingRef: FIRDatabaseReference!

var usersTypingQuery: FIRDatabaseQuery!

private var localTyping = false
var isTyping: Bool {
get {
return localTyping
}
set {
localTyping = newValue
userIsTypingRef.setValue(newValue)
}
}




override func viewDidLoad() {
super.viewDidLoad()



title = "Now Chatting With: " + userToBeChatted
setupBubbles()


// No avatars
collectionView!.collectionViewLayout.incomingAvatarViewSize = CGSizeZero
collectionView!.collectionViewLayout.outgoingAvatarViewSize = CGSizeZero

messageReference = rootReference.child("messages")

dataBaseMessageRef = messageReference.child("\(userToBeChatted)" + "\(FIRAuth.auth()?.currentUser?.displayName)")



print ("This users being messaged is: ", userToBeChatted)


}



override func didPressSendButton(button: UIButton!, withMessageText text: String!, senderId: String!,
senderDisplayName: String!, date: NSDate!) {

let itemRef = dataBaseMessageRef.childByAutoId() // 1
let messageItem = [ // 2
"text": text,
"senderId": senderId,
"receiver" : userToBeChatted,
"senderName": FIRAuth.auth()?.currentUser?.displayName,
"receiverID": userContacedID
]
itemRef.setValue(messageItem) // 3

// 4
JSQSystemSoundPlayer.jsq_playMessageSentSound()

// 5
finishSendingMessage()
}



override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)


observeMessages()
observeTyping()
}



override func viewDidDisappear(animated: Bool) {




super.viewDidDisappear(animated)
}



override func collectionView(collectionView: JSQMessagesCollectionView!,
messageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageData! {
return messages[indexPath.item]
}

override func collectionView(collectionView: UICollectionView,
numberOfItemsInSection section: Int) -> Int {
return messages.count
}


override func collectionView(collectionView: JSQMessagesCollectionView!,
messageBubbleImageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageBubbleImageDataSource! {



let message = messages[indexPath.item] // 1


if message.senderId == senderId { // 2
return outgoingBubbleImageView
} else { // 3
return incomingBubbleImageView
}
}



override func collectionView(collectionView: JSQMessagesCollectionView!,
avatarImageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageAvatarImageDataSource! {
return nil
}

private func setupBubbles() {
let factory = JSQMessagesBubbleImageFactory()
outgoingBubbleImageView = factory.outgoingMessagesBubbleImageWithColor(
UIColor.jsq_messageBubbleBlueColor())
incomingBubbleImageView = factory.incomingMessagesBubbleImageWithColor(
UIColor.jsq_messageBubbleRedColor())
}


func addMessage(id: String, text: String) {
let message = JSQMessage(senderId: id, displayName: FIRAuth.auth()?.currentUser?.displayName , text: text)
messages.append(message)
}



override func collectionView(collectionView: UICollectionView,
cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = super.collectionView(collectionView, cellForItemAtIndexPath: indexPath)
as! JSQMessagesCollectionViewCell

let message = messages[indexPath.item]

if message.senderId == senderId {
cell.textView!.textColor = UIColor.whiteColor()
} else {
cell.textView!.textColor = UIColor.whiteColor()
}

return cell
}




private func observeMessages() {

dataBaseMessageRef = messageReference.child("\(userToBeChatted)\(FIRAuth.auth()?.currentUser?.displayName as String!)")




let messagesQuery = dataBaseMessageRef.queryLimitedToLast(25)

messagesQuery.observeEventType(.ChildAdded, withBlock: { snapshot in
let id = snapshot.value!["senderId"] as! String
let text = snapshot.value!["text"] as! String
self.addMessage(id, text: text)
self.finishReceivingMessage()
})
}


override func textViewDidChange(textView: UITextView) {
super.textViewDidChange(textView)
isTyping = textView.text != ""
}

private func observeTyping() {
let typingIndicatorRef = rootReference.child("typingIndicator")
userIsTypingRef = typingIndicatorRef.child(senderId)
userIsTypingRef.onDisconnectRemoveValue()

usersTypingQuery = typingIndicatorRef.queryOrderedByValue().queryEqualToValue(true)
usersTypingQuery.observeEventType(.Value, withBlock: { snapshot in
// You're the only one typing, don't show the indicator
if snapshot.childrenCount == 1 && self.isTyping { return }

// Are there others typing?
self.showTypingIndicator = snapshot.childrenCount > 0
self.scrollToBottomAnimated(true)
})
}


}

Answer

in viewDidAppear before observeMessages() insert messages = ()