I have Core Data database. Structure is on the image (DBContact have many DBMessages with property messages
, each DBMessage have one contact with property contact
):
I want to display messages grouped by contact and sorted by date. So the number of rows have to be = number of contacts with messages. And in each row I have to display avatar, nameAndSurname of contact and text and date of last message of this contact.
The only solution I found is:
let entityName = kDBOrder
let entityDescription = NSEntityDescription.entityForName(entityName, inManagedObjectContext: managedObjectContext)
let fetchRequest = NSFetchRequest()
fetchRequest.entity = entityDescription
fetchRequest.fetchBatchSize = 20
// sort
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "contact.id", ascending: false), NSSortDescriptor(key: "date", ascending: false)]
let sectionNameKeyPath: String? = "contact.id"
self.fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: managedObjectContext, sectionNameKeyPath: sectionNameKeyPath, cacheName: nil)
fetchedResultsController!.delegate = self
if tableViewMain != nil {
do {
try fetchedResultsController!.performFetch()
} catch {
print("An error occurred in fetchresultcontroller")
}
tableViewMain.reloadData()
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
var count = 0
if let sections = fetchedResultsController?.sections {
let currentSection = sections[section]
count = currentSection.numberOfObjects
// in each section we must have only 1 row
if count > 0 {
count = 1
}
}
return count
}
But in this case contacts will be sorted by id, but I need to sort them by date of last message. But if I change sortDescriptors to fetchRequest.sortDescriptors = [NSSortDescriptor(key: "date", ascending: false), NSSortDescriptor(key: "contact.id", ascending: false)]
to sort by date first, it will not display contacts properly.
Do anybody have ideas how to implement this?
I'd probably change the model to make life easier and do a little more processing earlier. Basically if add another relationship, 1-to-1, between the 2 entities and each time a new message is added is update that relationship - so you always have a direct pointer to the most recent message.
Once you've done that your FRC and your table load speed are trivial because you just use contacts in the fetch. New messages are also handled correctly because the relationship gets updated so the contact changes and the FRC will see it.