SwiftData|在 iOS 17 上必须显式调用 context.insert() 插入数据

了解如何在 iOS 17 上使用 SwiftData,以及一些必须遵守的限制条件。

SwiftData|在 iOS 17 上必须显式调用 context.insert() 插入数据

假设封装了一个 addTag 辅助方法用于操作数据:

在 iOS 18 上,你无需 context.insert(),也无需设置反向关系,SwiftData 会自动处理这种关系:

此代码在 iOS 18 上工作良好。

这带来的好处是,无需在方法中传递 ModelContext 变量,可以创建更干净的代码:

iOS 17|必须为方法传递 ModelContext 变量

iOS 17.4 及以上版本

在 iOS 17.4 及以上,必须调用 context.insert(),但无需设置反向关系:

准确来说,是 iOS 17.2 以上就无需保存 context.insert() 也不会报错。但可能无法保存记录(原因未知)。所以,建议直接使用 iOS 17.4 及以上版本。
此代码在 iOS 17.2 以上工作良好

如果注释掉 context.insert(),执行就会报错:

return self.getValue(forKey: \.xxx)

错误信息。

下面这个帖子说明了相同的情况:

Weird issue with SwiftData saving … | Apple Developer Forums
SwiftData issue with relationship
I have 2 classes and a relation from one to another. During runtime i get a error..."Thread 1: EXC_BREAKPOINT (code=1, subcode=0x233cd16e4)" Is there any solution to this error... import

在 Apple 提供的项目中,对于数据操作方法,也都显式传递了 ModelContext 参数,印证了上述推测。

iOS 17.1 及以下

在 iOS 17.1 及以下

  • 必须显式调用 context.insert()和设置反向关系
  • 必须先调用 context.insert(),然后再设置反向关系

否则就会报错。

项目最好设置兼容 iOS 17.4 及以上。

必须传递 ModelContext 带来的问题

由于 ModelContext 只能从 View 中获取,因此在调用方法的时候,必须在 View 中传递。如果涉及到方法的嵌套使用,就必须递层传递,比较麻烦。