The Problem:
When using SwiftData to store a custom enum, changes made to the enum value in the UI are not persisted when the app is relaunched. How can this issue be resolved to ensure that the enum changes are persisted?
The Solutions:
Solution 1: Fixed in iOS 17 Beta 7
The issue with persisting custom enums using SwiftData has been resolved in iOS 17 beta 7 and above. The following updated code should now function correctly:
enum ItemType: Int, Codable {
case foo = 0
case bar = 1
}
@Model
final public class Item {
var type: ItemType
init(type: ItemType) {
self.type = type
}
}
struct DetailView: View {
@Bindable var item: Item
var body: some View {
Picker("Type", selection: $item.type) {
Text("Foo").tag(ItemType.foo)
Text("Bar").tag(ItemType.bar)
}
.pickerStyle(.segmented)
}
}
Solution 2: Use a Transient Property and a RawValue Attribute
To persist a custom enum with SwiftData, consider using a transient property and a raw value attribute. The transient property provides a getter and setter to convert the enum to and from its raw value. The raw value attribute stores the actual value in the database.
Here’s an example:
enum SomeType: Int, Codable {
case foo = 0
case bar = 1
}
@Model
final public class Item {
@Transient var type: SomeType {
get { SomeType(rawValue: _type)! }
set { _type = newValue.rawValue }
}
@Attribute var _type: SomeType.RawValue
}
Solution 3: Nested enums
You can define your enum inside the model as a nested type. This will allow SwiftData to persist the enum’s value correctly.
@Model
final public class Item {
@Column(unique: true)
public var id: UUID // For simplicity
@Column
var type: ItemType
enum ItemType: Int, Codable {
case foo = 0
case bar = 1
}
init(type: ItemType) {
self.type = type
}
}
Q&A
How to fix iOS version 16 SwiftUI – SwiftData enum issue?
The issue has been fixed in iOS 17 beta 7 or newer.
Is there a workaround for the iOS 16 SwiftUI – SwiftData enum issue?
You can create a Transient wrapper to get around the problem for now.
Is enum placed inside the class also having the same issue?
The issue exists even when the enum is placed inside the class.
Video Explanation:
The following video, titled "WWDC23 SwiftData: how to use enums in SwiftData models ...", provides additional insights and in-depth exploration related to the topics discussed in this post.
WWDC introduced SwiftData, a new way of persisting data, basically CoreData on steriod and in SwiftUI's cloths, but this early beta, enum ...
The following video, titled "WWDC23 SwiftData: how to use enums in SwiftData models ...", provides additional insights and in-depth exploration related to the topics discussed in this post.
WWDC introduced SwiftData, a new way of persisting data, basically CoreData on steriod and in SwiftUI's cloths, but this early beta, enum ...