CoreData loadPersistentStores error

Recently I update my App a new version in App Store . What I do is only add a new Entity and add one new column to an existing Entity.Then over than 200 users run into crash when they update(Not all users run into this).

This is how I create Core Data Stack.
Code Block swiftclass AppGroupLocalPersistentContainer: NSPersistentContainer {    open override class func defaultDirectoryURL() -> URL {        let storeURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.mindo")        return storeURL!    }}extension NSPersistentContainer {    var url: URL? {        let url: URL? = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.mindo")        return url?.appendingPathComponent("Mindo.sqlite")    }}public class LocalCoreData {    deinit {        Logger.info("LocalCoreData deinit")    }    lazy var localContext: NSManagedObjectContext = {        let context = localContainer.viewContext        context.mergePolicy = NSMergePolicy(merge: NSMergePolicyType.mergeByPropertyObjectTrumpMergePolicyType)        context.automaticallyMergesChangesFromParent = true        context.stalenessInterval = 0        return context    }()    lazy var localContainer: NSPersistentContainer = {        let container = AppGroupLocalPersistentContainer(name: "Mindo", managedObjectModel: NSManagedObjectModel.mergedModel(from: [Bundle.main])!)        guard let description = container.persistentStoreDescriptions.first else {            fatalError("Failed to retrieve a persistent store description.")        }        description.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)        description.setOption(false as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)        description.shouldMigrateStoreAutomatically = true        description.shouldInferMappingModelAutomatically = true                container.loadPersistentStores(completionHandler: { _, error in            if let error = error as NSError? {                fatalError("Unresolved error \(error), \(error.userInfo)")            }        })        return container    }()}


And here is part of crash log I copy from Xcode Organizer.

Code Block Thread 0 name:Thread 0 Crashed:0   libswiftCore.dylib            	0x0000000187d45cb4 _assertionFailure(_:_:file:line:flags:) + 492 (AssertCommon.swift:132)1   libswiftCore.dylib            	0x0000000187d45cb4 _assertionFailure(_:_:file:line:flags:) + 492 (AssertCommon.swift:132)2   Mindo                         	0x0000000104245088 closure #1 in closure #1 in LocalCoreData.localContainer.getter + 604 (LocalCoreData.swift:39)3   Mindo                         	0x00000001042449a0 thunk for @escaping @callee_guaranteed (@guaranteed NSPersistentStoreDescription, @guaranteed Error?) -> () + 64 (<compiler-generated>:0)4   CoreData                      	0x000000018a3da570 -[NSPersistentStoreCoordinator _doAddPersistentStoreWithDescription:privateCopy:completeOnMainThread:withHandler:] + 1008 (NSPersistentStoreCoordinator.m:1461)5   CoreData                      	0x000000018a28146c -[NSPersistentStoreCoordinator addPersistentStoreWithDescription:completionHandler:] + 268 (NSPersistentStoreCoordinator.m:1507)6   CoreData                      	0x000000018a4ae880 -[NSPersistentContainer _loadStoreDescriptions:withCompletionHandler:] + 232 (NSPersistentContainer.m:284)7   CoreData                      	0x000000018a289658 -[NSPersistentContainer loadPersistentStoresWithCompletionHandler:] + 316 (NSPersistentContainer.m:271)8   Mindo                         	0x0000000104244d10 closure #1 in LocalCoreData.localContainer.getter + 848 (LocalCoreData.swift:36)

I know the error is occur in this line :LocalCoreData.swift:39
Code Block fatalError("Unresolved error \(error), \(error.userInfo)")

But I have no idea how to fix this.
Did you find a solution to this?
I am having almost identical crashes, but only on some devices (iPhone 7s and SE). I did not migrate any data, but I am using peristent store with descriptions. I cant recreate the crash myself.

Here is my crash log
Code Block languageException Type:  EXC_BREAKPOINT (SIGTRAP)Exception Codes: 0x0000000000000001, 0x00000001950b6a18Termination Signal: Trace/BPT trap: 5Termination Reason: Namespace SIGNAL, Code 0x5Terminating Process: exc handler [188]Triggered by Thread:  0Thread 0 name:Thread 0 Crashed:0   libswiftCore.dylib            	0x00000001950b6a18 _assertionFailure(_:_:file:line:flags:) + 492 (AssertCommon.swift:132)1   libswiftCore.dylib            	0x00000001950b6a18 _assertionFailure(_:_:file:line:flags:) + 492 (AssertCommon.swift:132)2   SPWidgetExtension             	0x0000000100471dd4 closure #1 in closure #1 in CoreDataHelper.persistentContainer.getter + 464 (CoreDataHelper.swift:153)3   SPWidgetExtension             	0x0000000100471e18 thunk for @escaping @callee_guaranteed (@guaranteed NSPersistentStoreDescription, @guaranteed Error?) -> () + 64 (<compiler-generated>:0)4   CoreData                      	0x000000019775a570 -[NSPersistentStoreCoordinator _doAddPersistentStoreWithDescription:privateCopy:completeOnMainThread:withHandler:] + 1008 (NSPersistentStoreCoordinator.m:1461)5   CoreData                      	0x000000019760146c -[NSPersistentStoreCoordinator addPersistentStoreWithDescription:completionHandler:] + 268 (NSPersistentStoreCoordinator.m:1507)6   CoreData                      	0x000000019782e880 -[NSPersistentContainer _loadStoreDescriptions:withCompletionHandler:] + 232 (NSPersistentContainer.m:284)7   CoreData                      	0x0000000197609658 -[NSPersistentContainer loadPersistentStoresWithCompletionHandler:] + 316 (NSPersistentContainer.m:271)8   SPWidgetExtension             	0x0000000100471bc4 closure #1 in CoreDataHelper.persistentContainer.getter + 620 (CoreDataHelper.swift:151)9   SPWidgetExtension             	0x00000001004717e0 CoreDataHelper.persistentContainer.getter + 40 (CoreDataHelper.swift:144)10  SPWidgetExtension             	0x00000001004657e4 context.get + 4 (CoreDataHelper.swift:27)11  SPWidgetExtension             	0x00000001004657e4 getContext + 28 (WidgetData.swift:274)12  SPWidgetExtension             	0x00000001004657e4 init + 48 (WidgetProvider.swift:21)


