Xcode SwiftUI 预览崩溃,模拟器和设备工作正常

Xcode SwiftUI Preview Crashes, Simulator and Device Works Fine

在我的 SwiftUI 应用程序开发过程中的某个时刻,canvas 预览停止加载。该应用程序使用 CoreData,崩溃日志表明持久性功能存在问题。该应用程序继续在设备上和使用模拟器时按预期工作。

预览中崩溃日志的顶部:

Path:                  /Users/USER/Library/Developer/Xcode/UserData/Previews/Simulator Devices/836D94C3-1BF9-40BD-88EA-85DDF55F71E0/data/Containers/Bundle/Application/0011D911-75A5-4D79-AFA2-34BA2CB9E805/Training.app/Training
Identifier:            Training
Version:               1.5 (11)
Code Type:             X86-64 (Native)
Parent Process:        launchd_sim [80779]
Responsible:           SimulatorTrampoline [984]
User ID:               501

Date/Time:             2021-08-17 16:55:41.451 +0100
OS Version:            macOS 11.5 (20G71)
Report Version:        12
Bridge OS Version:     3.0 (14Y908)
Anonymous UUID:        A9FE029F-99BA-7511-2780-E515C2BA21E9

Sleep/Wake UUID:       EA1649DE-D2A1-438F-8B86-9C8D63032F7F

Time Awake Since Boot: 160000 seconds
Time Since Wake:       11000 seconds

System Integrity Protection: enabled

Crashed Thread:        0  Dispatch queue: com.apple.main-thread

Exception Type:        EXC_BAD_INSTRUCTION (SIGILL)
Exception Codes:       0x0000000000000001, 0x0000000000000000
Exception Note:        EXC_CORPSE_NOTIFY

Termination Signal:    Illegal instruction: 4
Termination Reason:    Namespace SIGNAL, Code 0x4
Terminating Process:   exc handler [81046]

