SwiftUI Preview 与 Core Data 崩溃 'NSInvalidArgumentException'
SwiftUI Preview crashes with Core Data 'NSInvalidArgumentException'
我无法使用 Canvas 预览应用程序的视图,因为我总是收到错误消息:
"Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: 'An NSManagedObject of class
'App.MPG_A' must have a valid NSEntityDescription."
现在更详细:在我想预览的视图中,我有一个抽象的@Binding class MultiplayerGame (MPG A or MPG B (subclasses) MultiplayerGame 是一个subclass of Game (下图)
评论:MultiplayerGame也是一个抽象实体(和Game一样)和“Class”->“MPG B”
当我想通过在预览中创建一个 moc 对象来预览 class 以下 class 时,我的应用程序崩溃了,但我不知道为什么:
import SwiftUI
import CoreData
import Combine
struct StandingEditView: View {
//multiplayer game with MPG A or MPG B class
@Binding var game : MultiplayerGame
@State private var invokeFunction : Bool = false
var body: some View {
VStack{
List{
ForEach(game.players!, id: \.self){ player in
HStack{
Text("\(player.name)")
}
}
}
Button(action: {
invokeFunction.toggle()
}, label: {
Text("Button")
})
}
}
}
struct StandingEditView_Previews: PreviewProvider {
static let moc = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
static var previews: some View {
let game : MultiplayerGame = Standing(context: moc)
let p1 : Player = Player(context: moc)
let p2 : Player = Player(context: moc)
let p3 : Player = Player(context: moc)
p1.name = "Player One"
p2.name = "Player Two"
p3.name = "Player Three"
game.players = [p1,p2,p3]
return StandingEditView(game: .constant(game))
}
}
而 Player 的唯一(非默认)属性是 -> var name : String
我也试过使用 AppDelegate,但也没用...
错误一定是因为预览和 moc-Object 而发生的,因为代码本身编译并且其他视图是可见的而没有错误。
感谢您的帮助!
您需要为上下文设置堆栈。 NSManagedObjectContext
一定知道你的型号。
以下StackBuilder
class提供temporary
版本适合预览。
private final class StackBuilder {
private let modelName = "Model" // must match your model filename
public enum Configuration {
case temporary
case permanent
}
let configuration: Configuration
public init(_ configuration: Configuration = .permanent) {
self.configuration = configuration
}
public func load() throws -> NSPersistentContainer {
var errors = [Error]()
let persistentContainer = NSPersistentContainer(name: modelName)
persistentContainer.persistentStoreDescriptions = [description(for: configuration)]
persistentContainer.loadPersistentStores { (value, error) in
if error != nil {
errors.append(error!)
}
}
if errors.count > 0 {
throw errors.first!
}
return persistentContainer as NSPersistentContainer
}
private func description(for configuration: Configuration) -> NSPersistentStoreDescription {
let desc = NSPersistentStoreDescription(url: NSPersistentContainer.defaultDirectoryURL())
switch configuration {
case .temporary:
desc.type = NSInMemoryStoreType
case .permanent:
desc.shouldInferMappingModelAutomatically = true
desc.shouldMigrateStoreAutomatically = true
desc.type = NSSQLiteStoreType
}
return desc
}
}
可能需要将上下文作为环境对象传递。
static var previews: some View {
return StandingEditView(game: .constant(game))
.environment(\.managedObjectContext, moc)
}
由于我已经尝试了所有其他可能性,但没有任何帮助,我创建了一个新项目并检查了 CoreData
。
然后我在 CoreData
文件中创建了主要的 class 并在 "ContentView"
.
中用 Game
替换了 Item
同样在 PersistenceController
中,我将 var preview : PersistenceController
下的 Item
替换为 Game
,并使用 codegen "Manual/None"
创建了所有 classes .
现在一切正常。
我无法使用 Canvas 预览应用程序的视图,因为我总是收到错误消息:
"Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'An NSManagedObject of class 'App.MPG_A' must have a valid NSEntityDescription."
现在更详细:在我想预览的视图中,我有一个抽象的@Binding class MultiplayerGame (MPG A or MPG B (subclasses) MultiplayerGame 是一个subclass of Game (下图)
评论:MultiplayerGame也是一个抽象实体(和Game一样)和“Class”->“MPG B”
当我想通过在预览中创建一个 moc 对象来预览 class 以下 class 时,我的应用程序崩溃了,但我不知道为什么:
import SwiftUI
import CoreData
import Combine
struct StandingEditView: View {
//multiplayer game with MPG A or MPG B class
@Binding var game : MultiplayerGame
@State private var invokeFunction : Bool = false
var body: some View {
VStack{
List{
ForEach(game.players!, id: \.self){ player in
HStack{
Text("\(player.name)")
}
}
}
Button(action: {
invokeFunction.toggle()
}, label: {
Text("Button")
})
}
}
}
struct StandingEditView_Previews: PreviewProvider {
static let moc = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
static var previews: some View {
let game : MultiplayerGame = Standing(context: moc)
let p1 : Player = Player(context: moc)
let p2 : Player = Player(context: moc)
let p3 : Player = Player(context: moc)
p1.name = "Player One"
p2.name = "Player Two"
p3.name = "Player Three"
game.players = [p1,p2,p3]
return StandingEditView(game: .constant(game))
}
}
而 Player 的唯一(非默认)属性是 -> var name : String
我也试过使用 AppDelegate,但也没用...
错误一定是因为预览和 moc-Object 而发生的,因为代码本身编译并且其他视图是可见的而没有错误。
感谢您的帮助!
您需要为上下文设置堆栈。 NSManagedObjectContext
一定知道你的型号。
以下StackBuilder
class提供temporary
版本适合预览。
private final class StackBuilder {
private let modelName = "Model" // must match your model filename
public enum Configuration {
case temporary
case permanent
}
let configuration: Configuration
public init(_ configuration: Configuration = .permanent) {
self.configuration = configuration
}
public func load() throws -> NSPersistentContainer {
var errors = [Error]()
let persistentContainer = NSPersistentContainer(name: modelName)
persistentContainer.persistentStoreDescriptions = [description(for: configuration)]
persistentContainer.loadPersistentStores { (value, error) in
if error != nil {
errors.append(error!)
}
}
if errors.count > 0 {
throw errors.first!
}
return persistentContainer as NSPersistentContainer
}
private func description(for configuration: Configuration) -> NSPersistentStoreDescription {
let desc = NSPersistentStoreDescription(url: NSPersistentContainer.defaultDirectoryURL())
switch configuration {
case .temporary:
desc.type = NSInMemoryStoreType
case .permanent:
desc.shouldInferMappingModelAutomatically = true
desc.shouldMigrateStoreAutomatically = true
desc.type = NSSQLiteStoreType
}
return desc
}
}
可能需要将上下文作为环境对象传递。
static var previews: some View {
return StandingEditView(game: .constant(game))
.environment(\.managedObjectContext, moc)
}
由于我已经尝试了所有其他可能性,但没有任何帮助,我创建了一个新项目并检查了 CoreData
。
然后我在 CoreData
文件中创建了主要的 class 并在 "ContentView"
.
Game
替换了 Item
同样在 PersistenceController
中,我将 var preview : PersistenceController
下的 Item
替换为 Game
,并使用 codegen "Manual/None"
创建了所有 classes .
现在一切正常。