Can't test equality of two model entities with a predicate

Hi,

given this model:

@Model
class OnlyName {
  var name: String
  
  init(name: String) {
    self.name = name
  }
}

I would assume that I could write a predicate like this: #Predicate<OnlyName> { $0.name == other.name }, where other is also an instance of OnlyName for example returned by an earlier fetch.

Unfortunately this results in the following compiler errors:

Initializer 'init(_:)' requires that 'OnlyName' conform to 'Encodable'
Initializer 'init(_:)' requires that 'OnlyName' conform to 'Decodable'

Any idea if this is a bug in SwiftData or if I am missing something?

Cheers, Michael

Answered by Purkylin_glow in 756485022

You should extract a variable for the name.

let tmp = other.name
#Predicate<OnlyName> { $0.name == tmp }

This seems to currently be an issue with swiftData. With that said, I wrote custom encoder/decoders for each Model, for the time being, which eliminated this error.

Encoder

func encode(to encoder: Encoder) throws {
        enum CodingKeys: String, CodingKey {
            case name
        }
        
        do {
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encode(name, forKey: .name)
        } catch {
            print("Encoding error: \(error)")
        }
    }

Decoder

public required convenience init(from decoder: Decoder)  {
        enum CodingKeys: String, CodingKey {
            name
        }
        
        do {
            let container = try decoder.container(keyedBy: CodingKeys.self)
            let name = try container.decode(String.self, forKey: .name)
            self.init(name: name)
        } catch {
            fatalError()
        }
    }

Once those were in place, the errors went away. Additionally, it'd probably make sense to just have your class conform to Equatable and implement an == method:

static func ==(lhs: OnlyName, rhs: OnlyName) -> Bool {
        return lhs.name == rhs.name
    }
Accepted Answer

You should extract a variable for the name.

let tmp = other.name
#Predicate<OnlyName> { $0.name == tmp }
Can't test equality of two model entities with a predicate
 
 
Q