I am developing a SwiftUI Budget management application which tracks the Expense and Income of the user. The application uses CoreData for managing the data management. The managed object has date as one property.
I use the below fetch request to get the data
@SectionedFetchRequest(sectionIdentifier: \Expence.itemMonthYearShort, sortDescriptors: [SortDescriptor(\Expence.date, order: .forward)])
private var expences : SectionedFetchResults<String, Expence>
This will give grouped data like Expense for Sept 2021
The managed object model is as below
extension Expence {
@nonobjc public class func fetchRequest() -> NSFetchRequest<Expence> {
return NSFetchRequest<Expence>(entityName: "Expence")
}
@NSManaged public var amount: Double
@NSManaged public var date: Date
@NSManaged public var id: UUID?
@NSManaged public var type: Int16
@NSManaged public var title: String?
@NSManaged public var note: String?
@NSManaged public var category: Category?
public var wrappedNotes : String{
note ?? ""
}
public var wrappedTitle : String{
title ?? ""
}
@objc var itemMonthYear : String{
return date.formatted(.dateTime.month(.wide).year())
}
@objc var itemMonthYearShort : String{
return date.formatted(.dateTime.month(.abbreviated).year())
}
@objc var itemMonthYearDescending : String{
return date.formatted(.dateTime.month(.wide).year()) + " "
}
@objc var itemMonth : String{
return date.formatted(.dateTime.month(.abbreviated
))
}
@objc var itemYear : String{
return date.formatted(.dateTime.year())
}
}
extension Expence : Identifiable {
}
I want to filter the data based on year. For example I want to show the expenses for particular year. How can I write the predicate for that ?
To find the start and end points of a particular year, Calendar
has a dateInterval
method. For example:
let today = Date.now // => November 18, 2022
let thisYear = Calendar.current.dateInterval(of: .year, for: today)! // NB: note this is an Optional
let predicate = NSPredicate(format: "date >= %@ AND date < %@", thisYear.start as NSDate, thisYear.end as NSDate)
If you want to look for a specific year, instead of using today's date as a starting point you can create a date whose year matches the one you want to filter by, and so on.