NSSortDescriptor sorting using NSDate in Swift
// newest first
request.sortDescriptors = [NSSortDescriptor(key: "date", ascending: false)]
NB: You do not need : [NSManagedObject]
if you already have as [NSManagedObject]
.
You do not need : NSFetchRequest
when you use the factory method of NSFetchRequest
.
Sort NSSortDescriptor by Month of date. Swift
You can create a custom sort to get your dates sorted by incoming birthday and pass your collection sorted to your ForEach method:
extension Collection where Element == Birthday {
func sortedByIncomingBirthday() -> [Element] {
sorted {
// lhs date is today or is in the future
($0.date.month, $0.date.day) >= (Date().month, Date().day) ?
// rhs date is today or is in the future
($1.date.month, $1.date.day) >= (Date().month, Date().day) ?
// sort them by a month day order
($0.date.month, $0.date.day) < ($1.date.month, $1.date.day) :
// otherwise is in increasing order
true :
// lhs date is in the past
// sort them by a month day order
($0.date.month, $0.date.day) < ($1.date.month, $1.date.day)
}
}
}
ForEach(birthdays.sortedByIncomingBirthday(), id: \.self) { birthday in
Another option is to extend Birthday and add a nextBirthday property this way you can sort it using it as a keyPath for your NSSortDescriptor:
extension Date {
var isInToday: Bool { Calendar.current.isDateInToday(self) }
var nextBirthday: Date {
isInToday ? self : Calendar.current.nextDate(after: Date(), matching: Calendar.current.dateComponents([.month, .day, .hour, .minute], from: self), matchingPolicy: .nextTime)!
}
}
extension Birthday {
var nextBirthday: Date { date.nextBirthday }
}
NSSortDescriptor(keyPath: \Birthday.nextBirthday, ascending: true)
edit/update:
if Birthday date property is optional don't force unwrap its value:
extension Birthday {
var nextBirthday: Date { date?.nextBirthday ?? .distantFuture }
}
and the first approach would need to deal with it as well:
extension Collection where Element == Birthday {
func sortedByIncomingBirthday() -> [Element] {
sorted { lhs, rhs in
if lhs.date == nil { return false }
let lhs = lhs.date ?? .distantFuture
let rhs = rhs.date ?? .distantFuture
// lhs date is today or is in the future
return (lhs.month, lhs.day) >= (Date().month, Date().day) ?
// rhs date is today or is in the future
(rhs.month, rhs.day) >= (Date().month, Date().day) ?
// sort them by a month day order
(lhs.month, lhs.day) < (rhs.month, rhs.day) :
// otherwise is in increasing order
true :
// lhs date is in the past
// sort them by a month day order
(lhs.month, lhs.day) < (rhs.month, rhs.day)
}
}
}
NSSortDescriptor NSDate ascending. How to sort objects with the same date?
sortDescriptors
is an array, so add additional NSSortDescriptor
for the second property you wish, something like that:
eventsRequest.sortDescriptors = [NSSortDescriptor(key: "startDate", ascending: true), NSSortDescriptor(key: "eventType", ascending: true)]
This will firstly use NSSortDescriptor
for the startDate
and if they are the same will check value of eventType
Core Data sort descriptor with NSDate, iOS with Swift
To fetch all objects satisfying some condition you don't need a
sort descriptor but a predicate, for example:
let predicate = NSPredicate(format: "timeStamp < %@", date)
fetchRequest.predicate = predicate
You need a sort descriptor to get the objects in a specified order,
for example:
let sectionSortDescriptor = NSSortDescriptor(key: "timeStamp", ascending: true)
let sortDescriptors = [sectionSortDescriptor]
fetchRequest.sortDescriptors = sortDescriptors
Multiple NSSortDescriptor Not Working When The 1st Descriptor is NSDate
I finally figured it out:
Apparently it's the sub-seconds information that also being saved into Core Data making the comparison between dates (even though the dates being compared share the exact same date) not working.
So what I did was to remove the sub-seconds information before saving it to Core Data:
self.recordDate = [NSDate dateWithTimeIntervalSinceReferenceDate:floor([recordDate timeIntervalSinceReferenceDate])];
I hope this can help anyone facing the same problem. Cheers!
NSSortDescriptor using NSDate attribute of Entity (Swift)
You can sort by setting a sortDescriptor on the NSFetchRequest. Pass true or false depending on if you want the results to be acending or descending.
var fetchRequest = NSFetchRequest(entityName: "Assessment")
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "nsDateOfAssessment", ascending: false)]
You could then use a high order function to map the results to only get the weight attribute you want
let fetchedResults = managedContext.executeFetchRequest(fetchRequest, error: &error) as [Assessment]?
Notice how I'm setting it to be an array of your subclassed NSManagedObject
if let assessments = fetchedResults {
let weights = assessments.map { assessment in assessment.weight }
}
Set NSSortDescriptor for CoreData using a calculated field
Unfortunately, it appears that this is not possible. A Core Data fetch request cannot sort on a computed property, only on persistent stored properties. I found the following question that I had previously overlooked on this site.
Sorting NSFetchedResultsController by Swift Computed Property on NSManagedObjectSubclass
However, if anyone knows otherwise, please let me know.
Related Topics
Integer Literal Overflows When Stored into 'Int'
Xcode 11 - Disable Resize Mode in Catalyst Swift
Swift 3: Converting Data to String Returns a Nil Value
Avplayerviewcontroller Black Screen When Swiping on iOS 11
Swift Cannot Infer Type from Context
Argument of '#Selector' Does Not Refer to an '@Objc' Method, Property or Initializer
How to Apply Animation for One Specific Modifier Change Only
Swift Vscode Class in Other File Not Recognized
Read Static Property from Object
How to Get Notification Authorization Status in Swift 3
Swift Any Difference Between Closures and First-Class Functions
How to Define Static Constant in a Generic Class in Swift
Swift - Exit Outer Function from Closure
Alamofire Returns Wrong Encoding
In Which Cases Arscnview.Raycastquery Returns Nil
How to Set an Initial Value for @Nsmanaged Property Pfobject Subclass