Search code examples
swiftxcodesqlitecore-datansuserdefaults

How can CoreData NSManagedObject != NIL but does not contain any data (data: <fault>)?


I encountered a pretty weird problem while using CoreData. I got an extension which saves and gets the active Profile saved in CoreData by using UserDefaults to store the active Profile ObjectID.

extension NSPersistentContainer {
    private var managedObjectIDKey: String {
        return "activeUserObjectID"
    }

    var activeUser: Profile? {
        get {
            guard let url = UserDefaults.standard.url(forKey: managedObjectIDKey) else {
                return nil
            }

            guard let managedObjectID = persistentStoreCoordinator.managedObjectID(forURIRepresentation: url) else {
                return nil
            }

            return viewContext.object(with: managedObjectID) as? Profile
        }
        set {
            guard let newValue = newValue else {
                UserDefaults.standard.removeObject(forKey: managedObjectIDKey)
                return
            }

            UserDefaults.standard.set(newValue.objectID.uriRepresentation(), forKey: managedObjectIDKey)
        }
    }
}

This whole think just works fine most of the time but then I found an very weird bug. The user is able to delete profiles (BUT NOT THE CURRENT ACTIVE ONE!)

The bug is the following: As soon as I delete e.g. Profile 2 while Profile 1 is activated, as soon as the deletion is finished Profile 1 is not activated anymore.

When trying to print out the activeUser variable it returns only data: fault instead of data: {all the data}. See the screenshot below:

The first line is printed before deleting Profile 2, the second line is printed directly after deleting the profile and the third line is printed after activating a profile again.

I have no idea what could cause this bug and spend a lot of time into finding this bug but haven't been succesful.

If you have any idea please let me now. Does maybe the ObjectID of all NSManagedObjects change after deleting one? Or is there anything else I didn't think of?

Thanks for your help in advance.


Solution

  • The object id of the object showing <fault> is different from the other two. If I understood correctly, your intent was to keep the the same profile active all the time, but this doesn't seem to be the case, i.e., something is activating a different profile.