我正在使用firebase DB开发社交应用。所以,我必须从我的数据库中获取一些数据才能将其显示在屏幕上。以下是我获取数据的函数:
@IBAction func writeMessageOnClick(_ sender: Any) {
let myGroup = DispatchGroup()
let ref1 = FIRDatabase.database().reference().child("chats")
let curUserUid = (FIRAuth.auth()?.currentUser?.uid)!
myGroup.enter()
ref1.observe(FIRDataEventType.value, with: { (snapshot) in
if snapshot.hasChildren() {
let postDict = snapshot.value as? [String : AnyObject] ?? [:]
for elem in postDict {
let valuesDict = elem.value as? [String : AnyObject] ?? [:]
for kv in valuesDict {
if kv.key == "name" && kv.value.contains(curUserUid) {
MainUsersList.currentChats.append(elem.key)
MessageAndLikes.channels.append(Channel(id: elem.key, name: kv.value as! String))
}
}
}
}
myGroup.leave()
})
myGroup.notify(queue: .main, execute: {
self.loadLastMsgs()
})
}
func loadLastMsgs() {
let myGroup2 = DispatchGroup()
if MainUsersList.currentChats.count > 0 {
for element in MainUsersList.currentChats {
let ref = FIRDatabase.database().reference().child("chats").child(element).child("messages")
myGroup2.enter()
ref.queryLimited(toLast: 1).observe(.childAdded, with: { snapshot in
if snapshot.hasChildren() {
MessageAndLikes.lastMsgs.append((snapshot.value as? [String : AnyObject] ?? [:])["text"] as! String)
MessageAndLikes.lastMsgsTime.append((snapshot.value as? [String : AnyObject] ?? [:])["time"] as! String)
}
myGroup2.leave()
})
}
}
myGroup2.notify(queue: .main, execute: {
var counter: Int = 0
for elem in MainUsersList.currentChats {
MainUsersList.chats.append(Chat(userUid: elem, userName: MainUsersList.friendsInfo[counter].userName, userImgLink: MainUsersList.friendsInfo[counter].userImgLink, lastMsg: MessageAndLikes.lastMsgs[counter], lastMsgTime: MessageAndLikes.lastMsgsTime[counter]))
counter += 1
}
self.ShowVC()
})
}
func ShowVC() {
let st = UIStoryboard(name:"Main", bundle: nil)
let anotherVC = st.instantiateViewController(withIdentifier: "messagesVC")
self.present(anotherVC, animated: true, completion: nil)
}
此代码对我来说是正确的。然后,我在chatVC中有一些代码,在用户聊天中显示消息(我只是从这里做个例子https://www.raywenderlich.com/140836/firebase-tutorial-real-time-chat-2) 当我尝试打印邮件并按下发送按钮时,出现此错误:http://imgur.com/a/QxpBc
override func didPressSend(_ button: UIButton!, withMessageText text: String!, senderId: String!, senderDisplayName: String!, date: Date!) {
// 1
let itemRef = messageRef.childByAutoId()
let date = Date()
let calendar = Calendar.current
let hour = calendar.component(.hour, from: date)
let minutes = calendar.component(.minute, from: date)
// 2
var min = "\(minutes)"
if min.characters.count == 1 {
min = "0" + "\(min)"
}
let fdate = "\(hour)" + ":" + "\(min)"
let messageItem = [
"senderId": senderId!,
"senderName": senderDisplayName!,
"text": text!,
"time": fdate
] as [String : Any]
// 3
itemRef.setValue(messageItem)
// 4
JSQSystemSoundPlayer.jsq_playMessageSentSound()
// 5
self.finishSendingMessage(animated: true)
isTyping = false
viewDidLoad()方法中的和observeMessages()函数:
private func observeMessages() {
let mul: MessageAndLikes = MessageAndLikes()
if AcceptUser.isClicked {
messageRef = channelRef!.child(AcceptUser.newChannelLink).child("messages")
}
else {
messageRef = channelRef!.child(MainUsersList.currentChats[mul.index]).child("messages")
}
let messageQuery = messageRef.queryLimited(toLast:25)
// We can use the observe method to listen for new
// messages being written to the Firebase DB
newMessageRefHandle = messageQuery.observe(.childAdded, with: { (snapshot) -> Void in
let messageData = snapshot.value as! Dictionary<String, String>
if let id = messageData["senderId"] as String!, let name = messageData["senderName"] as String!, let text = messageData["text"] as String!, let _ = messageData["time"] as String!, text.characters.count > 0 {
self.addMessage(withId: id, name: name, text: text)
self.finishReceivingMessage()
} else if let id = messageData["senderId"] as String!, let photoURL = messageData["photoURL"] as String! {
if let mediaItem = JSQPhotoMediaItem(maskAsOutgoing: id == self.senderId) {
self.addPhotoMessage(withId: id, key: snapshot.key, mediaItem: mediaItem)
if photoURL.hasPrefix("gs://") {
self.fetchImageDataAtURL(photoURL, forMediaItem: mediaItem, clearsPhotoMessageMapOnSuccessForKey: nil)
}
}
}
else {
print("Error! Could not decode message data")
}
})
// We can also use the observer method to listen for
// changes to existing messages.
// We use this to be notified when a photo has been stored
// to the Firebase Storage, so we can update the message data
/* updatedMessageRefHandle = messageRef.observe(.childChanged, with: { (snapshot) in
let key = snapshot.key
let messageData = snapshot.value as! Dictionary<String, String>
if let photoURL = messageData["photoURL"] as String! {
// The photo has been updated.
if let mediaItem = self.photoMessageMap[key] {
self.fetchImageDataAtURL(photoURL, forMediaItem: mediaItem, clearsPhotoMessageMapOnSuccessForKey: key)
}
}
}) */
}
据我所知,因为异步方法没有连接到dispatch_groups.leaves(),所以,请帮助我理解我的代码有什么问题。 附:当我从另一个VC访问它时,我的聊天不会崩溃,也不会调用writeMessageOnClick()。谢谢我提前!
- 线程#1:tid = 0x2019,0x0000000110094837 libdispatch.dylib
dispatch_group_leave + 58, queue = 'com.apple.main-thread', stop reason = EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) frame #0: 0x0000000110094837 libdispatch.dylib
dispatch_group_leave + 58 * frame#1: 0x000000010a5f3360精英 在MessageAndLikes.swift的俱乐部MainUsersList.(snapshot=0x0000608000439a20, myGroup2=0x0000600000492520) -> ()).(closure #1) + 2736 at MainUsersList.swift:216 frame #2: 0x000000010a57861c Elite Club
thunk + 60:0 第3帧:0x000000010a6d9fa4精英俱乐部__63-[FIRDatabaseQuery observeEventType:withBlock:withCancelBlock:]_block_invoke((null)=0x000060000004f780, snapshot=<unavailable>, prevName=<unavailable>) + 37 at FIRDatabaseQuery.m:361 [opt] frame #4: 0x000000010a7018a7 Elite Club
43- [FChildEventRegistration fireEvent:queue:] _ block_invoke.68((null)=)+ 88 at FChildEventRegistration.m:61 [opt] 帧#5:0x0000000110086978 libdispatch.dylib_dispatch_call_block_and_release + 12 frame #6: 0x00000001100b00cd libdispatch.dylib
_ dispatch_client_callout + 8 第7帧:0x00000001100908a4 libdispatch.dylib_dispatch_main_queue_callback_4CF + 406 frame #8: 0x000000010c9f0e49 CoreFoundation
__ CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE + 9 帧#9:0x000000010c9b637d CoreFoundation__CFRunLoopRun + 2205 frame #10: 0x000000010c9b5884 CoreFoundation
CFRunLoopRunSpecific + 420 帧#11:0x00000001111d5a6f GraphicsServicesGSEventRunModal + 161 frame #12: 0x000000010de0dc68 UIKit
UIApplicationMain + 159 第13帧:0x000000010a5d4e4f精英俱乐部main + 111 at AppDelegate.swift:15 frame #14: 0x00000001100fc68d libdyld.dylib
开始+ 1