Core Data + File Protection

Hi, I'm getting a crash when trying to load the persistent store with Core Data when the device is locked. This seems to be related to File Protection as it no longer happens after setting the File Protection level to none on the NSPersistentStoreDescription.

Is there a better solution to get around this issue without downgrading the protection level?

Incident Identifier: 1c735122-b4a4-4cbe-b528-159afb89142a
CrashReporter Key:   4ECA6948-C687-4E2A-929B-CF32C866C0FC
Hardware Model:      iPhone9,3
Process:         AppName [6781]
Path:            /private/var/containers/Bundle/Application/79B1324C-8DE5-4C7A-A106-129216E0EC13/AppName.app/AppName
Identifier:      com.AppName
Version:         6.0.0 (6000)
Code Type:       arm64
Parent Process:   [1]

Date/Time:       2021-06-09T16:07:01.999Z
Launch Time:     2021-06-09T16:06:59Z
OS Version:      iPhone OS 14.4.1 (18D61)
Report Version:  104

Exception Type:  SIGTRAP
Exception Codes: TRAP_BRKPT at 0x1b0ae2aa8
Crashed Thread:  0

Thread 0 Crashed:
0   libswiftCore.dylib                   0x00000001b0ae2aa8 Swift._assertionFailure(_: Swift.StaticString, _: Swift.String, file: Swift.StaticString, line: Swift.UInt, flags: Swift.UInt32) -> Swift.Never + 488
1   PersistenceKit                       0x0000000107413fd4 closure #1 (__C.NSPersistentStoreDescription, Swift.Error?) -> () in $defer #1 () -> () in PersistenceKit.PersistenceClient.init(storageMode: PersistenceKit.StorageMode, shouldPerformMigration: Swift.Bool, userDefaults: __C.NSUserDefaults) -> PersistenceKit.PersistenceClient (PersistenceClient.swift:61)
2   PersistenceKit                       0x0000000107414018 reabstraction thunk helper from @escaping @callee_guaranteed (@guaranteed __C.NSPersistentStoreDescription, @guaranteed Swift.Error?) -> () to @escaping @callee_unowned @convention(block) (@unowned __C.NSPersistentStoreDescription, @unowned __C.NSError?) -> () (<compiler-generated>:0)
3   CoreData                             0x00000001b2fa4b80 -[NSPersistentStoreCoordinator _doAddPersistentStoreWithDescription:privateCopy:completeOnMainThread:withHandler:] + 996
4   CoreData                             0x00000001b2e5592c -[NSPersistentStoreCoordinator addPersistentStoreWithDescription:completionHandler:] + 236
5   CoreData                             0x00000001b3072d10 -[NSPersistentContainer _loadStoreDescriptions:withCompletionHandler:] + 224
6   CoreData                             0x00000001b2e5d738 -[NSPersistentContainer loadPersistentStoresWithCompletionHandler:] + 308
7   PersistenceKit                       0x00000001074148a8 function signature specialization <Arg[2] = Owned To Guaranteed> of PersistenceKit.PersistenceClient.init(storageMode: PersistenceKit.StorageMode, shouldPerformMigration: Swift.Bool, userDefaults: __C.NSUserDefaults) -> PersistenceKit.PersistenceClient (PersistenceClient.swift:58)
8   PersistenceKit                       0x0000000107412b90 PersistenceKit.PersistenceClient.init(storageMode: PersistenceKit.StorageMode, shouldPerformMigration: Swift.Bool, userDefaults: __C.NSUserDefaults) -> PersistenceKit.PersistenceClient (<compiler-generated>:0)
9   Core                                 0x00000001074e590c Core.PersistenceAdapter.init(storageMode: PersistenceKit.StorageMode) -> Core.PersistenceAdapter (<compiler-generated>:0)
10  Core                                 0x000000010758ff98 Core.Core.__allocating_init(bundleVersion: Swift.String?, endpoint: Core.Endpoint, urlSession: AppNameFoundation.URLSessionProtocol) -> Core.Core (PersistenceAdapter.swift:0)
11  AppName                             0x0000000104151aa0 globalinit_33_64B1F616F3D178BFE7ADFF1C7D88AA96_func53 (Core+SharedInstance.swift:25)
Answered by Frameworks Engineer in 678363022

You shouldn't just fatalError if you receive an error attempting to load the persistent stores. I recommend inspecting the errors and determining which codes you want to handle and which you want to error out for. I suspect in some of the cases, you're receiving SQLITE_AUTH as we discussed yesterday in the lab. You can write tests against your error handling by overriding loadPersistentStores via a subclass and inject the error in to the completion block.

Hi Majd,

It looks like you have an assertion firing on PersistenceClient.swift:61. Can you post that code?

-d

That line refers to a defer closure which makes the call to load the persistent store:

defer {
    self.persistentContainer?.loadPersistentStores { _, error in
        if let error = error {
            fatalError("Failed to load store: \(error)")
        }
    }
}
Accepted Answer

You shouldn't just fatalError if you receive an error attempting to load the persistent stores. I recommend inspecting the errors and determining which codes you want to handle and which you want to error out for. I suspect in some of the cases, you're receiving SQLITE_AUTH as we discussed yesterday in the lab. You can write tests against your error handling by overriding loadPersistentStores via a subclass and inject the error in to the completion block.

Is there a documentation page which lists the possible errors that one can receive when attempting to load the persistent stores? I can't seem to find that.

Core Data + File Protection
 
 
Q