Search code examples
iosswiftparse-platformnspredicatepfquery

Find newest message from each sender?


I've got a Messages menu in my app, and I'm completely at a loss on how to show the newest message received/sent from EACH user, without loading ALL messages received/sent.

I'm using Parse as my backend, so I've gotta believe there's some clever subquery, or NSPredicate that I could user for this.

The current solution I have in mind is another Boolean attribute for my messages, where all but the most recent get augmented, so I can known what to load with a simple predicate. This seems slopy though, save me from myself!

EDIT:

Right now I'm getting the messages where the user is the sender or receiver (depending on a segmented control), and then displaying each user who was sent to/received from with a sample of their newest message.

Right now I'm using internal logic to do this, and still in the process of figuring it out (the logic is a little backwards right now...)

let query = PFQuery(className: "Messages")

            if recievedOrSent {
            query.whereKey("other", equalTo: userName)
            print("called OTHER query")
        } else {
            query.whereKey("sender", equalTo: userName)
            print("called SENDER query")
        }

        query.addDescendingOrder("createdAt")
        query.findObjectsInBackgroundWithBlock {
            (objects, error) -> Void in

            if error == nil {

                    if thisSender == userName || self.recievedUsers.contains(thisSender) &&  self.lesserDate(thisTime, rhs: self.recievedUsersTimes[self.recievedUsers.indexOf(thisSender)!])
                    {} else {
                        self.recievedUsers.append(thisSender)
                        self.recievedUsersMsg.append(thisMessage)
                        self.recievedUsersTimes.append(thisTime)
                        self.recievedUsersMsgRead.append(thisRead)
                    }

                    if thisOther == userName || self.sentUsers.contains(thisOther) && self.lesserDate(thisTime, rhs: self.sentUsersTimes[self.sentUsers.indexOf(thisOther)!])
                    {} else {
                        self.sentUsers.append(thisOther)
                        self.sentUsersMsg.append(thisMessage)
                        self.sentUsersTimes.append(thisTime)
                        self.sentUsersMsgRead.append(thisRead)  
                }
    }

Solution

  • If you want to get only the most recent message from each user that you are having a conversation with, create a new class called RecentMessage and update it each time using an afterSave cloud function on the Message class.

    In the afterSave hook, maintain a pointer in the RecentMessage class to the latest Message in the conversation for each user. Then all you have to do is query for all of the current user's RecentMessage objects and use includeKey on the Message pointer.

    This let's you abstract away more logic from the client side and streamline your queries where performance really counts :)