How to link a Datastack to a monitor sectioned list. #107

Closed
opened 2025-12-29 15:24:44 +01:00 by adam · 5 comments
Owner

Originally created by @ghost on GitHub (Dec 1, 2016).

At first, I linked CoreStore to a monitored sectioned list the same way that the sample code did it. That worked perfectly. However, I' am now trying to link a DataStack to a monitor sectioned list and nothing is happening. Here is the code for the dataStack.

class ViewController: UIViewController, ListSectionObserver {

 let datastack: DataStack = {
    
    let dataStack = DataStack(modelName: "Model")
    try! dataStack.addStorageAndWait(
        SQLiteStore(
            fileName: "randomfile.sqlite",
            localStorageOptions: .recreateStoreOnModelMismatch
        )
    )

    return dataStack
}()

override func viewDidLoad() {
    super.viewDidLoad()
    
   
    
    let friends : ListMonitor<Person> = {
        
        return self.datastack.monitorSectionedList(
            
            From<Person>(),
            SectionBy(#keyPath(Person.id)),
            OrderBy(.ascending(#keyPath(Person.id)))
            
        )
        
    }()
    
    
    friends.addObserver(self)
    
    
    
    datastack.beginAsynchronous { (transaction) in
        

        let person = transaction.create(Into<Person>())
        person.id = ""
        transaction.commit()
        
    }
    
}

func listMonitorWillChange(_ monitor: ListMonitor<Person>) {
    
}

func listMonitorDidChange(_ monitor: ListMonitor<Person>) {
}

func listMonitor(_ monitor: ListMonitor<Person>, didInsertObject object: Person, toIndexPath indexPath: IndexPath) {
    
    print("made it here") //not triggered
    
}

func listMonitor(_ monitor: ListMonitor<Person>, didInsertSection sectionInfo: NSFetchedResultsSectionInfo, toSectionIndex sectionIndex: Int) {

print("made it here") //not triggered


}

}

The "made it here" do not triggered, however when I simply link/use CoreStore and not make my own dataStack, they do get triggered.

Originally created by @ghost on GitHub (Dec 1, 2016). At first, I linked `CoreStore` to a monitored sectioned list the same way that the sample code did it. That worked perfectly. However, I' am now trying to link a `DataStack` to a monitor sectioned list and nothing is happening. Here is the code for the dataStack. class ViewController: UIViewController, ListSectionObserver { let datastack: DataStack = { let dataStack = DataStack(modelName: "Model") try! dataStack.addStorageAndWait( SQLiteStore( fileName: "randomfile.sqlite", localStorageOptions: .recreateStoreOnModelMismatch ) ) return dataStack }() override func viewDidLoad() { super.viewDidLoad() let friends : ListMonitor<Person> = { return self.datastack.monitorSectionedList( From<Person>(), SectionBy(#keyPath(Person.id)), OrderBy(.ascending(#keyPath(Person.id))) ) }() friends.addObserver(self) datastack.beginAsynchronous { (transaction) in let person = transaction.create(Into<Person>()) person.id = "" transaction.commit() } } func listMonitorWillChange(_ monitor: ListMonitor<Person>) { } func listMonitorDidChange(_ monitor: ListMonitor<Person>) { } func listMonitor(_ monitor: ListMonitor<Person>, didInsertObject object: Person, toIndexPath indexPath: IndexPath) { print("made it here") //not triggered } func listMonitor(_ monitor: ListMonitor<Person>, didInsertSection sectionInfo: NSFetchedResultsSectionInfo, toSectionIndex sectionIndex: Int) { print("made it here") //not triggered } } The "made it here" do not triggered, however when I simply link/use CoreStore and not make my own dataStack, they do get triggered.
adam closed this issue 2025-12-29 15:24:44 +01:00
Author
Owner

@JohnEstropia commented on GitHub (Dec 2, 2016):

Hi, I think the problem is because you are assigning

let friends : ListMonitor<Person>

to a local function variable. So once viewDidLoad() exits, your ListMonitor gets deallocated.

Try to retain the monitor with a property and see how it goes.

@JohnEstropia commented on GitHub (Dec 2, 2016): Hi, I think the problem is because you are assigning ```swift let friends : ListMonitor<Person> ``` to a local function variable. So once `viewDidLoad()` exits, your `ListMonitor` gets deallocated. Try to retain the monitor with a property and see how it goes.
Author
Owner

@ghost commented on GitHub (Dec 3, 2016):

Hi John, I tried that. Unfortunately, it always crashes at this line
switch context.parentStack!.persistentStoreForEntityClass(
entityClass,
configuration: nil,
inferStoreIfPossible: true
) {

With the message , unexpectedly found nil while unwrapping an Optional value. So parent Context must be nil. I'am not too sure how to fix that!

@ghost commented on GitHub (Dec 3, 2016): Hi John, I tried that. Unfortunately, it always crashes at this line switch context.parentStack!.persistentStoreForEntityClass( entityClass, configuration: nil, inferStoreIfPossible: true ) { With the message , unexpectedly found nil while unwrapping an Optional value. So parent Context must be nil. I'am not too sure how to fix that!
Author
Owner

@ghost commented on GitHub (Dec 3, 2016):

I even changed the code to just save with a datastack instead of using the default core store and I still get the same crash. I only have one attribute in the entity message of type string, no relationships or anything (if that even matters)

class ViewController: UIViewController {

var dataStack: DataStack {

let dataStack = DataStack(modelName: "random")
try! dataStack.addStorageAndWait(SQLiteStore(fileName: "randomrandom.sqlite"))
return dataStack
    
}





override func viewDidLoad() {
    super.viewDidLoad()

       self.dataStack.beginAsynchronous { (transaction) in
        let a = transaction.create(Into<Message>())
        a.text = "fmerffmelemler"
        transaction.commit()   //it crashes here. 
    }
    
}
@ghost commented on GitHub (Dec 3, 2016): I even changed the code to just save with a datastack instead of using the default core store and I still get the same crash. I only have one attribute in the entity message of type string, no relationships or anything (if that even matters) class ViewController: UIViewController { var dataStack: DataStack { let dataStack = DataStack(modelName: "random") try! dataStack.addStorageAndWait(SQLiteStore(fileName: "randomrandom.sqlite")) return dataStack } override func viewDidLoad() { super.viewDidLoad() self.dataStack.beginAsynchronous { (transaction) in let a = transaction.create(Into<Message>()) a.text = "fmerffmelemler" transaction.commit() //it crashes here. } }
Author
Owner

@ghost commented on GitHub (Dec 3, 2016):

when I put it as a static let in a private struct as in the example, it finally worked

@ghost commented on GitHub (Dec 3, 2016): when I put it as a static let in a private struct as in the example, it finally worked
Author
Owner

@JohnEstropia commented on GitHub (Dec 6, 2016):

@rslim087g Sorry for the late reply. If making it static fixes it for you, then your dataStack was getting deallocated early. I'm not sure how your view controller is being used here, but you should make sure that dataStack lives for longer than you need to use the ListMonitor.
(It's perfectly fine to keep it in a static as you did though)

I'm closing this issue but feel free to ask anything else :)

@JohnEstropia commented on GitHub (Dec 6, 2016): @rslim087g Sorry for the late reply. If making it `static` fixes it for you, then your `dataStack` was getting deallocated early. I'm not sure how your view controller is being used here, but you should make sure that `dataStack` lives for longer than you need to use the `ListMonitor`. (It's perfectly fine to keep it in a `static` as you did though) I'm closing this issue but feel free to ask anything else :)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/CoreStore#107