2017-09-20 2 views
0

Ich habe ein älteres Projekt/App, das ich auf eine 3.x-Version von Swift von Swift 2 bringen möchte. Im Zuge der Portierung des Codes habe ich ein neues Projekt mit derselben Bundle-ID neu gestartet und importiert der Code ist vorbei.Swift 2 zu Swift 3 Core Data in Xcode 9 - Wie kann ich über bereits gespeicherte Core Data "Daten" portieren?

Alles funktioniert jetzt in Swift 3.2 in Xcode 9 mit Ausnahme von Core Data. Jedes Gerät, auf dem eine ältere Version der App ausgeführt wird, stürzt beim Zugriff auf Core Data ab.

Der spezifische Fehler ist im Laden des NSManagedObjectModel.

OLD SWIFT 2 WAY:

Meine Coredata Datei heißt: "MyApp.xcdatamodeld"

lazy var managedObjectModel: NSManagedObjectModel = { 
    let modelURL = NSBundle.mainBundle().URLForResource("MyApp", withExtension: "momd")! 
    return NSManagedObjectModel(contentsOfURL: modelURL)! 
}() 

NEW SWIFT 3 WAY:

Meine neue Coredata Datei heißt: „MyApp. xcdatamodel“

lazy var managedObjectModel: NSManagedObjectModel = { 
    if let modelURL = Bundle.main.url(forResource: "MyApp", withExtension: "xcdatamodel") { 
    return NSManagedObjectModel(contentsOf: modelURL)! 
    } else { 
    let modelURLOld = Bundle.main.url(forResource: "MyApp", withExtension: "momd") 
    return NSManagedObjectModel(contentsOf: modelURLOld!)! 
    } 
} 

Wenn ich führen Sie den Code ich folgende Fehlermeldungen erhalten:

CoreData: annotation: Failed to load optimized model at path '/var/containers/Bundle/Application/50367482-FC2C-4553-B04B-68AD922B8128/MyApp.app/MyApp.momd/MyApp.omo' 

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'NSFetchRequest could not locate an NSEntityDescription for entity name 'UMyAppModel'' 

So findet mein neuer App-Code die Dateien nicht, die für CoreData geladen werden sollen.

Wie kann ich diese älteren CoreData-Dateien in meine App laden? Bei Bedarf kann ich eine Migration einrichten, aber das Problem ist, dass ich die älteren Core-Datendateien nicht sehen kann.

Ein Weg, ich die App bekommen laufen soll den folgenden Code hinzuzufügen:

let objectModel = NSManagedObjectModel.mergedModel(from: [Bundle.main]) 
    return objectModel! 

jedoch keine der früheren historischen Daten in die App geladen.

Wie kann ich migrieren oder Zugriff auf die ursprünglichen Coredata-Daten erhalten, um in die neuen Coredata-Dateien auf Geräten mit der alten Codeversion (swift 2) der App zu migrieren?

+0

Warum versuchen Sie die 'xcdatamodel' zu laden? So ist es nicht und wird von Swift 3 nicht benötigt. –

+0

Ja, Sie haben Recht. Ich schaute auf einen Kesseldrucker-Code aus einem neuen Coredata-Baseline-Projekt und fügte ihn zu App Delegate zurück. Das Problem ist jetzt, dass die App die alten Daten nicht sieht. – Ranknoodle

Antwort

0

Das Problem wurde behoben. Es hängt mit der Art zusammen, wie der NSPersistentContainer in meiner App initialisiert wurde. Der schnelle 3-Platten-Code wurde nicht in den neuen Datenspeicher migriert, noch wurde nach der alten SQL-Datenbank gesucht (die vermutlich die Hauptursache dafür war, dass die Daten nicht gefunden wurden).

Mein Code:

lazy var persistentContainer: NSPersistentContainer = { 
    let modelURL = Bundle.main.url(forResource: "MyApp", withExtension: "momd")! 
    let container = NSPersistentContainer(name: "MyApp", managedObjectModel: NSManagedObjectModel(contentsOf: modelURL)!) 

    let documentsDirectory = FileManager.default.urls(for: FileManager.SearchPathDirectory.documentDirectory, in: FileManager.SearchPathDomainMask.userDomainMask) 
    let storeUrl = self.applicationDocumentsDirectory.appendingPathComponent("MyApp.sqlite") 
    let description = NSPersistentStoreDescription() 

    description.shouldInferMappingModelAutomatically = true 
    description.shouldMigrateStoreAutomatically = true 

    container.persistentStoreDescriptions = [description] 
    container.persistentStoreDescriptions = [NSPersistentStoreDescription(url: storeUrl)] 

    container.loadPersistentStores(completionHandler: { (storeDescription, error) in 
    if let error = error as NSError? { 
     fatalError("Unresolved error \(error), \(error.userInfo)") 
    } 
    }) 
    return container 
}()