SwiftData|避免使用 String 类型数组

了解 SwiftData 支持的 Swift 类型,以及为什么不推荐在 SwiftData 中使用 String 类型的数组。

SwiftData|避免使用 String 类型数组

SwiftData 支持的类型

SwiftData 支持以下基本类型:

  • Int
  • String
  • Float
  • Bool(Apple 多个示例项目中在使用)
  • Date(Apple 多个示例项目中在使用)
  • TimeInterval(Backyard 示例项目中)
  • Double(Backyard 示例项目中)
  • Location(DataCache 示例项目中有使用)
  • URL

除此之外,也支持符合 Codable 协议的 Struct、Enum 类型。

避免使用 String 类型的数组(iOS 17)

iOS 17 中,若在 SwiftData 的模型属性或结构体中,使用 String 类型的数组,会导致以下错误:

Could not cast value of type 'Foundation.__NSSwiftData' (0x1bf9c7680) to 'NSArray' (0x11b013408).

在 DestinationVideo 项目中,有使用 Int 数组,但这个项目要求是 iOS18。在 iOS 17 上似乎和 String 数组有相同的问题。

我查询了苹果提供的多个 SwiftData 示例项目,包括 DestinationVideo、SampleTrip、DataCache、Backyard,均未使用 String 类型的数组。

💡
2025 年 4 月 25 日更新:
在 iOS 18 上,该问题似乎已经得到解决。苹果未明确说明,但在我的 Filmo 项目中使用 String 数组时,在 iOS 18 上运行没有出现问题。

错误原因探索

该问题可以搜索「swiftdata Struct array of strings」或者「swiftdata array of strings」。

以下帖子遇到相同的问题:

SwiftData: Error on decoding array in struct
I have a SwiftData @Model that contains a struct which contains an array. Why do I get the following runtime error when I fetch the model and access the struct? Could not cast value of type ′

和我的问题一样

SwiftData Transformable with Strin… | Apple Developer Forums

不使用 String 数组,如何存储 Tags 类型数据?

创建独立的 Model 模型

创建一个 Tag SwiftData 模型,然后这样使用它 tags:[Tag]

推荐采用扁平化组织,减少在 SwiftData 中使用 Struct 和 Enum。如果必须采用结构化数据,优先考虑创建一个新的模型 —— Struct 和 Enum 不支持在谓词中查询。

创建计算属性或方法(方便访问)