SwiftData @Query unable to filter on Int enum rawValue

I have a simple enum with Int raw values:

enum AccountType: Int, Codable, CaseIterable {
    case creditAccountReceivable = 1, 
         creditAccountPayable = 2,
         nominal = 3
}

In my model class I have a field:

   var type: AccountType.RawValue

I use the following filter in my View:

    @Query(
        filter: #Predicate { $0.type == AccountType.nominal.rawValue },
        sort: [SortDescriptor(\Account.group), SortDescriptor(\Account.accountName)])
    private var nominalAccounts: [Account]

This causes a build failure with 3 errors:

  1. 'AccountType.Type' cannot conform to 'Encodable'
  2. 'AccountType.Type' cannot conform to 'Decodable'
  3. Key path cannot refer to enum case 'nominal'

The only way I have been able to make it work is by substituting an Int literal in place of the enum raw value: filter: #Predicate { $0.type == 3 }

The other workaround I have used is reading all enitities and filtering using a computed variable.

Answered by newwbee in 761740022

Store the rawValue in a variable and access the variable inside the #Predicate closure.

Given below is an example:

enum AccountType: Int, Codable, CaseIterable {
    case creditAccountReceivable = 1,
         creditAccountPayable = 2,
         nominal = 3
}

@Model
class Account {
    var type: Int
    
    init(type: AccountType.RawValue) {
        self.type = type
    }
}

struct ContentView: View {
    
    @Query
    private var nominalAccounts: [Account]

    init() {
        //Store it in a variable type
        let type = AccountType.creditAccountPayable.rawValue

        let filter = #Predicate<Account> { account in
            //Access the variable inside the closure
            account.type == type
        }
        _nominalAccounts = Query(filter: filter, sort: \.type)
    }
    
    var body: some View {
        Text("Hello")
    }
}
  • Just a small suggestion, next time please post minimum code that would compile.
  • Add the tag SwiftData to the post so that experts in SwiftData can view your question as your question is more related to SwiftData
Accepted Answer

Store the rawValue in a variable and access the variable inside the #Predicate closure.

Given below is an example:

enum AccountType: Int, Codable, CaseIterable {
    case creditAccountReceivable = 1,
         creditAccountPayable = 2,
         nominal = 3
}

@Model
class Account {
    var type: Int
    
    init(type: AccountType.RawValue) {
        self.type = type
    }
}

struct ContentView: View {
    
    @Query
    private var nominalAccounts: [Account]

    init() {
        //Store it in a variable type
        let type = AccountType.creditAccountPayable.rawValue

        let filter = #Predicate<Account> { account in
            //Access the variable inside the closure
            account.type == type
        }
        _nominalAccounts = Query(filter: filter, sort: \.type)
    }
    
    var body: some View {
        Text("Hello")
    }
}
  • Just a small suggestion, next time please post minimum code that would compile.
  • Add the tag SwiftData to the post so that experts in SwiftData can view your question as your question is more related to SwiftData
SwiftData @Query unable to filter on Int enum rawValue
 
 
Q