以下は、ユーザーが最初にチャットを開いたときにのみ以前のすべてのメッセージを正常に読み込むviewDidAppear関数です。その後、ユーザがチャットを終了してから別のチャットを開始すると、直前のチャットのメッセージが最上部に表示され、最新のチャットに固有のメッセージがメッセージの最後に追加されます。明らかに理想的ではない。 chatVCの[戻る]ボタンをクリックして終了するとメッセージ配列からすべてのメッセージを削除しようとしましたが(下図参照)、新しいチャットを読み込もうとするとアプリケーションがクラッシュします。具体的には、オーバーライド関数のcollectionView(@ collectionView:JSQMessagesCollectionView!、messageDataForItemAt indexPath:IndexPath!)でクラッシュする - > JSQMessageData! { メッセージを返す[indexPath.item] }(下記も参照)。誤っ空白を始めさまざまなチャットに行くに "self.collectionView.reloadData()" の後に "self.messages.removeAll()" の結果を追加他のチャットに切り替えるときにチャットビューコントローラからメッセージを削除できない
またoverride func viewDidAppear(_ animated: Bool) {
if presentedChatVCFromChatListVC{
chatRef.child(chatListingID).child("messages").observe(.value, with: { snapshot in
print("snapshot.value is \(snapshot.value)")
for child in snapshot.children {
let childData = child as! FIRDataSnapshot
print("childData is \(childData)")
if let dict = childData.value as? NSDictionary{
let mediaType = dict["MediaType"] as! String
let senderId = dict["senderId"] as! String
let senderName = dict["senderName"] as! String
self.observeUsers(senderId)
switch mediaType {
case "TEXT":
let text = dict["text"] as! String
self.messages.append(JSQMessage(senderId: senderId, displayName: senderName, text: text))
self.collectionView.reloadData()
case "PHOTO":
let photo = JSQPhotoMediaItem(image: nil)
let fileUrl = dict["fileUrl"] as! String
let downloader = SDWebImageDownloader.shared()
downloader.downloadImage(with: URL(string: fileUrl)!, options: [], progress: nil, completed: { (image, data, error, finished) in
DispatchQueue.main.async(execute: {
photo?.image = image
self.collectionView.reloadData()
})
})
self.messages.append(JSQMessage(senderId: senderId, displayName: senderName, media: photo))
if self.senderId == senderId {
photo?.appliesMediaViewMaskAsOutgoing = true
}else{
photo?.appliesMediaViewMaskAsOutgoing = false
}
case "VIDEO":
let fileUrl = dict["fileUrl"] as! String
let video = URL(string: fileUrl)!
let videoItem = JSQVideoMediaItem(fileURL: video, isReadyToPlay: true)
self.messages.append(JSQMessage(senderId: senderId, displayName: senderName, media: videoItem))
if self.senderId == senderId {
videoItem?.appliesMediaViewMaskAsOutgoing = true
} else {
videoItem?.appliesMediaViewMaskAsOutgoing = false
}
default:
print("unknown data type")
}
}
self.collectionView.reloadData()
}
})
}else{
chatRef.queryOrdered(byChild: "otherUserID").queryEqual(toValue: otherUID).observe(.value, with:{
snapshot in
print("snapshot.value is \(snapshot.value)")
for child in snapshot.children {
let childData = child as! FIRDataSnapshot
print("childData is \(childData)")
if let dict = childData.value as? NSDictionary{
let temp = dict["userID"] as! String
if temp == userID{
chatListingID = dict["chatRoomKey"] as! String
self.chatRef.child(chatListingID).child("messages").observe(.value, with:{
snapshot in
for child1 in snapshot.children {
let childData1 = child1 as! FIRDataSnapshot
print("childData1 is \(childData1)")
if let dict1 = childData1.value as? NSDictionary{
let mediaType = dict1["MediaType"] as! String
let senderId = dict1["senderId"] as! String
let senderName = dict1["senderName"] as! String
self.observeUsers(senderId)
switch mediaType {
case "TEXT":
let text = dict1["text"] as! String
self.messages.append(JSQMessage(senderId: senderId, displayName: senderName, text: text))
self.collectionView.reloadData()
case "PHOTO":
let photo = JSQPhotoMediaItem(image: nil)
let fileUrl = dict1["fileUrl"] as! String
let downloader = SDWebImageDownloader.shared()
downloader.downloadImage(with: URL(string: fileUrl)!, options: [], progress: nil, completed: { (image, data, error, finished) in
DispatchQueue.main.async(execute: {
photo?.image = image
self.collectionView.reloadData()
})
})
self.messages.append(JSQMessage(senderId: senderId, displayName: senderName, media: photo))
if self.senderId == senderId {
photo?.appliesMediaViewMaskAsOutgoing = true
}else{
photo?.appliesMediaViewMaskAsOutgoing = false
}
case "VIDEO":
let fileUrl = dict1["fileUrl"] as! String
let video = URL(string: fileUrl)!
let videoItem = JSQVideoMediaItem(fileURL: video, isReadyToPlay: true)
self.messages.append(JSQMessage(senderId: senderId, displayName: senderName, media: videoItem))
if self.senderId == senderId {
videoItem?.appliesMediaViewMaskAsOutgoing = true
} else {
videoItem?.appliesMediaViewMaskAsOutgoing = false
}
default:
print("unknown data type")
}
}
}
})
}
}
self.collectionView.reloadData()
}
})
}
observeTyping()
}
override func collectionView(_ collectionView: JSQMessagesCollectionView!, messageDataForItemAt indexPath: IndexPath!) -> JSQMessageData! {
return messages[indexPath.item]
}
func backButtonDidClick(){
self.messages.removeAll()
dismiss(animated: true, completion: nil)
}
、。クラッシュより少し良いが、あまりない。チャット・ビュー・コントローラーのユーザー・メッセージの結果を誰が変更して、そのユーザーのメッセージをロードするだけで、以前にロードされたものや全くロードされていないものを変更することはできません。あなたは、このメソッドは、できるだけ頻繁にあなたがここで想定していると呼ばれていませんviewDidAppear
であなたのロジックのすべてを入れているので、