fetchAll returning empty array #383

Open
opened 2025-12-29 15:30:36 +01:00 by adam · 10 comments
Owner

Originally created by @darrenasaro on GitHub (Mar 17, 2022).

I have an app which stores an entity class EntityA: NSManagedObject {...}
I have the following simplified CoreData code to fetch this entity

    let container = NSPersistentContainer(name: "Model")
    let context = container.viewContext
    let coordinator = NSPersistentStoreCoordinator(managedObjectModel: container.managedObjectModel)
    
    let documentsPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
    let persistentStoreURL = documentsPath.appendingPathComponent("Model.sqlite")
    
    try! coordinator.addPersistentStore(
      ofType: NSSQLiteStoreType,
      configurationName: nil,
      at: persistentStoreURL,
      options: [:]
    )

    container.loadPersistentStores { _, _ in }
    
    let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "EntityA")
    try! context.fetch(fetchRequest) as! [EntityA] // array populated with multiple objects

I created the equivalent CoreStore code

    let dataStack = DataStack(xcodeModelName: "Model")

    let documentsPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
    let sqliteFileUrl = documentsPath.appendingPathComponent("Model.sqlite")
    
    let storage = SQLiteStore(fileURL: sqliteFileUrl)
    try! dataStack.addStorageAndWait(storage)

    try! dataStack.fetchAll(From<ModelA>(nil)) // array empty

The CoreData code returns the properly populated array while CoreStore returns an empty array. I tried initializing SQLiteStore with a number of different options, and tried the async versions of addStorage all to no avail. I set breakpoints in the relevant CoreStore functions, but could not find anything glaring that would indicate the issue. Not sure if this is a bug or if I am misusing CoreStore but any help here would be much appreciated.

Originally created by @darrenasaro on GitHub (Mar 17, 2022). I have an app which stores an entity `class EntityA: NSManagedObject {...}` I have the following simplified CoreData code to fetch this entity ``` let container = NSPersistentContainer(name: "Model") let context = container.viewContext let coordinator = NSPersistentStoreCoordinator(managedObjectModel: container.managedObjectModel) let documentsPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] let persistentStoreURL = documentsPath.appendingPathComponent("Model.sqlite") try! coordinator.addPersistentStore( ofType: NSSQLiteStoreType, configurationName: nil, at: persistentStoreURL, options: [:] ) container.loadPersistentStores { _, _ in } let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "EntityA") try! context.fetch(fetchRequest) as! [EntityA] // array populated with multiple objects ``` I created the equivalent CoreStore code ``` let dataStack = DataStack(xcodeModelName: "Model") let documentsPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] let sqliteFileUrl = documentsPath.appendingPathComponent("Model.sqlite") let storage = SQLiteStore(fileURL: sqliteFileUrl) try! dataStack.addStorageAndWait(storage) try! dataStack.fetchAll(From<ModelA>(nil)) // array empty ``` The CoreData code returns the properly populated array while CoreStore returns an empty array. I tried initializing `SQLiteStore` with a number of different options, and tried the async versions of `addStorage` all to no avail. I set breakpoints in the relevant CoreStore functions, but could not find anything glaring that would indicate the issue. Not sure if this is a bug or if I am misusing CoreStore but any help here would be much appreciated.
adam added the ios/compiler bug label 2025-12-29 15:30:36 +01:00
Author
Owner

@JohnEstropia commented on GitHub (Mar 17, 2022):

@darrenasaro Since you're not getting an error at try! dataStack.fetchAll(), then it's likely your SQLite file does not contain records in the first place.

@JohnEstropia commented on GitHub (Mar 17, 2022): @darrenasaro Since you're not getting an error at `try! dataStack.fetchAll()`, then it's likely your SQLite file does not contain records in the first place.
Author
Owner

@darrenasaro commented on GitHub (Mar 17, 2022):

It does as evidenced by the CoreData implementation returning a populated array. I've swapped these implementations verbatim with all else equal and the CoreData one always returns a populated array while the CoreStore implementation always returns empty.

@darrenasaro commented on GitHub (Mar 17, 2022): It does as evidenced by the CoreData implementation returning a populated array. I've swapped these implementations verbatim with all else equal and the CoreData one always returns a populated array while the CoreStore implementation always returns empty.
Author
Owner

@JohnEstropia commented on GitHub (Mar 17, 2022):

@darrenasaro Can you print the original file URL from here

let persistentStore = try! coordinator.addPersistentStore(
      ofType: NSSQLiteStoreType,
      configurationName: nil,
      at: persistentStoreURL,
      options: [:]
    )
print(persistentStore.url)

and check if it's still the same URL passed to SQLiteStore here?

let sqliteFileUrl = documentsPath.appendingPathComponent("Model.sqlite")
@JohnEstropia commented on GitHub (Mar 17, 2022): @darrenasaro Can you print the original file URL from here ``` let persistentStore = try! coordinator.addPersistentStore( ofType: NSSQLiteStoreType, configurationName: nil, at: persistentStoreURL, options: [:] ) print(persistentStore.url) ``` and check if it's still the same URL passed to `SQLiteStore` here? ``` let sqliteFileUrl = documentsPath.appendingPathComponent("Model.sqlite") ```
Author
Owner

@darrenasaro commented on GitHub (Mar 17, 2022):

@JohnEstropia They are the same. I've recreated the issue in it's simplest form here
https://github.com/darrenasaro/fetch-demo

