Edit: Fixed with iOS 18.1 Beta 5 (Build: 22B5054e).
Let's create a simple SwiftData
model with a codable OptionSet
.
@Model
final class Item {
var options: SomeOptions
struct SomeOptions: OptionSet, Codable {
let rawValue: Int
}
init(options: SomeOptions = .init(rawValue: .random(in: 0..<10))) {
self.options = options
}
}
When killing then relaunching the app, all items options
rawValues equal 0.
struct ContentView: View {
@Environment(\.modelContext) private var modelContext
@Query private var items: [Item]
var body: some View {
NavigationStack {
List(items) { item in
Text(item.options.rawValue.formatted()) // FIXME: this always diplays "0"
}
.toolbar {
ToolbarItem {
Button("Add item", systemImage: "plus", action: addItem)
}
}
}
}
private func addItem() {
withAnimation {
let newItem = Item()
modelContext.insert(newItem)
try! modelContext.save() // FIXME: if not saved, the OptionSet always equals 0 too
}
}
}
Any idea of what's going on please?
Tested with Xcode 15.0.
This looks like a SwiftData bug to me. One workaround for now is to store the raw value of the OptionSet
instead and use a transient property of the custom type to access it.
private var optionsStorage: SomeOptions.RawValue
@Transient
var options: SomeOptions {
get { SomeOptions(rawValue: optionsStorage) }
set { optionsStorage = newValue.rawValue }
}
We also need to adjust the initialisation
init(options: SomeOptions) {
self.optionsStorage = options.rawValue
}