UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

How to use a SwiftData custom fetch descriptor to limit properties to fetch while using a dynamic filter predicate

Forums > SwiftUI

I would like to create a custom fetch descriptor using the techniques described in this article. Specifically, I would like to limit properties retrieved using .propertiesToFetch.

The project I am working on uses techniques described in this article to create a dynamic filter predicate. That is working well. What I can't figure out is how to marry the two.

The following is the init in my view that leverages the filtered data. How do I incorporate the concept of the custom fetch descriptor so that I only fetch certain properties?

It's not clear if/how I can do that with the _items = Query(filter: predicate, sort: sortDescriptors) construct.

While I'm here ;-), in my everquest to learn, if there other ways to improve they way I'm handling the predicate please share!

I would appreciate any guidance. thanks -- jay

init(filterText: String, filter: Filter, settingsVM: SettingsViewModel) {

      self.filter = filter

      self.settingsVM = settingsVM
      _journalViewType = State(initialValue: settingsVM.defaultJournalView)

      // use computed variables for Predicate to work
      let distantPast = Date.distantPast
      let last7DaysFilter = filter.id == .last7
      let last30DaysFilter = filter.id == .last30
      let lastYearFilter = filter.id == .lastYear
      let last7Days = Calendar.current.date(byAdding: .day, value: -7, to: Date.now)!
      let last30Days = Calendar.current.date(byAdding: .month, value: -1, to: Date.now)!
      let lastYear = Calendar.current.date(byAdding: .year, value: -1, to: Date.now)!

      let sortDescriptors: [SortDescriptor<Item>] = [SortDescriptor(\Item.date, order: .reverse)]

      // compound expression to check for date filter AND search text if it exists

      let predicate = #Predicate<Item> { item in
         if last7DaysFilter {
            return item.date > last7Days && (item.text.localizedStandardContains(filterText) || (item.locationForFilterPredicate.localizedStandardContains(filterText)) || filterText.isEmpty)
         } else if last30DaysFilter {
            return item.date > last30Days && (item.text.localizedStandardContains(filterText) || (item.locationForFilterPredicate.localizedStandardContains(filterText)) || filterText.isEmpty)
         } else if lastYearFilter {
            return item.date > lastYear && (item.text.localizedStandardContains(filterText) || (item.locationForFilterPredicate.localizedStandardContains(filterText)) || filterText.isEmpty)
         } else {
            return item.date > distantPast && (item.text.localizedStandardContains(filterText) || (item.locationForFilterPredicate.localizedStandardContains(filterText)) || filterText.isEmpty)
      _items = Query(filter: predicate, sort: sortDescriptors)


Hacking with Swift is sponsored by Essential Developer

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until April 28th.

Click to save your free spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

Unknown user

You are not logged in

Log in or create account

Link copied to your pasteboard.