Reputation: 29
I would love to get help on this one since I've been on it for a while.
So I fetch my Sections like this and they all get in the right order, but the relationship "Todoitem" they have do not come in the same order. They get all in the correct Section but in wrong order. I wanna get the Todoitems like this:
Section[ Todoitem "first created", Todoitem "second created", Todoitem "third created"...]
Instead they come like this when I create them, always random:
Section[ Todoitem "second created", Todoitem "third created", Todoitem "first created"...]
You guys in here are awesome and if someone would like to take the time to help me I would be more than tankful!
I'm working in Swift Xcode, Storyboard.
func fetchSections() {
let startOfDay = Calendar.current.startOfDay(for: currentDate)
var components = DateComponents()
components.day = 1
components.second = -1
let endOfDay = Calendar.current.date(byAdding: components, to: startOfDay)
let fetchRequest : NSFetchRequest<Section> = Section.fetchRequest()
fetchRequest.predicate = NSPredicate(format: "date >= %@ AND date <= %@", startOfDay as NSDate, endOfDay! as NSDate)
do {
self.tableViewData = try context.fetch(fetchRequest)
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
catch {
//error
}
}
Fixed it with this:
extension Section {
var sortedItems: [TodoItem] {
guard let items = todoitem as? Set<TodoItem> else {
return []
}
return items.sorted { (item1, item2) in
return item1.date ?? Date() < item2.date ?? Date()
}
}
}
and in cell for row:
let text = self.tableViewCoreData[indexPath.section].sortedItems[indexPath.row - 1].todo cell.myLabel.text = text
Upvotes: 0
Views: 78
Reputation: 29
Fixed it with this:
extension Section {
var sortedItems: [TodoItem] {
guard let items = todoitem as? Set<TodoItem> else {
return []
}
return items.sorted { (item1, item2) in
return item1.date ?? Date() < item2.date ?? Date()
}
}
}
and in cell for row:
let text = self.tableViewCoreData[indexPath.section].sortedItems[indexPath.row - 1].todo
cell.myLabel.text = text
Got help from a friend of mine, thanks anyways!
Upvotes: 0
Reputation: 5143
Predicate is for filtering data only. You probably need to use an NSSortDescriptor
to get the output you desire.
After this line:
fetchRequest.predicate = NSPredicate(format: "date >= %@ AND date <= %@",
startOfDay as NSDate, endOfDay! as NSDate)
Add these lines:
let dateSortDescriptor = NSSortDescriptor(key: "date", ascending: true)
fetchRequest.sortDescriptors = [dateSortDescriptor]
Update
As Joakim Danielson rightly mentioned in the comments, the sorting cannot be directly applied on sections as the date resides in the ToDoItems entity.
Since you are creating a fetch request using the sections entity, I am not sure you can apply the sort descriptor directly to your to do items entity (atleast to my knowledge).
I would do the following updates to get your desired goal:
First change your var tableViewData to be compatible with this solution
// I am assuming Section and ToDoItems are names of your entities
// and NOT the name of the relationship between them so create this
var tableViewData: [Section: ToDoItem] = [:]
Then make some updates in the fetching
// Since you said this works fine, I do not make any changes to these two lines
let fetchRequest : NSFetchRequest<Section> = Section.fetchRequest()
fetchRequest.predicate = NSPredicate(format: "date >= %@ AND date <= %@",
startOfDay as NSDate, endOfDay! as NSDate)
// Temp container to build the desired sorted results
var sectionItems: [Section: [ToDoItems]] = [:]
do {
// Retrieve the sections
let sections = try context.fetch(fetchRequest)
// Loop over all the sections you retrieve
for section in sections
{
// Initialize a sort descriptor for the date attribute in the ToDoItems
// entity. Change it to the right name if it is not date
let sortDescriptor = [NSSortDescriptor(key: "date", ascending: true)]
// Change hasToDoItems to your correct relationship name
if let sortedItems = section.hasToDoItems?
.sortedArray(using: sortDescriptor) as? [ToDoItem]
{
sectionItems[section] = sortedItems
}
}
// Assign the tableViewData with the sorted data
self.tableViewData = sectionItems
// Reload your data
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
Give this a go and let me know if this gives you the desired results or comment with your results and I'll amend the code accordingly.
Upvotes: 1