Walter Pak
Walter Pak

Reputation: 107

CoreData: Failed to find a unique match for an NSEntityDescription

I am fairly certain CoreData is throwing the captioned error because of the line let newGoal = Goal(context: viewContext) in function addNewGoal. But I don't know another way to "rephrase" my func.

The search results in stackoverflow of the same error seem to be irrelevant to my issue here. (one is solved by using a static var instead of lazy var; the other one is about this error occurs randomly)

Great thanks in advance

(Apologies if this is a stupid question. I am a beginner learning by building a project. CoreData is vital to the concept of my project but I am completely out of my depth and it's killing me inside. )

import CoreData

struct PersistenceController {
    static let shared = PersistenceController()

    static var preview: PersistenceController = {
        let result = PersistenceController(inMemory: true)
        let viewContext = result.container.viewContext
        for _ in 0..<10 {
            let newItem = Goal(context: viewContext)
            
        }
        do {
            try viewContext.save()
        } catch {

            let nsError = error as NSError
            fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
        }
        return result
    }()

    let container: NSPersistentContainer

    init(inMemory: Bool = false) {
        container = NSPersistentContainer(name: "Project")
        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)")
            }
        })
    }
    
    func addNewGoal() {
        let result = PersistenceController(inMemory: true)
        let viewContext = result.container.viewContext
        let newGoal = Goal(context: viewContext)
        newGoal.passed = true
        newGoal.title = "New Goal \(Date())"
        newGoal.date = Date()
    }
    
    func addNewFail() {
        let result = PersistenceController(inMemory: true)
        let viewContext = result.container.viewContext
        let newGoal = Goal(context: viewContext)
        newGoal.passed = false
        newGoal.title = "New Goal \(Date())"
        newGoal.date = Date()
    }
    
}

Error

2021-08-11 05:05:44.981041+0800 Project[27243:1370905] [error] warning: Multiple NSEntityDescriptions claim the NSManagedObject subclass 'Goal' so +entity is unable to disambiguate.
CoreData: warning: Multiple NSEntityDescriptions claim the NSManagedObject subclass 'Goal' so +entity is unable to disambiguate.

2021-08-11 05:05:44.981226+0800 Project[27243:1370905] [error] warning:      'Goal' (0x6000032cc370) from NSManagedObjectModel (0x6000026fa7b0) claims 'Goal'.
CoreData: warning:       'Goal' (0x6000032cc370) from NSManagedObjectModel (0x6000026fa7b0) claims 'Goal'.

2021-08-11 05:05:44.981343+0800 Project[27243:1370905] [error] warning:      'Goal' (0x6000032d5e40) from NSManagedObjectModel (0x6000026bc5f0) claims 'Goal'.
CoreData: warning:       'Goal' (0x6000032d5e40) from NSManagedObjectModel (0x6000026bc5f0) claims 'Goal'.

2021-08-11 05:05:44.981447+0800 Project[27243:1370905] [error] error: +[Goal entity] Failed to find a unique match for an NSEntityDescription to a managed object subclass
CoreData: error: +[Goal entity] Failed to find a unique match for an NSEntityDescription to a managed object subclass

Edit: model file

Upvotes: 3

Views: 2478

Answers (2)

SeaSpell
SeaSpell

Reputation: 758

Its saying you defined a subclass of NSManaged object called Goal twice. It also says you define two models with the same class and it can't tell which one you want. Can you show your two model files?

Upvotes: 0

Yrb
Yrb

Reputation: 9665

First, get rid of the:

let result = PersistenceController(inMemory: true)

line and make the next line:

let viewContext = container.viewContext

You already have the container variable scoped to the whole struct so it is available in the PersistenceController struct.

Your function would be this:

func addNewGoal() {
    let viewContext = container.viewContext
    let newGoal = Goal(context: viewContext)
    newGoal.passed = true
    newGoal.title = "New Goal \(Date())"
    newGoal.date = Date()
}

As to the errors, according to this answer the problem is caused having two models loaded at the same time, and by calling PersistenceController(inMemory: true) I think you may have done that.

Also, the whole point of having the shared var is so you are only using one instance of the PersistenceController. You certainly don't want to initialize it by passing inMemory: true which it is already initialized with.

Upvotes: 4

Related Questions