Search code examples
swiftswiftuipredicate

Thread 1: signal SIGABRT Predicate SwiftUI


For some reason, I am getting "SGNL SGBRT" error where I assign a value at predicate. What is the reason of this and how can I overcome this problem?

struct SearchView: View {
    @Environment(\.managedObjectContext) private var viewContext
    @FetchRequest var reminder: FetchedResults<CDReminder>
    @Binding var searchText: String

init(searchText: Binding<String>) {
    self._searchText = searchText
    var predicate : NSPredicate?
    predicate = NSPredicate(format: "name CONTAINS %@", searchText as! CVarArg) // SGNL SGBRT ERROR
    self._reminder = FetchRequest(
        entity: CDReminder.entity(),
        sortDescriptors: [],
        predicate: predicate
        )
}
    var body: some View {
        VStack{
            SearchBar(text: $searchText)
                .environment(\.managedObjectContext, viewContext)
            List{
                ForEach(reminder, id: \.self){ reminder in
                    DatedReminderCell(reminder: reminder, isSelected: false, onComplete: {})
                }
            }
        }
    }
}

Solution

  • The property wrapper @Binding has the following semantics:

    • self._searchText (same as $searchText) represents the struct Binding<String>, the two-way binding.
    • self.searchText (same as self._searchText.wrappedValue) represents the wrapped string value.

    It's a bit similar to a RawRepresentable String enum. You need the rawValue rather than the enum case.

    So the correct syntax is either

    predicate = NSPredicate(format: "name CONTAINS %@", self.searchText)
    

    or

    predicate = NSPredicate(format: "name CONTAINS %@", self._searchText.wrappedValue)
    

    As String conforms to the CVArg protocol a (bridge) cast is not needed. A force cast is wrong anyway.