I am attempting to implement JSQMesages to my app, however, I can't figure out why when I press the send button all of the messages disappear. I have went step by step and can't figure it out, when the chat initially loads, everything is there. But then the send button does something that makes it all vanish?
Any ideas?
//
// JSQMessagesViewController.swift
// ACSS
//
// Created by Trever on 10/21/15.
// Copyright © 2015 trever.me. All rights reserved.
//
import UIKit
class MessagesViewController: JSQMessagesViewController {
// Refresh Messages
var timer : NSTimer!
// Don't double load!
var isLoading = false
// ID for this chatroom. Can have mutliple users
var chatroom = ""
// Currently only set up for two people
var currentUser : TradeUser?
var otherUser : PFUser?
//Value collection so don't double load too much
var avatars = [String:JSQMessagesAvatarImage]()
//Array of messages
var messages = [JSQMessage]()
//Collection of users
var users = [String : PFObject]()
// Chat bubbles for conversation
var outgoingBubbleImageView : JSQMessagesBubbleImage!
var incomingBubbleImageView : JSQMessagesBubbleImage!
override func viewDidLoad() {
super.viewDidLoad()
// Create a chatroom for each pair. Same for both
// Smaller ID first
self.senderId = TradeUser.currentUser()?.objectId
self.chatroom = currentUser!.objectId > otherUser!.objectId ?
"\(currentUser!.objectId!)-\(otherUser!.objectId!)" :
"\(otherUser!.objectId!)-\(currentUser!.objectId!)"
//Setup chat bubbles
let bubbleFactory = JSQMessagesBubbleImageFactory()
outgoingBubbleImageView = bubbleFactory.outgoingMessagesBubbleImageWithColor(UIColor.jsq_messageBubbleLightGrayColor())
incomingBubbleImageView = bubbleFactory.incomingMessagesBubbleImageWithColor(UIColor.jsq_messageBubbleBlueColor())
//Loading...
isLoading = false
self.loadMessages()
//Check for new messages every 5 seconds
timer = NSTimer.scheduledTimerWithTimeInterval(5.0, target: self, selector: "loadMessages", userInfo: nil, repeats: true)
self.senderDisplayName = "test"
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(true)
self.collectionView?.collectionViewLayout.springinessEnabled = true
}
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
// when they leave this screen, stop checking for messages
timer.invalidate()
}
func loadMessages() {
if !isLoading {
isLoading = true
let message_last = messages.last
//Fetch Messages
let query = TradeChat.query()!
query.whereKey("chatRoom", equalTo: chatroom)
//Time Base Pagination
if message_last != nil {
query.whereKey("createdAt", greaterThan: message_last!.date)
}
// Get senders ID
query.includeKey("sender")
//Show Messages in order
query.orderByAscending("createdAt")
query.findObjectsInBackgroundWithBlock({ (objects, error) -> Void in
if error == nil {
for object in objects! {
// Go through each message and create a message for display
let tradeChat = object as! PFObject
let senderObject = tradeChat.objectForKey("sender") as! PFObject
let senderFirstName = senderObject.objectForKey("firstName") as! String
let createdAt = tradeChat.createdAt
let text = tradeChat.objectForKey("chatText") as! String
let message = JSQTextMessage(senderId: senderObject.objectId!, senderDisplayName: senderFirstName, date: createdAt, text: text)
self.messages.append(message)
print(self.messages.count)
//Chache the user object for later
self.users[senderObject.objectId!] = senderObject
}
if !objects!.isEmpty {
self.finishReceivingMessage()
}
}
self.isLoading = false
})
}
}
override func didPressSendButton(button: UIButton!, withMessageText text: String!, senderId: String!, senderDisplayName: String!, date: NSDate!) {
// When they hit send. Save the message
let tradeChat = TradeChat()
tradeChat.chatRoom = chatroom
tradeChat.sender = TradeUser.currentUser()!
tradeChat.chatText = text
tradeChat.saveInBackgroundWithBlock { (succeeded, error) -> Void in
if error == nil {
JSQSystemSoundPlayer.jsq_playMessageSentSound()
self.loadMessages()
}
}
self.finishSendingMessage()
}
override func collectionView(collectionView: JSQMessagesCollectionView!, messageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageData! {
return messages[indexPath.item]
}
override func collectionView(collectionView: JSQMessagesCollectionView!, messageBubbleImageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageBubbleImageDataSource! {
let message = messages[indexPath.item]
if message.senderId == self.senderId {
return outgoingBubbleImageView
} else {
return incomingBubbleImageView
}
}
override func collectionView(collectionView: JSQMessagesCollectionView!, avatarImageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageAvatarImageDataSource! {
let message = messages[indexPath.item]
if self.avatars[message.senderId] == nil {
var imageView = JSQMessagesAvatarImage(placeholder: UIImage(named: "profile"))
self.avatars[message.senderId] = imageView
let user = users[message.senderId]!
print(user)
var parseAvatar = PFFile()
var imageQuery = TradeUser.query()!
imageQuery.whereKey("objectId", equalTo: user.objectId!)
imageQuery.limit = 1
imageQuery.findObjectsInBackgroundWithBlock({ (images: [AnyObject]?, error: NSError?) -> Void in
if imageQuery.countObjects() == 0 {
return
} else {
for image in images! {
if image.objectForKey("profileImage") == nil {
return
} else {
let userPic = image.objectForKey("profileImage") as! PFFile
userPic.getDataInBackgroundWithBlock({ (imageData: NSData?, error: NSError?) -> Void in
if (error == nil) {
let image = UIImage(data: imageData!)
imageView.avatarImage = JSQMessagesAvatarImageFactory.circularAvatarImage(UIImage(data: imageData!), withDiameter: 30)
}
})
}
}
}
})
// Reload entire table now that the avatar is downloaded
self.collectionView?.reloadData()
}
return self.avatars[message.senderId]
}
override func collectionView(collectionView: JSQMessagesCollectionView!, attributedTextForMessageBubbleTopLabelAtIndexPath indexPath: NSIndexPath!) -> NSAttributedString! {
// Show the name every once and a while
let message = messages[indexPath.item]
if message.senderId == self.senderId {
return nil
}
if indexPath.item - 1 > 0 {
let prevMessage = messages[indexPath.item - 1]
if prevMessage.senderId == message.senderId {
return nil
}
}
let firstName = otherUser?.objectForKey("firstName") as! String
return NSAttributedString(string: firstName)
}
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
print("Found \(messages.count) messages")
return messages.count
}
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
// Grab the cell were about to show
let cell = super.collectionView(collectionView, cellForItemAtIndexPath: indexPath) as! JSQMessagesCollectionViewCell
//Customize it some
let message = messages[indexPath.item]
if message.senderId == self.senderId {
cell.textView?.textColor = UIColor.blackColor()
} else {
cell.textView?.textColor = UIColor.whiteColor()
}
return cell
}
override func collectionView(collectionView: JSQMessagesCollectionView!, layout collectionViewLayout: JSQMessagesCollectionViewFlowLayout!, heightForCellTopLabelAtIndexPath indexPath: NSIndexPath!) -> CGFloat {
// If were going to show the date/time, give it some height
if indexPath.item % 3 == 0 {
return kJSQMessagesCollectionViewCellLabelHeightDefault
}
return 0.0
}
override func collectionView(collectionView: JSQMessagesCollectionView!, layout collectionViewLayout: JSQMessagesCollectionViewFlowLayout!, heightForMessageBubbleTopLabelAtIndexPath indexPath: NSIndexPath!) -> CGFloat {
let message = messages[indexPath.item]
if message.senderId == self.senderId {
return 0.0
}
if indexPath.item - 1 > 0 {
let previousMessage = messages[indexPath.item - 1]
if previousMessage.senderId == message.senderId {
return 0.0
}
}
return kJSQMessagesCollectionViewCellLabelHeightDefault
}
override func collectionView(collectionView: JSQMessagesCollectionView!, layout collectionViewLayout: JSQMessagesCollectionViewFlowLayout!, heightForCellBottomLabelAtIndexPath indexPath: NSIndexPath!) -> CGFloat {
// more height logic
return 0.0
}
override func collectionView(collectionView: JSQMessagesCollectionView!, header headerView: JSQMessagesLoadEarlierHeaderView!, didTapLoadEarlierMessagesButton sender: UIButton!) {
print("tapped load earlier messages - need implementation")
}
}