Parse Messenger Chat Swift:消息乱序

时间:2016-01-24 04:27:39

标签: ios swift parse-platform chat messenger

最近我的ios使者遇到了一些麻烦。我一开始只提取短信,一切都很完美。当我试图从解析中获取图像时,我成功了;但是,饲料的顺序不正确。 它似乎忽略了" query.orderByAscending"完全...

 fetchMessages()
 {
    currentUser = PFUser.currentUser()!
    let query = PFQuery(className:"Messages")
    query.whereKey("convoid", equalTo:convoid)
    query.orderByAscending("createdAt")
    query.cachePolicy = .NetworkElseCache
    query.findObjectsInBackgroundWithBlock {
        (objects: [PFObject]?, error: NSError?) -> Void in
        if error == nil {
            dispatch_async(dispatch_get_main_queue()) {
            if let objects = objects {
              for object in objects {
                if(object["fileType"] as? String == "photo"){
                    if(object["senderId"] as? String == self.currentUser.objectId!){
                        let userImageFile = object["file"] as! PFFile
                        userImageFile.getDataInBackgroundWithBlock {
                            (imageData: NSData?, error: NSError?) -> Void in
                            if error == nil {
                                let imageddata = UIImage(data:imageData!)
                                let chatBubbleData = ChatBubbleData(text: "", image:imageddata, date: object.createdAt, type: .Mine)
                                self.addChatBubble(chatBubbleData)
                                self.chatBubbleDatas.append(chatBubbleData)
                            }
                        }
                    }else{
                        let userImagefile = object["file"] as! PFFile
                        userImagefile.getDataInBackgroundWithBlock {
                            (imageData: NSData?, error: NSError?) -> Void in
                            if error == nil {
                                let imageddata = UIImage(data:imageData!)
                                let chatBubbleData = ChatBubbleData(text: "", image:imageddata, date: object.createdAt, type: .Opponent)
                                self.addChatBubble(chatBubbleData)
                                self.chatBubbleDatas.append(chatBubbleData)

                            }
                        }
                    }
                }else{
                    if(object["senderId"] as? String == self.currentUser.objectId!){
                        let chatBubbleData = ChatBubbleData(text: object["text"] as? String, image:nil, date: object.createdAt, type: .Mine)
                            self.addChatBubble(chatBubbleData)
                            self.chatBubbleDatas.append(chatBubbleData)
                    }else{
                        let chatBubbleData = ChatBubbleData(text: object["text"] as? String, image:nil, date: object.createdAt, type: .Opponent)
                            self.addChatBubble(chatBubbleData)
                            self.chatBubbleDatas.append(chatBubbleData)
                    }

                }
                }
                }
            }
        } else {
            print("Error: \(error!) \(error!.userInfo)")
        }
    }
    self.messageCointainerScroll.contentSize = CGSizeMake(CGRectGetWidth(messageCointainerScroll.frame), lastChatBubbleY + internalPadding)
    self.addKeyboardNotifications()
}

除了消息视图没有以正确的顺序显示所有消息这一事实之外,一切都很有效。实际上,所有文本消息都是正确的顺序,但无论是什么情况,无论创建日期如何,消息图像总是会出现。我认为它必须与加载做一些事情;但是我很快就知道了,我并不完全确定。有关修复或参考的任何见解请分享!

2 个答案:

答案 0 :(得分:0)

我的第一个猜测是,它与您在主队列上执行操作的调用位置有关: dispatch_async(dispatch_get_main_queue()) { 当您需要在最后更新用户界面时,您可能只想这样做。问题是花费更长时间的操作可能会在自整个块在后台运行开始后花费较少时间的操作之后得到处理(在不同的队列上,因此您不知道调度在主队列......)。

进一步检查后,你的街区内有一堆其他背景调用,例如: userImagefile.getDataInBackgroundWithBlock 我使用Parse和JSQMessagesViewController编写了这样的代码,我假设你正在做的事情。我强烈建议您找到通过网络将用户界面更新与模型更新分离的方法。你现在所拥有的不仅难以调试,而且还可能导致你的问题难以检测异步方式。

答案 1 :(得分:0)

它实际上是使用query.orderByAscending("createdAt")来获取对象。只需在print(objects)内添加query.findObjectsInBackgroundWithBlock,您就会看到所有对象都按照正确的顺序打印。

错误的顺序是加载图像的结果。获得文本对象后,立即附加数据。但是当对象是图像时,您调用userImageFile.getDataInBackgroundWithBlock,在调用附加数据的块之前下载图像。

您需要做的是为图像添加占位符,使其处于正确的位置,然后在图像下载完成后更新它。

作为旁注,您可能需要查看subclassing PFObject,它将删除所有as? if语句并删除Pyramid of Doom