I have been trying so many ways to resolve this issue. I am trying to fetch SwiftData records with a predicate. but everything I try results in a pair of errors:
initializer 'init(_:)' requires that 'Item' conform to 'Encodable'
initializer 'init(_:)' requires that 'Item' conform to 'Decodable'
The error is coming from within the expanded #Predicate macro.
Here is a bare bones class to demonstrate the issue:
@Model
final class Item {
@Attribute(.unique) var id: String
var timestamp: Date
init(timestamp: Date) {
self.id = UUID().uuidString
self.timestamp = timestamp
}
}
And here is the bare bones code that causes the compiler issue:
extension Item {
static func foo() {
let item = Item(timestamp: .now)
let pred = #Predicate<Item> { $0.id == item.id }
}
}
I've tried so many ways to resolve this error. None of the Apple SwiftData sample projects I've seen give this error.
I've tried conforming to Identifiable. I've renamed the id property. I've changed the id type to UUID directly instead of String.
And of course I've added code to conform to Codable. While that fixed the compiler error, I ended up getting a runtime error. Note that none of the Apple SwiftData projects conform their models to Codable.
What am I missing?
The solution is to avoid referencing a model object inside the #Predicate closure.
Simply change the predicate line from:
let pred = #Predicate<Item> { $0.id == item.id }
to:
let anID = item.id
let pred = #Predicate<Item> { $0.id == anID }
While the solution seems trivial and obvious, the error can easily lead you down many wrong paths.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With