swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
67.68k stars 10.39k forks source link

#Preview crash with custom `ModelContainer` and `.modelContainer` modifier #66537

Open wmorgue opened 1 year ago

wmorgue commented 1 year ago

Description Recently I follow Build an app with SwiftData and I created my own preview container, which doesn't quite work right.

Steps to reproduce If you conform @MainActor to let closure previewContainer, you will get a canvas preview crash and the data doesn't appear in preview and simulator too. To reproduce, run the following in a simulator or in a preview:

// Model.swift
@Model
final class VoiceItem {
    @Attribute(.unique)
    var id: String

    var name: String
    var creationDate: Date
    var recognizedText: String?

    init(id _: String, name: String, creationDate _: Date, recognizedText: String? = nil) {
        self.id = UUID().uuidString
        self.name = name
        self.creationDate = .now
        self.recognizedText = recognizedText
    }
}

// VoiceList.swift
struct VoiceList: View {

    @Query(sort: \.creationDate)
    private var voiceItems: [VoiceItem]

    var body: some View {
        NavigationStack {
            List(voiceItems) { item in
                Text(item.name)
            }
            .navigationTitle("Records")
            .navigationBarTitleDisplayMode(.inline)
        }
    }
}

#Preview("Voice List") {
    VoiceList()
        .modelContainer(previewContainer)
}

// previewContainer.swift

// Bug here with @MainActor
@MainActor
let previewContainer: ModelContainer = {
    do {
        let container = try ModelContainer(for: VoiceItem.self, ModelConfiguration(inMemory: true))

        for previewItem in VoiceItemPreview.previewData {
            container.mainContext.insert(object: previewItem)
        }

        return container
    } catch {
        fatalError("Failed to create container: \(error.localizedDescription)")
    }
}()

// VoiceItemPreview.swift
struct VoiceItemPreview {
    static var previewData: [VoiceItem] = [
        VoiceItem(id: UUID().uuidString, name: "Daily task", creationDate: Date(timeIntervalSince1970: 1_686_397_625), recognizedText: "Wake up, then open Xcode"),
        VoiceItem(id: UUID().uuidString, name: "Update CV", creationDate: Date(timeIntervalSince1970: 1_686_732_425), recognizedText: "Update CV in Figma"),
        VoiceItem(id: UUID().uuidString, name: "Lecture 7", creationDate: Date(timeIntervalSince1970: 1_687_677_605), recognizedText: "Good morning students. Nice to see you again"),
        VoiceItem(id: UUID().uuidString, name: "Unusual shopping", creationDate: Date(timeIntervalSince1970: 1_688_989_505), recognizedText: "Fruits, banana and something unusual"),
        VoiceItem(id: UUID().uuidString, name: "Podcast #125", creationDate: Date(timeIntervalSince1970: 1_689_526_805), recognizedText: "Greetings. In this episode we will talk about future of Vision Pro"),
    ]
}

// Voice_ActivityApp.swift
@main
struct Voice_ActivityApp: App {
    var body: some Scene {
        WindowGroup {
            VoiceList()
        }
        .modelContainer(for: VoiceItem.self)
    }
}

Screenshot 2023-06-10 at 16 01 44

Preview canvas doesn't work, and there is no data in the simulator. This only happens when using @MainActor with the let previewContainer: ModelContainer = {...}.

If we change previewContainer to code below:

let previewContainer: ModelContainer = {
    do {
        let container = try ModelContainer(for: VoiceItem.self, ModelConfiguration(inMemory: true))

        for previewItem in VoiceItemPreview.previewData {
            Task { @MainActor in
                container.mainContext.insert(object: previewItem)
            }
        }

        return container
    } catch {
        fatalError("Failed to create container: \(error.localizedDescription)")
    }
}()

we won't get any errors and everything will work.

Screenshot 2023-06-10 at 16 10 31

Expected behavior Data will appear in preview canvas/simulator, should not crash.

Environment

wmorgue commented 1 year ago

FB12300379

joelklabo commented 1 year ago

Still experiencing this: Version 15.0 beta 6 (15A5219j) was it fixed for anyone else?

kavehsaket commented 1 year ago

15.0.1 still same issue