Home > Software engineering >  Using NSPredicate to filter / unfilter sections in a SectionedFetchRequest
Using NSPredicate to filter / unfilter sections in a SectionedFetchRequest

Time:05-10

I'm ordering my data and fetching into sections by using SectionedFetchRequest. I built a filter button that is supposed to filter all data where its priority is 0 (it is saved as int32 and update a list.

After reading enter image description here

My code:

extension Task {
    @objc
    var priorityText: String{
        var result = ""
        switch self.priority {
        case 0: result = "Today"
        case 1: result = "Important Tasks"
        default: result = "All Others"
        }
        return result
    }
}


struct ContentView: View {
    @Environment(\.managedObjectContext) private var viewContext

    @SectionedFetchRequest(entity: Task.entity(),
                           sectionIdentifier: \.priorityText,
                           sortDescriptors: [NSSortDescriptor(keyPath: \Task.priority, ascending: true)],
                           predicate: nil,
                           animation: Animation.linear)
    var sections: SectionedFetchResults<String, Task>
    
    @State var filtered = false
    
    var body: some View {
        NavigationView {
            List {
                ForEach(sections) { section in
                    Section(header: Text(section.id.capitalized).fontWeight(.bold).foregroundColor(.primary)) {
                        ForEach(section) { task in
                            Text("\(task.tasktext!)")
                        }
                    }
                }
            }
            .toolbar {
                ToolbarItem(placement: .bottomBar) {
                    Button(action: {
                        filtered.toggle()
                        if filtered {
                            // check https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Predicates/Articles/pSyntax.html
                            //sections.nsPredicate = NSPredicate(format: "priorityText CONTAINS[c] %@", "Today")
                            //sections.nsPredicate = NSPredicate(format: "priority == %@", 0)
                            //sections.nsPredicate = NSPredicate(format: "priority like %@", 0)
                            //sections.nsPredicate = NSPredicate(format: "priorityText == %@", "Today")
                            //sections.nsPredicate = NSPredicate(format: "priorityText like %@", "Today")
                            sections.nsPredicate = NSPredicate(format: "priority == %@", 0 as NSInteger)
                        } else {
                           print("unfilter?")
                        }
                    }) {
                        Label("Filter", systemImage: filtered ? "line.3.horizontal.decrease.circle.fill": "line.3.horizontal.decrease.circle").foregroundColor(.primary)
                    }
                }
            }
            .listStyle(.plain)
        }
    }
}

EDIT:

The answer to the first question, how to filter data based on an integer, is:

sections.nsPredicate = NSPredicate(format: "priority == %i",0)

And to display the unfiltered data:

sections.nsPredicate = NSPredicate(format: "priority >= %i",0)

CodePudding user response:

Did you try:

sections.nsPredicate = NSPredicate(format: "priority == %@",Int32(0))

as a predicate?

Also, see this answer for changing your search in the view.

CodePudding user response:

I'm going to answer my own question:

To filter:

sections.nsPredicate = NSPredicate(format: "priority == %i",0)

To unfilter:

sections.nsPredicate = NSPredicate(format: "priority >= %i",0)
  • Related