应用程序在dispatch_group.leave

时间:2017-06-26 19:30:38

标签: swift asynchronous grand-central-dispatch

我正在使用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 GraphicsServices GSEventRunModal + 161 frame #12: 0x000000010de0dc68 UIKit UIApplicationMain + 159   第13帧:0x000000010a5d4e4f精英俱乐部main + 111 at AppDelegate.swift:15 frame #14: 0x00000001100fc68d libdyld.dylib开始+ 1
  •   

0 个答案:

没有答案