我正在尝试在我的应用程序中实现 JSQMesages,但是,我无法弄清楚为什么当我按下发送按钮时所有消息都消失了。我一步一步走,无法弄清楚,当聊天最初加载时,一切都在那里。但是然后发送按钮做了什么让这一切都消失了?
有任何想法吗?
//
// 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")
}
}