Core Data 模型转 SwiftData 转换器
粘贴 .xcdatamodel 里的 contents 文件,就能得到每个实体一个 SwiftData @Model 类:Swift 类型、可选与默认值、对应唯一约束、外部存储和 renaming identifier 的 @Attribute 选项、对应 transient 属性的 @Transient,以及带删除规则和反向关系的 @Relationship,另外还有 init。备注列表会说明哪些地方无法完整转换,例如 fetched property、派生属性、有序关系和 CloudKit 限制。文件只在本页读取,不会上传。
你的 Core Data 模型
粘贴 .xcdatamodel 里的 contents 文件(XML),或把它拖到这里。不会上传任何内容。
把 contents 文件拖到这里
粘贴或拖入一个模型,就能看到 SwiftData 类。
事实出处
转换怎么做
- •类型:Integer 16、32、64 变成 Int16、Int32、Int64;Double、Float、Decimal、String 同名;Boolean 变成 Bool;Binary 变成 Data;URI 变成 URL;Date 和 UUID 不变。Transformable 属性沿用模型里的类名,模型指定了转换器时写上 .transformable(by:)。
- •可选与默认值:可选属性变成可选的 Swift 属性。模型里的默认值会写进 Swift 声明和 init 的默认参数。没有默认值的必填属性变成 init 的必填参数。
- •属性选项:单个属性的唯一约束变成 @Attribute(.unique);跨多个属性的约束变成 #Unique 宏(Apple 标注为 iOS 18、macOS 15 起)。Allows External Storage 变成 .externalStorage,renaming identifier 变成 originalName:。transient 属性变成 @Transient,不进入 init。
- •关系:一对多变成数组,删除规则 Nullify、Cascade、Deny、No Action 对应 .nullify、.cascade、.deny、.noAction。每一对关系只在一端写 inverse: 键路径,有一对多端时写在那一端,与 Apple 示例的写法一致。
- •继承:子实体变成带 @available(iOS 26, ...) 声明的子类,父类不再是 final,与 Apple 的 Adopting inheritance in SwiftData 一文一致。子类的 init 会调用 super.init。
- •由二进制元素组成的 fetch index 变成 #Index 宏(iOS 18、macOS 15 起)。其他没有对应项的内容会列在备注里,而不是猜着转换。
它不做什么
- •不迁移已有存储里的数据,也不写迁移方案。Apple 把这类工作称为 VersionedSchema 和 SchemaMigrationPlan;改动已上架 App 的模型之前,请先读 Apple 的相关页面。
- •不转换 fetched property、派生属性和复合属性,只把它们列出来。实体的 configuration 也不会带过来。
- •不了解你的自定义类。Transformable 类型按模型给出的类名写出,定义它的框架仍需你自己 import。
- •不检查结果能否在你的项目里编译。请读一遍代码、加入 target 并构建。如果模型要与 CloudKit 同步,请用 SwiftData 与 CloudKit 检查器检查结果。
- •不上传也不保存任何内容,关掉页面模型就没了。
常见问题
- 要粘贴的 XML 在哪里?
- 在 Finder 里右键 .xcdatamodeld 文件夹,选“显示包内容”,打开里面的 .xcdatamodel 文件夹,再打开名为 contents 的文件,它就是纯 XML。本页也能读取拖入的文件。有多个模型版本的 App 每个版本有一个 .xcdatamodel,请选你要转换的那个。
- SwiftData 支持像 Core Data 那样的实体继承吗?
- 支持。Apple 的 Adopting inheritance in SwiftData 一文展示了用 @Model 写的模型子类,示例里的子类标注了 @available(iOS 26, *)。Apple 还说,用一个布尔值或枚举就能区分情况时、或查询从不需要基类时,应避免继承。本页按这种方式转换父子实体,并为每一处写备注。
- 删除规则怎么对应?
- Apple 列出了 Schema.Relationship.DeleteRule 的四个值:cascade 删除所有相关模型,deny 在模型仍有相关模型时阻止删除,noAction 不改动相关模型,nullify 清除相关模型对被删除模型的引用。它们与 Core Data 的 Cascade、Deny、No Action、Nullify 一一对应。
- 为什么 inverse 只写在一端?
- Apple 的 SwiftData 示例只在关系对的一端写 inverse:,另一端交给 SwiftData 设置。本页把它写在每一对的一对多端;两端都是一对一时选其中一端。另一端的删除规则如果不是 Nullify,会保留成它自己的 @Relationship 行。
- 模型要与 CloudKit 同步会有什么问题?
- Apple 关于同步的 SwiftData 页面说,CloudKit 无法保证 unique 选项,要求关系可选,并且不支持 deny 删除规则。Apple 的 Core Data CloudKit 模型页面还说不支持唯一约束,每个关系都需要反向关系。如果模型标记为与 CloudKit 一起使用,备注会列出触犯这些规则的每个属性。
- 已有的存储能用新类打开吗?
- 本页无法判断。它写出的类沿用实体名、属性名和类型;Apple 的“在 Core Data App 中采用 SwiftData”示例里,两个版本的实体名、属性和关系是一致的。已有存储能否打开、已上架模型怎么改,请看 Apple 关于 VersionedSchema 和 SchemaMigrationPlan 的页面,并用真实数据的副本测试。