Application Specific Information:
Training/Persistence.swift:17: Fatal error: Unresolved error Error Domain=NSCocoaErrorDomain Code=134110 "An error occurred during persistent store migration." UserInfo={sourceURL=file:///Users/liamday/Library/Developer/Xcode/UserData/Previews/Simulator%20Devices/836D94C3-1BF9-40BD-88EA-85DDF55F71E0/data/Containers/Data/Application/723C3942-DBEE-4A0E-BBBE-5F3B7F5F01A1/Library/Application%20Support/Training.sqlite, reason=Cannot migrate store in-place: I/O error for database at /Users/liamday/Library/Developer/Xcode/UserData/Previews/Simulator Devices/836D94C3-1BF9-40BD-88EA-85DDF55F71E0/data/Containers/Data/Application/723C3942-DBEE-4A0E-BBBE-5F3B7F5F01A1/Library/Application Support/Training.sqlite.  SQLite error code:1, 'no such table: ZPROGRAMS', destinationURL=file:///Users/liamday/Library/Developer/Xcode/UserData/Previews/Simulator%20Devices/836D94C3-1BF9-40BD-88EA-85DDF55F71E0/data/Containers/Data/Application/723C3942-DBEE-4A0E-BBBE-5F3B7F5F01A1/Library/Application%20Support/Training.sqlite, NSUnderlyingError=0x6000016b1200 {Error Domain=NSCocoaErrorDomain Code=134110 "An error occurred during persistent store migration." UserInfo={NSSQLiteErrorDomain=1, NSFilePath=/Users/liamday/Library/Developer/Xcode/UserData/Previews/Simulator Devices/836D94C3-1BF9-40BD-88EA-85DDF55F71E0/data/Containers/Data/Application/723C3942-DBEE-4A0E-BBBE-5F3B7F5F01A1/Library/Application Support/Training.sqlite, NSUnderlyingException=I/O error for database at /Users/liamday/Library/Developer/Xcode/UserData/Previews/Simulator Devices/836D94C3-1BF9-40BD-88EA-85DDF55F71E0/data/Containers/Data/Application/723C3942-DBEE-4A0E-BBBE-5F3B7F5F01A1/Library/Application Support/Training.sqlite.  SQLite error code:1, 'no such table: ZPROGRAMS', reason=I/O error for database at /Users/liamday/Library/Developer/Xcode/UserData/Previews/Simulator Devices/836D94C3-1BF9-40BD-88EA-85DDF55F71E0/data/Containers/Data/Application/723C3942-DBEE-4A0E-BBBE-5F3B7F5F01A1/Library/Application Support/Training.sqlite.  SQLite error code:1, 'no such table: ZPROGRAMS'}}}, ["reason": Cannot migrate store in-place: I/O error for database at /Users/liamday/Library/Developer/Xcode/UserData/Previews/Simulator Devices/836D94C3-1BF9-40BD-88EA-85DDF55F71E0/data/Containers/Data/Application/723C3942-DBEE-4A0E-BBBE-5F3B7F5F01A1/Library/Application Support/Training.sqlite.  SQLite error code:1, 'no such table: ZPROGRAMS', "NSUnderlyingError": Error Domain=NSCocoaErrorDomain Code=134110 "An error occurred during persistent store migration." UserInfo={NSSQLiteErrorDomain=1, NSFilePath=/Users/liamday/Library/Developer/Xcode/UserData/Previews/Simulator Devices/836D94C3-1BF9-40BD-88EA-85DDF55F71E0/data/Containers/Data/Application/723C3942-DBEE-4A0E-BBBE-5F3B7F5F01A1/Library/Application Support/Training.sqlite, NSUnderlyingException=I/O error for database at /Users/liamday/Library/Developer/Xcode/UserData/Previews/Simulator Devices/836D94C3-1BF9-40BD-88EA-85DDF55F71E0/data/Containers/Data/Application/723C3942-DBEE-4A0E-BBBE-5F3B7F5F01A1/Library/Application Support/Training.sqlite.  SQLite error code:1, 'no such table: ZPROGRAMS', reason=I/O error for database at /Users/liamday/Library/Developer/Xcode/UserData/Previews/Simulator Devices/836D94C3-1BF9-40BD-88EA-85DDF55F71E0/data/Containers/Data/Application/723C3942-DBEE-4A0E-BBBE-5F3B7F5F01A1/Library/Application Support/Training.sqlite.  SQLite error code:1, 'no such table: ZPROGRAMS'}, "sourceURL": file:///Users/liamday/Library/Developer/Xcode/UserData/Previews/Simulator%20Devices/836D94C3-1BF9-40BD-88EA-85DDF55F71E0/data/Containers/Data/Application/723C3942-DBEE-4A0E-BBBE-5F3B7F5F01A1/Library/Application%20Support/Training.sqlite, "destinationURL": file:///Users/liamday/Library/Developer/Xcode/UserData/Previews/Simulator%20Devices/836D94C3-1BF9-40BD-88EA-85DDF55F71E0/data/Containers/Data/Application/723C3942-DBEE-4A0E-BBBE-5F3B7F5F01A1/Library/Application%20Support/Training.sqlite]
 
CoreSimulator 757.5 - Device: iPhone 12 Pro (836D94C3-1BF9-40BD-88EA-85DDF55F71E0) - Runtime: iOS 14.5 (18E182) - DeviceType: iPhone 12 Pro

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   libswiftCore.dylib              0x00007fff2f07cd1e _assertionFailure(_:_:file:line:flags:) + 1742
1   co.uk.LiamDay.Training          0x0000000105d3266a closure #1 in PersistenceController.init(inMemory:) + 890 (Persistence.swift:17)
2   co.uk.LiamDay.Training          0x0000000105d326fb thunk for @escaping @callee_guaranteed (@guaranteed NSPersistentStoreDescription, @guaranteed Error?) -> () + 139
3   CoreData                        0x00007fff251a7838 -[NSPersistentStoreCoordinator _doAddPersistentStoreWithDescription:privateCopy:completeOnMainThread:withHandler:] + 978
4   CoreData                        0x00007fff251a7c3a -[NSPersistentStoreCoordinator addPersistentStoreWithDescription:completionHandler:] + 236
5   CoreData                        0x00007fff2514b01b -[NSPersistentContainer _loadStoreDescriptions:withCompletionHandler:] + 272
6   CoreData                        0x00007fff2514aee4 -[NSPersistentContainer loadPersistentStoresWithCompletionHandler:] + 398
7   co.uk.LiamDay.Training          0x0000000105d32144 PersistenceController.init(inMemory:) + 1060 (Persistence.swift:15)
8   co.uk.LiamDay.Training          0x0000000105d31d01 one-time initialization function for shared + 17 (Persistence.swift:6)
9   libdispatch.dylib               0x00007fff201078df _dispatch_client_callout + 8
10  libdispatch.dylib               0x00007fff20108b16 _dispatch_once_callout + 20
11  libswiftCore.dylib              0x00007fff2f3a059a swift_once + 26
12  co.uk.LiamDay.Training          0x0000000105d32234 PersistenceController.shared.unsafeMutableAddressor + 52 (Persistence.swift:6)
13  co.uk.LiamDay.Training          0x0000000105e73ba0 TrainingApp.init() + 80 (TrainingApp.swift:12)
14  co.uk.LiamDay.Training          0x0000000105e73ce1 protocol witness for App.init() in conformance TrainingApp + 17
15  com.apple.SwiftUI               0x00007fff562e5376 static App.main() + 47
16  co.uk.LiamDay.Training          0x0000000105e73c6e static TrainingApp.$main() + 78 (TrainingApp.swift:10)
17  co.uk.LiamDay.Training          0x0000000105e73d04 main + 20
18  libdyld.dylib                   0x00007fff2025abbd start + 1

Thread 1:
0   libsystem_pthread.dylib         0x00007fff6033f420 start_wqthread + 0

Thread 2:
0   libsystem_pthread.dylib         0x00007fff6033f420 start_wqthread + 0

Thread 0 crashed with X86 Thread State (64-bit):
  rax: 0x0000000200000003  rbx: 0x0000000106005a90  rcx: 0xfffffffe00000000  rdx: 0x0000000000000003
  rdi: 0x00007fe683033208  rsi: 0x0000000000000103  rbp: 0x00007ffee9ed0430  rsp: 0x00007ffee9ed0390
   r8: 0x0000000106868a00   r9: 0x00000001068603e0  r10: 0x0000000000000040  r11: 0x000000000000003b
  r12: 0x0000000000000f30  r13: 0x00007ffee9ed0350  r14: 0x000000000000000b  r15: 0x00007ffee9ed0390
  rip: 0x00007fff2f07cd1e  rfl: 0x0000000000010246  cr2: 0x00007fff2067e4ee
  
Logical CPU:     1
Error Code:      0x00000000
Trap Number:     6

Thread 0 instruction stream:
  fe fe fe fe fe fe 00 b9-20 00 00 00 45 85 c0 74  ........ ...E..t
  07 41 0f bd c8 83 f1 1f-c1 e9 03 be 04 00 00 00  .A..............
  48 29 ce 8d 0c f5 00 00-00 00 48 c7 c2 ff ff ff  H)........H.....
  ff 48 d3 e2 48 f7 d2 44-89 c1 48 01 c1 48 21 d1  .H..H..D..H..H!.
  48 89 4d b8 48 8d 15 77-15 00 00 48 8d 7d b8 e8  H.M.H..w...H.}..
  1e 35 2d 00 4c 89 fc 48-8b 7d d0 e8 12 df 32 00  .5-.L..H.}....2.
 [0f]0b 55 48 89 e5 31 c0-5d c3 0f 1f 84 00 00 00  ..UH..1.]....... <==
  00 00 55 48 89 e5 41 57-41 56 41 55 41 54 53 50  ..UH..AWAVAUATSP
  4d 89 cc 45 89 c6 49 89-cf 48 89 d3 49 89 f5 ff  M..E..I..H..I...
  d7 49 89 d0 48 8d 3d bb-14 38 00 be 0b 00 00 00  .I..H.=..8......
  ba 02 00 00 00 48 89 c1-49 89 d9 6a 00 41 54 41  .....H..I..j.ATA
  56 41 57 e8 da f8 ff ff-48 83 c4 20 0f 0b 0f 1f  VAW.....H.. ....
  
