简体   繁体   中英

Xcode 8 Core Data App Crash After Change of Project Name

I changed the name of my Xcode 8 project how described in this post How do I completely rename an Xcode project (ie inclusive of folders)?

Now when running the new version of the app on a device where the old version is installed the app crashes with the following error message:

[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class (OLD_PROJECTNAME.SomeObject) for key (NS.objects); the class may be defined in source code or a library that is not linked

So it seems that the old name doesn't fit to the core data stack of the renamed version. How can I change this name to make the app executable?

EDIT: This is the core data initialization code inside my AppDelegate.Swift :

// MARK: - Core Data stack

lazy var persistentContainer: NSPersistentContainer = {
    /*
     The persistent container for the application. This implementation
     creates and returns a container, having loaded the store for the
     application to it. This property is optional since there are legitimate
     error conditions that could cause the creation of the store to fail.
    */

    let container = NSPersistentContainer(name: "Data")


    container.loadPersistentStores(completionHandler: { (storeDescription, error) in
        if let error = error as NSError? {
            // Replace this implementation with code to handle the error appropriately.
            // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.

            /*
             Typical reasons for an error here include:
             * The parent directory does not exist, cannot be created, or disallows writing.
             * The persistent store is not accessible, due to permissions or data protection when the device is locked.
             * The device is out of space.
             * The store could not be migrated to the current model version.
             Check the error message to determine what the actual problem was.
             */
            fatalError("Unresolved error \(error), \(error.userInfo)")
        }
    })
    return container
}()

// MARK: - Core Data Saving support

func saveContext () {
    let context = persistentContainer.viewContext
    if context.hasChanges {
        do {
            try context.save()
        } catch {
            // Replace this implementation with code to handle the error appropriately.
            // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
            let nserror = error as NSError
            fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
        }
    }
}

It's a production app and the user should not lose any data after the update.

You mentioned in a comment that you have some transformable attributes. This is consistent with your error message, since [NSKeyedUnarchiver decodeObjectForKey:] is part of NSCoding , and since Core Data uses NSCoding with transformable attributes.

This isn't a Core Data problem. You'd get the same error if you used NSCoding on the values of those attributes and wrote the result to a file. In Swift, the full name of a class is something like AppName.ClassName . If AppName doesn't match, NSCoding can't decode the object. You saved objects with a name like OLD_PROJECTNAME.SomeObject , but now your class name is something like NEW_PROJECTNAME.SomeObject . NSCoding can't handle that on its own. You need to help it.

To fix this, you need to tell the archiving system what class to use. You can do that with the NSKeyedUnarchiver class method setClass(_:forClassName:) . You might have to experiment a little to get the syntax right but you'll have something like

NSKeyedUnarchiver.setClass(SomeClass.self, forClassName:"OLD_PROJECT_NAME.SomeObject")

You must do this before you attempt to create any objects that use this class so that it will affect how those objects are created. Since you're using Core Data that means before doing anything at all that touches Core Data in any way.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM