2015-10-25 21 views
13

Sto seguendo questo tutorial esattamente, che aggiunge CoreData di un'app esistente: https://www.youtube.com/watch?v=WcQkBYu86h8Come risolvere: "NSPersistentStoreCoordinator non ha archivi persistenti"?

Quando arrivo al seedPerson() moc.save(), l'applicazione si blocca con questo errore:

CoreData: error: Illegal attempt to save to a file that was never opened. "This NSPersistentStoreCoordinator has no persistent stores (unknown). It cannot perform a save operation.". No last error recorded.

È stato aggiunto NSManagedSubclass.

Il DataController è cablato e posso intervenire. Non è fino al save() che le cose vanno male. Qualche idea su cosa avrei potuto lasciare per causare questo errore?

+0

Forse hai lasciato fuori la chiamata a 'addPersistentStoreWithType: configuration: URL: options: error:'? È necessario aggiungere un archivio permanente prima di poter salvare i dati su di esso. –

+0

Pubblica il codice che crea lo stack di dati principale. –

risposta

2

Sfortunatamente, quel video utilizza del codice dal sito Web di Apple e quell'esempio di codice è difettoso. Il difetto principale è che memorizza nella cache il MOC prima che l'archivio permanente sia stato aggiunto al MOC. Pertanto, se la creazione dell'archivio non riesce, il contesto dell'oggetto gestito verrà inizializzato con un coordinatore di archivio permanente che non ha negozio.

È necessario utilizzare il debugger e scorrere il codice che crea il PSC (il metodo DataController.init) e vedere perché si verifica l'errore. Se si taglia/incolla allo stesso modo di quello nell'esempio, forse si è anche dimenticato di cambiare il nome del modello durante l'istanziazione del modello.

In ogni caso, la causa più probabile è che un codice di inizializzazione in quella funzione non è riuscito e in seguito si andrà felicemente con uno stack di dati principale che non ha negozi.

14

Ho seguito anche il tutorial di YouTube e ho avuto lo stesso problema. Ho appena rimosso il blocco thread in background che aggiunge l'archivio persistente e ha funzionato. Ecco il mio DataController:

import UIKit 
import CoreData 

class WellbetDataController: NSObject { 
    var managedObjectContext: NSManagedObjectContext 

    override init() { 
     // This resource is the same name as your xcdatamodeld contained in your project. 
     guard let modelURL = NSBundle.mainBundle().URLForResource("DataModel", withExtension:"momd") else { 
      fatalError("Error loading model from bundle") 
     } 

     // The managed object model for the application. It is a fatal error for the application not to be able to find and load its model. 
     guard let mom = NSManagedObjectModel(contentsOfURL: modelURL) else { 
      fatalError("Error initializing mom from: \(modelURL)") 
     } 

     let psc = NSPersistentStoreCoordinator(managedObjectModel: mom) 
     self.managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType) 
     self.managedObjectContext.persistentStoreCoordinator = psc 

     let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask) 
     let docURL = urls[urls.endIndex-1] 
     /* The directory the application uses to store the Core Data store file. 
     This code uses a file named "DataModel.sqlite" in the application's documents directory. 
     */ 
     let storeURL = docURL.URLByAppendingPathComponent("DataModel.sqlite") 
     do { 
      try psc.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: nil) 
     } catch { 
      fatalError("Error migrating store: \(error)") 
     } 



//  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)) { 
//   let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask) 
//   let docURL = urls[urls.endIndex-1] 
//   /* The directory the application uses to store the Core Data store file. 
//   This code uses a file named "DataModel.sqlite" in the application's documents directory. 
//   */ 
//   let storeURL = docURL.URLByAppendingPathComponent("DataModel.sqlite") 
//   do { 
//    try psc.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: nil) 
//   } catch { 
//    fatalError("Error migrating store: \(error)") 
//   } 
//  } 
    } 
} 
+1

Grazie! Si è imbattuto nello stesso problema: la rimozione di 'dispatch_async' l'ha risolto. –

+0

Mi sono imbattuto in un problema simile utilizzando un codice di esempio da un libro. Stavo cercando di impostare alcuni oggetti gestiti iniziali all'avvio dell'app a scopo di test. Spostando questa operazione sul thread principale significa che l'installazione di NSPersistentStoreCoordinator è terminata prima che qualcos'altro abbia la possibilità di provare a scrivere dati su un NSManagedObjectContext. Nel mio caso, credo che stavo cercando di scrivere su NSManagedObjectContext prima che il lavoro di installazione fosse completato nell'operazione asincrona. –

0

Il problema è su queste due linee:

guard let modelURL = NSBundle.mainBundle().URLForResource("DataModel", withExtension:"momd") else { 

& &

let storeURL = docURL.URLByAppendingPathComponent("DataModel.sqlite") 

DataModel deve essere cambiato al nome dell'applicazione se il CoreData era creato automaticamente da Xcode. Se vuoi inserire queste linee in AppDelegate.swift

0

Se questa è la prima volta che si esegue l'applicazione dopo aver messo i dati fondamentali in essa allora forse si potrebbe lavorare rimuovendo l'applicazione da simulatore ed eseguirlo nuovamente.

E 'successo a me e funziona dopo che l'ho fatto.

Problemi correlati