如何在没有时间的情况下按日期对获取请求进行排序 - Swift 3



我想按日期和另一个描述符对我的fetchRequest进行排序:

let sortDate = NSSortDescriptor(key: "returnDate", ascending: true)
let sortAmount = NSSortDescriptor(key: "amount", ascending: true)
fetchRequest.sortDescriptors = [sortDate, sortAmount]

但不能使用sortAmount,因为它是按时间排序的

2017-06-18 11:18:55 +0000 amount 231.0 
2018-06-16 09:49:53 +0000 amount 33.0 
2018-06-16 11:06:34 +0000 amount 55.0 
2018-06-16 11:44:05 +0000 amount 44.0 
2018-06-16 11:44:28 +0000 amount 77.0 
2018-06-16 11:45:50 +0000 amount 33.0 
2019-06-16 14:48:03 +0000 amount 55.0 

例如,如何仅按天进行排序?

通常,您可以只子类NSSortDescriptor来制作自己的排序描述符,并在您自己的排序描述符中比较没有时间组件的日期。然后使用您自己的排序描述符而不是标准描述符来比较日期。这里有一些未经测试的代码,但它会给你一个想法:

class DaySortDescriptor: NSSortDescriptor {
static private let calendar = NSCalendar( calendarIdentifier: .gregorian)
override
func compare ( _ object1: Any, to object2: Any ) -> ComparisonResult {
// Both must be dates as we cannot sort anything else
guard let date1 = object1 as? Date,
let date2 = object2 as? Date,
let calendar = DaySortDescriptor.calendar
else { assertionFailure(); return .orderedSame }
let comp1 = calendar.components(
[ .year, .month, .day ], from: date1
)
let comp2 = calendar.components(
[ .year, .month, .day ], from: date2
)
let cleanedDate1 = calendar.date(from: comp1)!
let cleanedDate2 = calendar.date(from: comp2)!
return super.compare(cleanedDate1, to: cleanedDate2)
}
}

唯一的问题是,虽然这适用于仅存储在内存中的 CoreData,以及使用二进制或 XML 作为后备存储的 CoreData,但在使用 SQLite 后退存储时将不起作用。实际上,苹果甚至对此发表了评论,并给出了如何做到这一点的建议:

原因:读取请求的确切执行方式取决于存储 - 请参阅读取对象。

补救措施:如果直接执行提取,请不要使用基于 Cocoa 的排序运算符,而是在内存中对返回的数组进行排序。 如果您使用的是数组控制器,则可能需要子类 NSArrayController,这样它就不会将排序描述符传递给 数据库,但在您的数据完成后将进行排序 获取。

资料来源:https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreData/TroubleshootingCoreData.html

最新更新