Mikael
Mikael

Reputation: 2395

NSPredicate on collection of an NSManagedObject fail to request

I try to do the following:

    predicate = NSPredicate(format: "user.userID = %@ AND messages[SIZE] > 0", IOSUser.sharedInstance().userID)
    let managedObjectCtx = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
    let entity = NSEntityDescription.entityForName("Session", inManagedObjectContext: managedObjectCtx)
    fetchRequest.entity = entity
    fetchRequest.predicate = predicate
    let dateSortDescriptor = NSSortDescriptor(key: "messages[LAST].date", ascending: false)
    let sortDescriptors = [dateSortDescriptor]
    fetchRequest.sortDescriptors = sortDescriptors
    sessionFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: managedObjectCtx, sectionNameKeyPath: nil, cacheName: nil)
    sessionFetchedResultsController.delegate = self

do{
  try sessionFetchedResultsController.performFetch()
}catch{
  abort()
}

But it crashes on the performFetch().

Basically I try to get all chat Sessions owned by the user of the app and I try to be sure that all sessions have at least 1 message. Also, I want to sort all sessions by most recent messages.

Here is the crash:

enter image description here

Upvotes: 1

Views: 43

Answers (1)

pbasdf
pbasdf

Reputation: 21536

I don't think you will be able to get a fetched results controller to achieve what you want. The predicate can be made to work:

predicate = NSPredicate(format: "user.userID = %@ AND messages.@count > 0", IOSUser.sharedInstance().userID)

But the sort descriptor is a lost cause: CoreData can only sort on (persistent) attributes. One solution would be to add a persistent attribute (eg. lastMessageDate) to the Session entity. You would obviously need to update this attribute whenever adding/deleting a message to/from the Session.

If you can live with a plain fetch, you could fetch Message objects with a predicate:

predicate = NSPredicate(format: "session.user.userID = %@", IOSUser.sharedInstance().userID)

and sort descriptor:

let dateSortDescriptor = NSSortDescriptor(key: "date", ascending: false)

and then extract an array of distinct Session objects using

let sessionsArray = fetchResults.valueForKeyPath("@distinctUnionOfObjects.session")

(you might need to cast fetchResults as NSArray).

Upvotes: 1

Related Questions