Anyone found the solution for this? Experiencing the same.

My loadPersistentStore completion error block is not being triggered

        container.loadPersistentStores { (description, error) in
            if let error = error {
                error.sendLog()
                fatalError(error.localizedDescription)
            }
        }

is this more of an assertion failure on coredata?

can't replicate it myself, but a few crash report happened in Testflight for some users.

I'm also having the same issues. Specially when the app is in background phase.

Moving this as an answer instead of a comment. Hope this helps someone experiencing the same issue

Found the solution to my issue, it's because I was calling it on Delegate's appDidFinishLaunching and apparently not all resources have been loaded yet at that point in time.

I had to change my persistentStore description to this:

description.shouldAddStoreAsynchronously = true
description.shouldMigrateStoreAutomatically = true
description.shouldInferMappingModelAutomatically = true

Noticed that it only happened on iOS 15.x

Its not the best at it means the store may create it before I did my first persistent store request. Probably adding in a queue manager will help, but that's a different issue

I have the same issue.

After the test, I found out that the problem was I move storeURL to shared container(App group), and then fetch CoreData in widget extension

In most time, the app works fine. But when I change dataModel, The problem arises。

In Debug, when I run project, CoreData migrate store automatically and there is no problem, because I'm not running widget extension at this point.

In Production, when I update app from an old version, CoreDataStack container loadPersistentStores failed some time. I think both app and extension fetch sqlite file at same time case migrate failed

When I remove the code from the widget that accesses coreData, the problem goes away

I hope I can help others who are going through the same problem as me

For anyone looking for a solution. I fired a TSI, and now figured out what is the problem.

Reply from Apple Developer Technical Support:

When sharing a Core Data store among multiple processes, like your main app and extensions, errors can happen when multiple processes try to load the store almost at the same time, because both processes triggers the migration, which leads to a crash or data consistency. In that case, I don’t see a solution, other than avoiding multiple processes loading the store at the same time.

Then, how to avoid multiple processes loading the store at the same time?

I normally consider two options:

  • Your extensions load the store with the readonly mode, and rely on the main app to change or migrate the store.
  • If that is not possible, coordinate the processes with your own mechanism. For example, KVO + sharing UserDefaults (UserDefaults(suiteName: <App Group ID>)) to monitor changes from other process in an app group.

What I have Done to avoid this problem:

Widgets(iOS 14+):

Load the store with the readonly mode.

#if APP_WIDGET
      description.setOption(true as NSNumber, forKey: NSReadOnlyPersistentStoreOption)
#endif

Today extension(iOS 13 +)

Check if migration is required before load persistent stores. If is, load persistent stores until migration is not required. If not, load persistent stores normally.

...
if container.isNeedMigration() {
      Logger.info("Need Migration")
      #if TODAY_EXTENSION
        while container.isNeedMigration() {
          do {
            sleep(3)
          }
        }
      #endif
    }
container.loadPersistentStores
...
....
....
extension NSPersistentContainer {
  var url: URL? {
    let url: URL? = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.xxxx.xxxx.xxxx")
    return url?.appendingPathComponent("xxxxx.sqlite")
  }
}
extension NSPersistentContainer {
  func isNeedMigration() -> Bool {
    guard let url = self.url else { return false }
    if FileManager.default.fileExists(atPath: url.path) {
      do {
        let sourceMetadata = try NSPersistentStoreCoordinator.metadataForPersistentStore(ofType: NSSQLiteStoreType, at: url, options: nil)
        let destinationModel = persistentStoreCoordinator.managedObjectModel
        return !destinationModel.isConfiguration(withName: nil, compatibleWithStoreMetadata: sourceMetadata)
      } catch {
        let e = error
        Logger.info("error when check xmode compatibile", e)
      }
    }
    return false
  }
}

Hope someone find a better way to avoid multiple processes loading the store at the same time.

CoreData loadPersistentStores error
 
 
Q