简体   繁体   中英

How to sort fetch request by date without time - Swift 3

I want to sort my fetchRequest by date and another descriptor :

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

but sortAmount can't be used, because it is sorting by time

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 

How can I sort, for example, only by day?

Generally you can just subclass NSSortDescriptor to make your own sort descriptor and in your own sort descriptor, compare dates without the time component. Then use your own sort descriptor instead of the standard ones for comparing the dates. Here's some untested code but it will give you the idea:

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)
    }
}

The only problem is, while this will work with CoreData just stored in memory, as well as with CoreData using binary or XML as a backing store, it will not work when using a SQLite backing store. Actually Apple has even commented on that and gives a recommendation how to do it:

Cause: Exactly how a fetch request is executed depends on the store—see Fetching Objects.

Remedy: If you are executing the fetch directly, do not use Cocoa-based sort operators—instead, sort the returned array in memory. If you are using an array controller, you may need to subclass NSArrayController, so that it will not pass the sort descriptors to the database but will instead do the sorting after your data has been fetched.

Source: https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreData/TroubleshootingCoreData.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM