CoreStore object data are not being stored correctly... #369

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

Originally created by @bradleydworak on GitHub (Jul 12, 2021).

Hi,

I'm new to CoreStore and attempting to test my ability to create, store, and fetch CoreStore Objects correctly. It appears entries are being created based on results of dataStack.fetchCount() and transaction.create(), but the data is unavailable or not stored correctly based on my results of dataStack.fetchAll() (it says data: at the end of each object) and inspection of the SQLite database with Liya software reveals no entries in the table. My example code is as follows:

MyImage.swift:

import CoreStore
final class MyImage: CoreStoreObject {
    @Field.Stored("desc")
    var desc: String = ""
}

ContentView.swift:

struct ContentView: View {
let dataStack: DataStack = {
        let dataStack = DataStack(
            CoreStoreSchema(
                modelVersion: "V1",
                entities: [
                    Entity<MyImage>("MyImage")
                ],
                versionLock: [
                    "MyImage": [...,...,...,...]
                ]
            )
        )
        let migrationProgress = dataStack.addStorage(
            SQLiteStore(
                fileName: "MyStore.sqlite"
            ),
            completion: { (result) -> Void in
                switch result {
                case .success(let storage):
                    print("Successfully added sqlite store: \(storage)")
                case .failure(let error):
                    print("Failed adding sqlite store with error: \(error)")
                }
            }
        )
        CoreStoreDefaults.dataStack = dataStack
        return dataStack
    }()

Button(action: {
dataStack.perform(
     asynchronous: { (transaction) -> Void in
     let test  = transaction.create(Into<MyImage>())
     test.desc = "John Smith"
     },
     completion: { (result) -> Void in
          switch result {
               case .success:
                    print("success!")
               case .failure(let error): print(error)
          }
   }
)
}

I appreciate your help. Thanks, Brad

Originally created by @bradleydworak on GitHub (Jul 12, 2021). Hi, I'm new to CoreStore and attempting to test my ability to create, store, and fetch CoreStore Objects correctly. It appears entries are being created based on results of dataStack.fetchCount() and transaction.create(), but the data is unavailable or not stored correctly based on my results of dataStack.fetchAll() (it says data: <fault> at the end of each object) and inspection of the SQLite database with Liya software reveals no entries in the table. My example code is as follows: _MyImage.swift:_ ```swift import CoreStore final class MyImage: CoreStoreObject { @Field.Stored("desc") var desc: String = "" } ``` _ContentView.swift:_ ```swift struct ContentView: View { let dataStack: DataStack = { let dataStack = DataStack( CoreStoreSchema( modelVersion: "V1", entities: [ Entity<MyImage>("MyImage") ], versionLock: [ "MyImage": [...,...,...,...] ] ) ) let migrationProgress = dataStack.addStorage( SQLiteStore( fileName: "MyStore.sqlite" ), completion: { (result) -> Void in switch result { case .success(let storage): print("Successfully added sqlite store: \(storage)") case .failure(let error): print("Failed adding sqlite store with error: \(error)") } } ) CoreStoreDefaults.dataStack = dataStack return dataStack }() Button(action: { dataStack.perform( asynchronous: { (transaction) -> Void in let test = transaction.create(Into<MyImage>()) test.desc = "John Smith" }, completion: { (result) -> Void in switch result { case .success: print("success!") case .failure(let error): print(error) } } ) } ``` I appreciate your help. Thanks, Brad
adam closed this issue 2025-12-29 15:30:11 +01:00
Author
Owner

@JohnEstropia commented on GitHub (Jul 13, 2021):

@bradleydworak You are accessing dataStack.perform(...) before your dataStack.addStorage(...) has completed. You will need to handle this timing by yourself (ex: Create ContentView only after the completed: closure has executed)

@JohnEstropia commented on GitHub (Jul 13, 2021): @bradleydworak You are accessing `dataStack.perform(...)` before your `dataStack.addStorage(...)` has completed. You will need to handle this timing by yourself (ex: Create `ContentView` only after the `completed:` closure has executed)
Author
Owner

@bradleydworak commented on GitHub (Jul 14, 2021):

Thanks @JohnEstropia for your guidance. I order to ensure dataStack.addStorage(...) has completed before the ContentView() has been created, my strategy is to move the let dataStack: DataStack = {...}() code into the Swift file containing @main preceding ContentView(). If this makes sense, then what additional code needs to placed here in order to call dataStack.addStorage(...) first? My example code is as follows:

MyApp.swift

import CoreStore
import Foundation

@main
struct MyApp: App {

let dataStack: DataStack = {
        let dataStack = DataStack(
            CoreStoreSchema(
                modelVersion: "V1",
                entities: [
                    Entity<MyImage>("MyImage")
                ],
                versionLock: [
                    "MyImage": [...,...,...,...]
                ]
            )
        )
        let migrationProgress = dataStack.addStorage(
            SQLiteStore(
                fileName: "MyStore.sqlite"
            ),
            completion: { (result) -> Void in
                switch result {
                case .success(let storage):
                    print("Successfully added sqlite store: \(storage)")
                case .failure(let error):
                    print("Failed adding sqlite store with error: \(error)")
                }
            }
        )
        CoreStoreDefaults.dataStack = dataStack
        return dataStack
    }() 

var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

I appreciate your help. Thanks again, Brad

@bradleydworak commented on GitHub (Jul 14, 2021): Thanks @JohnEstropia for your guidance. I order to ensure ```dataStack.addStorage(...)``` has completed before the ```ContentView()``` has been created, my strategy is to move the ```let dataStack: DataStack = {...}()``` code into the Swift file containing @main preceding ```ContentView()```. If this makes sense, then what additional code needs to placed here in order to call ```dataStack.addStorage(...)``` first? My example code is as follows: _MyApp.swift_ ``` import CoreStore import Foundation @main struct MyApp: App { let dataStack: DataStack = { let dataStack = DataStack( CoreStoreSchema( modelVersion: "V1", entities: [ Entity<MyImage>("MyImage") ], versionLock: [ "MyImage": [...,...,...,...] ] ) ) let migrationProgress = dataStack.addStorage( SQLiteStore( fileName: "MyStore.sqlite" ), completion: { (result) -> Void in switch result { case .success(let storage): print("Successfully added sqlite store: \(storage)") case .failure(let error): print("Failed adding sqlite store with error: \(error)") } } ) CoreStoreDefaults.dataStack = dataStack return dataStack }() var body: some Scene { WindowGroup { ContentView() } } } ``` I appreciate your help. Thanks again, Brad
Author
Owner

@bradleydworak commented on GitHub (Jul 20, 2021):

Hi @JohnEstropia, I modified my example code as a sanity check to ensure I can add the storage, create a object, and fetch objects synchronously in the init() section before I call ContentView(). I'm still getting the same error in which I notice the words data: fault for each of the entities listed from fetchAll(), as well as no objects appear upon inspection of the database. I appreciate any information as to how I can troubleshoot this. My example code is as follows:

MyApp.swift

import CoreStore
import Foundation

@main
struct MyApp: App {

        let dataStack = DataStack(
            CoreStoreSchema(
                modelVersion: "V1",
                entities: [
                    Entity<MyImage>("MyImage")
                ],
                versionLock: [
                    "MyImage": [...,...,...,...]
                ]
            )
        )

        init() {
        print("At start of init")
        do {
            try dataStack.addStorageAndWait(
                SQLiteStore( fileName: "MyStore.sqlite",
                    localStorageOptions: .recreateStoreOnModelMismatch
                )
            )
            CoreStoreDefaults.dataStack = dataStack // pass the dataStack to CoreStore for easier access later on
            
        } catch { print("error adding storage") }
        print("after add storage")
        print(dataStack.coreStoreDumpString)
        try! dataStack.perform(
            synchronous: { (transaction) in
                let test = transaction.create(Into<MyImage>())
                test.desc = "Description"
            },
            waitForAllObservers: false
        )
        print("after add person")
        do {
            let objects = try dataStack.fetchAll(From<MyImage>())
            print(objects)
        } catch { print("error fetching")}
        
    }

var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

I appreciate your help. Thanks again, Brad

@bradleydworak commented on GitHub (Jul 20, 2021): Hi @JohnEstropia, I modified my example code as a sanity check to ensure I can add the storage, create a object, and fetch objects synchronously in the ```init()``` section before I call ```ContentView()```. I'm still getting the same error in which I notice the words _data: fault_ for each of the entities listed from ```fetchAll()```, as well as no objects appear upon inspection of the database. I appreciate any information as to how I can troubleshoot this. My example code is as follows: _MyApp.swift_ ```swift import CoreStore import Foundation @main struct MyApp: App { let dataStack = DataStack( CoreStoreSchema( modelVersion: "V1", entities: [ Entity<MyImage>("MyImage") ], versionLock: [ "MyImage": [...,...,...,...] ] ) ) init() { print("At start of init") do { try dataStack.addStorageAndWait( SQLiteStore( fileName: "MyStore.sqlite", localStorageOptions: .recreateStoreOnModelMismatch ) ) CoreStoreDefaults.dataStack = dataStack // pass the dataStack to CoreStore for easier access later on } catch { print("error adding storage") } print("after add storage") print(dataStack.coreStoreDumpString) try! dataStack.perform( synchronous: { (transaction) in let test = transaction.create(Into<MyImage>()) test.desc = "Description" }, waitForAllObservers: false ) print("after add person") do { let objects = try dataStack.fetchAll(From<MyImage>()) print(objects) } catch { print("error fetching")} } var body: some Scene { WindowGroup { ContentView() } } } ``` I appreciate your help. Thanks again, Brad
Author
Owner

@bradleydworak commented on GitHub (Jul 21, 2021):

I posted the issue on Stack Overflow as well:
https://stackoverflow.com/questions/68463258/corestore-xcode-data-fault-issue-when-fetching-objects

@bradleydworak commented on GitHub (Jul 21, 2021): I posted the issue on Stack Overflow as well: https://stackoverflow.com/questions/68463258/corestore-xcode-data-fault-issue-when-fetching-objects
Author
Owner

@JohnEstropia commented on GitHub (Jul 21, 2021):

@bradleydworak

fault for each of the entities listed from fetchAll()

These are your objects. print() will only show fault for each object until you access any of their properties. Try

            let objects = try dataStack.fetchAll(From<MyImage>())
            print(objects.map { $0.desc })

no objects appear upon inspection of the database

I'm not sure how you inspect your DB, but if dataStack.fetchAll() returns the correct count of objects, that means the data do exist in the database. It's possible there are sync timing issues in the DB introspection method you use.

@JohnEstropia commented on GitHub (Jul 21, 2021): @bradleydworak > fault for each of the entities listed from fetchAll() These are your objects. `print()` will only show `fault` for each object until you access any of their properties. Try ```swift let objects = try dataStack.fetchAll(From<MyImage>()) print(objects.map { $0.desc }) ``` > no objects appear upon inspection of the database I'm not sure how you inspect your DB, but if `dataStack.fetchAll()` returns the correct `count` of objects, that means the data do exist in the database. It's possible there are sync timing issues in the DB introspection method you use.
Author
Owner

@bradleydworak commented on GitHub (Jul 21, 2021):

Thanks @JohnEstropia for your input, much appreciated. print(objects.map {$0.desc}) indeed displays the value of the property for all entries. I use Liya software to inspect the SQLite database. It also is working now as the updates are displayed immediately after re-querying the database.

@bradleydworak commented on GitHub (Jul 21, 2021): Thanks @JohnEstropia for your input, much appreciated. ```print(objects.map {$0.desc})``` indeed displays the value of the property for all entries. I use Liya software to inspect the SQLite database. It also is working now as the updates are displayed immediately after re-querying the database.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/CoreStore#369