swiftcore-datamagicalrecordcore-data-migration

Importing Core Data database to new project


I'm rewriting an application from Objective-C to Swift in a different project and I have a problem (fetch requests return empty results) with importing core data database, which in previous project were handled by MagicalRecord.

Here's what's I am doing:

  1. Copied database model file to the new project.

  2. Add that model file to the Compile Sources and Copy Bundle Resources in Build Phases.

  3. Changes entities code generation language from objc to swift inside model file.

  4. Create NSManagedObject subclasses

Things I've checked:

Here's how I initialize the stack (of course the strings here I've changed for known reasons, they are valid in the project):

    lazy var applicationDocumentsDirectory: URL = {
        let urls = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)
        var applicationDocumentsDirectoryRaw = urls[urls.count-1]
        applicationDocumentsDirectoryRaw.appendPathComponent("App_Name", isDirectory: true)
        return applicationDocumentsDirectoryRaw
    }()

    lazy var managedObjectModel: NSManagedObjectModel = {
        let modelURL = Bundle.main.url(forResource: "Model_Name", withExtension: "momd")!
        return NSManagedObjectModel.init(contentsOf: modelURL)!
    }()

    lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
        let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
        let url = self.applicationDocumentsDirectory.appendingPathComponent("CoreDataStore.sqlite")
        var failureReason = "There was an error creating or loading the application's saved data."
        do {
            try coordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: [NSMigratePersistentStoresAutomaticallyOption: true])
        } catch {
            var dict = [String: AnyObject]()
            dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data" as AnyObject?
            dict[NSLocalizedFailureReasonErrorKey] = failureReason as AnyObject?

            dict[NSUnderlyingErrorKey] = error as NSError
            let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
            NSLog("Unresolved error \(wrappedError), \(wrappedError.userInfo)")
            abort()
        }

        return coordinator
    }()

    lazy var managedObjectContext: NSManagedObjectContext = {
        let coordinator = self.persistentStoreCoordinator
        var managedObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
        managedObjectContext.persistentStoreCoordinator = coordinator
        return managedObjectContext
    }()

Solution

  • PersistentStore's url was NOT the same in the current and the previous project.

    I thought it was but it wasn't. One of the MagicalRecord's methods - NSPersistentStore.MR_defaultLocalStoreUrl - returned invalid NSURL.

    For the future generations - download your app's IPA via Xcode Device Manager and find out where its URL is manually!