如何解决创建 SwiftData #Predicate 时的编译器错误?

huangapple go评论75阅读模式
英文:

How to resolve compiler error creating a SwiftData #Predicate?

问题

我一直在尝试多种方法来解决这个问题。我正在尝试使用谓词来获取 SwiftData 记录,但无论我尝试什么,都会导致一对错误:

初始化程序 'init(_:)' 要求 'Item' 遵循 'Encodable'

初始化程序 'init(_:)' 要求 'Item' 遵循 'Decodable'

这个错误是在扩展的 #Predicate 宏内部引发的。

这里是一个简单的类来演示这个问题:

@Model
final class Item {
    @Attribute(.unique) var id: String
    var timestamp: Date

    init(timestamp: Date) {
        self.id = UUID().uuidString
        self.timestamp = timestamp
    }
}

这里是导致编译器错误的简化代码:

extension Item {
    static func foo() {
        let item = Item(timestamp: .now)
        let pred = #Predicate<Item> { $0.id == item.id }
    }
}

我尝试了多种方法来解决这个错误。我看过的所有 Apple SwiftData 示例项目都没有出现这个错误。

我尝试遵循 Identifiable 协议。我尝试重命名 id 属性。我尝试直接将 id 类型更改为 UUID,而不是 String

当然,我还添加了代码来遵循 Codable 协议。虽然这修复了编译器错误,但我最终遇到了运行时错误。请注意,Apple SwiftData 项目中的模型都没有遵循 Codable 协议。

我漏掉了什么?

英文:

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&lt;Item&gt; { $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?

答案1

得分: 7

解决方法是避免在 #Predicate 闭包内引用模型对象。

只需将谓词行从:

let pred = #Predicate<Item> { $0.id == item.id }

更改为:

let anID = item.id
let pred = #Predicate<Item> { $0.id == anID }

虽然解决方法似乎很简单和明显,但错误很容易让您走入许多错误的路径。

英文:

The solution is to avoid referencing a model object inside the #Predicate closure.

Simply change the predicate line from:

let pred = #Predicate&lt;Item&gt; { $0.id == item.id }

to:

let anID = item.id
let pred = #Predicate&lt;Item&gt; { $0.id == anID }

While the solution seems trivial and obvious, the error can easily lead you down many wrong paths.

huangapple
  • 本文由 发表于 2023年7月7日 04:28:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/76632340.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定