SwiftData framework crashes application when enumerations are part of arrays

If I use a Codable enum as the type in an array property on a Model, I get a crash. The message is something like:

Illegal attempt to use a Optional(Swift.Mirror.DisplayStyle.enum) as a Property

Minor change code example from a fresh project using SwiftData:

@Model
final class Item {
    var timestamp: Date
    var choices: [Choice]
    
    init(timestamp: Date,
         choices: [Choice]) {
        self.timestamp = timestamp
        self.choices = choices
    }
}



enum Choice: String, Codable {
    case beep, bloop
}

ContentView (largely unchanged):

import SwiftUI
import SwiftData

struct ContentView: View {
    @Environment(\.modelContext) private var modelContext
    @Query private var items: [Item]
    
    var body: some View {
        NavigationView {
            List {
                ForEach(items) { item in
                    NavigationLink {
                        VStack {
                            Text("Item at \(item.timestamp, format: Date.FormatStyle(date: .numeric, time: .standard))")
                            Text("\(item.choices.map({"\($0.rawValue)"}).joined())")
                        }
                    } label: {
                        Text(item.timestamp, format: Date.FormatStyle(date: .numeric, time: .standard))
                    }
                }
                .onDelete(perform: deleteItems)
            }
            .toolbar {
#if os(iOS)
                ToolbarItem(placement: .navigationBarTrailing) {
                    EditButton()
                }
#endif
                ToolbarItem {
                    Button(action: addItem) {
                        Label("Add Item", systemImage: "plus")
                    }
                }
            }
            Text("Select an item")
        }
    }

    private func addItem() {
        withAnimation {
            let newItem = Item(timestamp: Date(), choices: [.bloop, .beep])
            modelContext.insert(newItem)
        }
    }

    private func deleteItems(offsets: IndexSet) {
        withAnimation {
            for index in offsets {
                modelContext.delete(items[index])
            }
        }
    }
}

#Preview {
    ContentView()
        .modelContainer(for: Item.self, inMemory: true)
}

This is strange and seems like a bug as if I use Codable structs in this instance it is fine. Yet, if that Codable struct has an enum as a property, it also crashes with a different error.

Working:

import Foundation
import SwiftData

@Model
final class Item {
    var timestamp: Date
    var choices: [Choice]
    
    init(timestamp: Date,
         choices: [Choice]) {
        self.timestamp = timestamp
        self.choices = choices
    }
}



struct Choice: Codable {
    let foo: String
}

Also doesn't work:

import Foundation
import SwiftData

@Model
final class Item {
    var timestamp: Date
    var choices: [Choice]
    
    init(timestamp: Date,
         choices: [Choice]) {
        self.timestamp = timestamp
        self.choices = choices
    }
}



struct Choice: Codable {
    enum SpecificChoice: String, Codable {
        case beep, bloop
    }
    let foo: SpecificChoice
}

It seems really odd and arbitrary that an enum would cause these issues. There may be other cases involving enums, but to wrap up it seems enums as properties of Codables that live within an array on a SwiftData model, or an array of enums on a SwiftData model cause crashes.

Post not yet marked as solved Up vote post of nibsandxibs Down vote post of nibsandxibs
1.8k views

Replies

To be clear, it seems an enum not housed in an array is fine:


@Model

final class Item {

    var timestamp: Date

    var choice: Choice

    

    init(timestamp: Date,

         choice: Choice) {

        self.timestamp = timestamp

        self.choice = choice

    }

}


enum Choice: String, Codable {

    case beep, bloop

}

I also discovered this bug. I hope this is a bug, this blocks my development process for iOS 17 currently.

Array property in SwiftData model seems to cause hang in my app, and the following errors:

fault: Either a non nil result OR an error

CoreData: Either a non nil result OR an error

fault: Either a non nil result OR an error OR an exception

CoreData: Either a non nil result OR an error OR an exception

Foundation._GenericObjCError.nilError

I can confirm this issue for Xcode Version 15.0 beta 4 (15A5195m).

For me this issue also occurs for arrays of enums in a model.

@Model
final class Entity {
   var values: [SomeValue]

   init(values: [SomeValues]) {
      self.values = values // Fatal error: Illegal attempt to use a Optional(Swift.Mirror.DisplayStyle.enum) as a Property
   }
}

enum SomeValue {
   case value1
   case value2
}

...

let object = Entity(values: [.value1, .value2])

I have submitted a bug report: FB12674261

Has anyone found a fix/workaround for this? I am currently stuck on this issue.