I just released an App update the didn't touch ANYTHING to do with Core Data (nothing changed in our Coredata code for at least 8 months). The update uses SDK for iOS 18 and Xcode 16.2 and the app now requires iOS 18 and was a minor bug patch and UI improvements for recent iOS changes.
Since the update we are getting a steady trickle of users on iOS 18, some who allow the App to store data in iCloud (Cloudkit) and others who do not, all reporting that after the update to our recent release ALL their data is gone?!
I had not seen this on ANY device until today when I asked a friend who uses the App if they had the issue and it turned out they did, so I hooked their device up to Xcode and ALL the data in the CoreData database was gone?! They are NOT using iCloud. There were no errors or exceptions on Xcode console but a below code returned NO records at all?!
Chart is custom entity and is defined as:
@interface Chart : NSManagedObject {}
let moc = pc.viewContext
let chartsFetch = NSFetchRequest<NSFetchRequestResult>(entityName:"Charts") // Fetch all Charts
do {
let fetchedCharts = try moc.fetch(chartsFetch) as! [Chart]
for chart in fetchedCharts {
....
}
}
A break point inside the do on fetchedCharts show there are NO objects returned.
This is a serious issue and seems like an iOS 18 thing. I saw some people talking in here about NSFetchRequest issues with iOS 18. I need some guidance here from someone Apple engineer here who knows what the status of these NSFetchrequest bugs are and what possible workarounds are. Becasue this problem will grow for me as more users update to iOS 18.
we DID open the CoreData store and found 0 (ZERO) Chart. entities where before the update there had been many?! Was that not clear from the explanation associated with the code snippet?
Yeah, I saw the fetch in your code snippet. What I'd like to confirm though is that the Core Data store you open has the right path. When your app is updated, the absolute path to the app's container ("Application_Home") may change. (See the “Managing Data Across Updates” section in Testing iOS App Updates.) If you rely on the absolute path in some way to manage your Core Data store URL, it may turn out that you create and open a new empty store in somewhere else, while the original store is still there in your app's container.
The other point I believe is worth mentioning: If your app implements the logic to create a new (empty) store when hitting a Core Data failure, you might run into the issue as well. A Core Data failure can happen when the store is data-protected or corrupted.
If your app tries to access the Core Data store when running in the background and the store is data-protected, you will likely hit a SQLITE_AUTH
error. See Encrypting Your App’s Files for more information on data protection.
Regarding corrupted stores, here are several cases I can think of:
a. You missed the -wal
file when copying the database using file system APIs.
b. Your app is suspended or killed when Core Data is accessing the store. This can happen when your app is suspended (because of running out of the background execution time) while accessing a Core Data store. In this case, you will likely get a crash with the exception code 0xdead10cc
before hitting a corrupted store, indicating that your app “has been terminated by the OS because it held on to a file lock or sqlite database lock during suspension.” See TN2151 for more details.
c. Lightweight migration process is re-entered. Depending on your data set, a Core Data lightweight migration can take long time. If you access your Core Data stack from a different thread while a migration process is ongoing, you can trigger another migration on the same store, which may lead to a corrupted store.
Best,
——
Ziqiao Chen
Worldwide Developer Relations.