Thread 0 last branch register state not available.

这是我的 Persistence.swift 文件:

import CloudKit

struct PersistenceController {
    //MARK: - 1. PERSISTENCE CONTROLLER
    static let shared = PersistenceController()
    //MARK: - 2. PERSISTENT CONTAINER
    let container: NSPersistentContainer
    //MARK: - 3. INIT (load the persistent store)
    init(inMemory: Bool = false) {
        container = NSPersistentContainer(name: "Training")
        if inMemory {
            container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
        }
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        })
    }
    //MARK: - 4. PREVIEW
    static var preview: PersistenceController = {
        let result = PersistenceController(inMemory: true)
        let viewContext = result.container.viewContext
        
        let plannedExercise1 =  PlannedWorkouts(context: viewContext)
        plannedExercise1.dateCreated = Date()
        plannedExercise1.dateOfWorkout = Date()
        plannedExercise1.duration = 3600.00
        plannedExercise1.totalDistanceUnit = "meters"
        plannedExercise1.totalDistanceDoubleValue = 5000.0
        plannedExercise1.totalEnergyBurnedUnit = "KCal"
        plannedExercise1.totalEnergyBurnedDoubleValue = 500.0
        plannedExercise1.workoutActivityType = 32
        plannedExercise1.id = UUID()
        
        let plannedExercise2 =  PlannedWorkouts(context: viewContext)
        plannedExercise2.dateCreated = K.init().EndOfWeek(weeksSinceAnchorDate: 1)
        plannedExercise2.dateOfWorkout = Date()
        plannedExercise2.duration = 3600.00
        plannedExercise2.totalDistanceUnit = "meters"
        plannedExercise2.totalDistanceDoubleValue = 5000.0
        plannedExercise2.totalEnergyBurnedUnit = "KCal"
        plannedExercise2.totalEnergyBurnedDoubleValue = 500.0
        plannedExercise2.workoutActivityType = 35
        plannedExercise2.id = UUID()
        
        let newStatisticChartView = ChartView(context: viewContext)
        newStatisticChartView.id = UUID()
        newStatisticChartView.chartViewRawValue = "dailyTrainingImpactChartView"
        
        let newGoalView = GoalViews(context: viewContext)
        newGoalView.startDate = K.init().EndOfWeek(weeksSinceAnchorDate: 1)
        newGoalView.endDate = K.init().EndOfWeek(weeksSinceAnchorDate: 2)
        newGoalView.id = UUID()
        newGoalView.totalDistanceUnit = "meters"
        newGoalView.totalDistanceDoubleValue = 30000
        newGoalView.workoutActivityType = Int16(32)
        
        let newProgram = Programs(context: viewContext)
        
        let newProgrammedWorkout = ProgrammedWorkouts(context: viewContext)
        
        let newPlannedProgram = PlannedPrograms(context: viewContext)
        
        
        do {
            try viewContext.save()
        } catch {
            let nsError = error as NSError
            fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
        }
        return result
    }()
}

我已经重新启动Xcode并清除了派生数据。接下来我应该尝试什么?或者这是 SwiftUI 预览器对复杂应用程序构建的限制?

您问题的答案在调试输出的长字符串中。简单来说就是更新持久化容器框架自动创建的数据库Training.sqlite有问题

尝试手动删除这些文件夹/文件。您可以在错误消息中找到完整路径。

此外,正如其他发帖人所指出的,建议在构建预览数据库时使用 PersistentController.preview。然后它将始终在内存中从头开始创建。

您在预览中使用的是 PersistenceController.preview 还是 PersistenceController.shared?总是在你的预览中使用 .preview,因为它避免了将数据库保存到磁盘——根据你的错误,它看起来像是在尝试保存到磁盘,这会有点工作,但你会 运行错误。还要确保您的视图没有调用 PersistenceController.shared 而是传递上下文或使用环境变量。