1

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 ?

Joakim Danielson
  • 43,251
  • 5
  • 22
  • 52
RP89
  • 101
  • 3
  • 13
  • 1
    Does this answer your question? [Filter fetchRequest for year/month using NSPredicate](https://stackoverflow.com/questions/42386771/filter-fetchrequest-for-year-month-using-nspredicate) – Willeke Nov 19 '22 at 22:21

1 Answers1

3

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.

ScottM
  • 7,108
  • 1
  • 25
  • 42
  • 2
    You can use `NSPredicate(format:argumentArray:)` and avoid `as NDSDate`: `NSPredicate(format: date >= %@ AND date < %@, argumentArray: [thisYear.start, thisYear.end)])` – Larme Nov 18 '22 at 15:43
  • @Larme TIL! I'm off to refactor all my code now…! – ScottM Nov 18 '22 at 16:13