@darrenasaro commented on GitHub (Mar 17, 2022): @JohnEstropia They are the same. I've recreated the issue in it's simplest form here [https://github.com/darrenasaro/fetch-demo](url)
Author
Owner

@JohnEstropia commented on GitHub (Mar 18, 2022):

Thanks for isolating the issue! I'll investigate

@JohnEstropia commented on GitHub (Mar 18, 2022): Thanks for isolating the issue! I'll investigate
Author
Owner

@JohnEstropia commented on GitHub (Mar 18, 2022):

@darrenasaro Oh boy... It looks like NSPersistentContainer forces the file directory to where it likes. Try this out:

print("Expected URL:\n\(sqliteFileUrl)")
container.loadPersistentStores { persistentStore, _ in
    print("NSPersistentContainer:\n\(persistentStore.url!)")
}
let store = try! dataStack.addStorageAndWait(storage)
print("CoreStore:\n\(store.fileURL)")

Look at the output:

Expected URL:
file:///Users/<User>/Library/Developer/CoreSimulator/Devices/185DD2F2-A17F-4FBB-9D90-2BDA5B802F57/data/Containers/Data/Application/2732C567-34D7-42EF-942C-2DB5F34CD27F/Documents/Model.sqlite

NSPersistentContainer:
file:///Users/<User>/Library/Developer/CoreSimulator/Devices/185DD2F2-A17F-4FBB-9D90-2BDA5B802F57/data/Containers/Data/Application/2732C567-34D7-42EF-942C-2DB5F34CD27F/Library/Application%20Support/Model.sqlite

CoreStore:
file:///Users/<User>/Library/Developer/CoreSimulator/Devices/185DD2F2-A17F-4FBB-9D90-2BDA5B802F57/data/Containers/Data/Application/2732C567-34D7-42EF-942C-2DB5F34CD27F/Documents/Model.sqlite

Note that NSPersistentContainer moved the directory to Library/Application Support/, while CoreStore keeps it to where it's actually configured (/Documents/).

@JohnEstropia commented on GitHub (Mar 18, 2022): @darrenasaro Oh boy... It looks like `NSPersistentContainer` forces the file directory to where it likes. Try this out: ``` print("Expected URL:\n\(sqliteFileUrl)") ``` ``` container.loadPersistentStores { persistentStore, _ in print("NSPersistentContainer:\n\(persistentStore.url!)") } ``` ``` let store = try! dataStack.addStorageAndWait(storage) print("CoreStore:\n\(store.fileURL)") ``` Look at the output: ``` Expected URL: file:///Users/<User>/Library/Developer/CoreSimulator/Devices/185DD2F2-A17F-4FBB-9D90-2BDA5B802F57/data/Containers/Data/Application/2732C567-34D7-42EF-942C-2DB5F34CD27F/Documents/Model.sqlite NSPersistentContainer: file:///Users/<User>/Library/Developer/CoreSimulator/Devices/185DD2F2-A17F-4FBB-9D90-2BDA5B802F57/data/Containers/Data/Application/2732C567-34D7-42EF-942C-2DB5F34CD27F/Library/Application%20Support/Model.sqlite CoreStore: file:///Users/<User>/Library/Developer/CoreSimulator/Devices/185DD2F2-A17F-4FBB-9D90-2BDA5B802F57/data/Containers/Data/Application/2732C567-34D7-42EF-942C-2DB5F34CD27F/Documents/Model.sqlite ``` Note that `NSPersistentContainer` moved the directory to `Library/Application Support/`, while `CoreStore` keeps it to where it's actually configured (`/Documents/`).
Author
Owner

@JohnEstropia commented on GitHub (Mar 18, 2022):

It looks like the behavior is correct if you use the NSPersistentStoreDescription method instead:
Screen Shot 2022-03-18 at 10 13 28

@JohnEstropia commented on GitHub (Mar 18, 2022): It looks like the behavior is correct if you use the `NSPersistentStoreDescription` method instead: <img width="497" alt="Screen Shot 2022-03-18 at 10 13 28" src="https://user-images.githubusercontent.com/3029684/158918893-ac7d780f-dc92-499c-8dcd-0257e8349f0b.png">
Author
Owner

@JohnEstropia commented on GitHub (Mar 18, 2022):

Since it looks like CoreStore is behaving correctly here, I'm marking this issue as a ios/compiler bug. I suggest that you find the original path actually created by the NSPersistentContainer for your store, and then pass it to CoreStore in your migrated code. I'd also recommend submitting a bug report to Apple through feedback assistant, since this issue seems destructive enough on its own.

@JohnEstropia commented on GitHub (Mar 18, 2022): Since it looks like CoreStore is behaving correctly here, I'm marking this issue as a `ios/compiler bug`. I suggest that you find the original path actually created by the `NSPersistentContainer` for your store, and then pass it to CoreStore in your migrated code. I'd also recommend submitting a bug report to Apple through feedback assistant, since this issue seems destructive enough on its own.
Author
Owner

@darrenasaro commented on GitHub (Mar 18, 2022):

@JohnEstropia Thank you for investigating this! Excited I can use this library now. This CoreData behavior definitely seems to be problematic. I actually downloaded the container to investigate and it looks like CoreData puts an sqlite file in /Documents/(or whatever directory you specify) and Library/Application Support/, the former file having just structure data and the latter containing structure data as well as actual records. Super weird. Will follow with a bug report.

@darrenasaro commented on GitHub (Mar 18, 2022): @JohnEstropia Thank you for investigating this! Excited I can use this library now. This CoreData behavior definitely seems to be problematic. I actually downloaded the container to investigate and it looks like CoreData puts an sqlite file in `/Documents/`(or whatever directory you specify) and `Library/Application Support/`, the former file having just structure data and the latter containing structure data as well as actual records. Super weird. Will follow with a bug report.
Author
Owner

@JohnEstropia commented on GitHub (Mar 18, 2022):

Oh my, that's even worse. I'll try to explain that situation in the CoreStore README for future migrators. Thanks for investigating the behavior further

@JohnEstropia commented on GitHub (Mar 18, 2022): Oh my, that's even worse. I'll try to explain that situation in the CoreStore README for future migrators. Thanks for investigating the behavior further
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/CoreStore#383