I have a data model that looks like this:
As you can see there is a many to many relationship. In my home view controller I am fetching all the Tag objects like so:
let tagFetchRequest =
NSFetchRequest<NSManagedObject>(entityName: "Tag")
//3
tagFetchRequest.predicate = NSPredicate(format: "self.posts.@count != 0")
//let sort = NSSortDescriptor(key: "posts.first?.timestamp", ascending: false). This line is the issue
tagFetchRequest.sortDescriptors = [sort]
fetchedResultsController = NSFetchedResultsController(fetchRequest: tagFetchRequest, managedObjectContext: managedContext, sectionNameKeyPath: nil, cacheName: nil) as? NSFetchedResultsController<Tag>
fetchedResultsController.delegate = self
do {
try fetchedResultsController.performFetch()
} catch let error as NSError {
print("Could not fetch. \(error), \(error.userInfo)")
}
I want the tags to show up such that the tag for who's posts has the most recent timestamp shows up first. Since posts is an ordered set, Im thinking perhaps if I could get the first post in the ordered set's timestamp and sort the tags on that, that would work. But it doesn't seem that the NSSortDescriptor key language accepts things like "self.posts.first".
Another option would be to - for each fetched tag perform an additional fetch of its posts, then sort those programmatically and somehow return the value of this sorted most recent timestamp and give it to the NSFetchedResultsController. I don't know if you can do this though - where would you perform this additional fetch even? and can you pass things like that to an NSSortDescriptor.
You should denormalise the data. Add a field in Tag
for dateLastUsed
and sort by that. Update it when a post is tagged. Depending on your product requirements you might also have to update it when a tag is removed from a post. In that case you would have to look through all of the tag's posts and assign the dateLastUsed
of the latest of those posts.
Also you said "... for each fetched tag perform an additional fetch of its posts,". You should NEVER be fetching the posts of a tag or the tags of a post, but ALWAYS using the relationship. The relationships are orders of magnitude faster.