繁体   English   中英

CoreStore如何观察数据库中的更改

[英]CoreStore how to observe changes in database

导入后,我需要观察Entity更改。

目前,我有下一个逻辑:

  1. 将具有临时标识符( NSManagedObject.objectId )的Entity保存到本地核心数据存储中。
  2. 通过Alamofire POST请求将Entity发送到服务器。
  3. Server生成JSON并使用几乎相同的Entity细节进行回复,但具有先前已修改的标识符NSManagedObject.objectId 因此,本地一个实体ID将使用服务器ID更新。
  4. 现在,当我收到新的JSON时,我执行transaction.importUniqueObjects

在这一步,我想通知我的数据源有关更改的信息。 并使用更新的标识符重新获取数据。

因此,我的DataSource在一个数组中有一些Entities ,虽然我使用此数据源显示数据,但它仍然是我之前获取的那个数组中的静态信息,但是正如您在步骤4上看到的那样,我已经通过CoreStore导入和更新了核心数据存储希望DataSource的数组也被更新。

我在CoreStore中找到了有关ListMonitor的一些信息,并尝试使用它。 如我所见,当更新到来时,此方法有效

func listMonitorDidChange(_ monitor:ListMonitor)

但我尝试以某种方式重新获取数据。 监视器似乎已经包含一些最新信息。

但是当我这样做时:

func listMonitorDidChange(_ monitor: ListMonitor<MyEntity>) {

    let entities = try? CoreStore.fetchAll(
                From<MyEntity>()
                    .orderBy(.ascending(\.name))
            ) // THERE IS STILL old information in database, but monitor instance shows new info.
    }

然后代码变成这样:

func listMonitorDidChange(_ monitor: ListMonitor<MyEntity>) {

        var myEntitiesFromMonitor = [MyEntity]()

        for index in 0...monitor.numberOfObjects() {
            myEntitiesFromMonitor.append(monitor[index])
        }

        if myEntitiesFromMonitor.count > 0 {
            // HERE we update DataSource
            updateData(with: myEntitiesFromMonitor) 
        }

    }

不确定我的方法是否正确。

如果我错了,请纠正我:

据我了解,每次使用新更改更新核心数据时,监视器也会更新。 我还没有通过一些CoreData上下文通知或其他方式深入了解它是如何实现的,但是在您通过CoreStore事务执行了某些操作(例如创建或更新或删除对象或您想要的任何对象)之后,监视器将得到更新。 它还具有您需要在您的类中实现的回调函数,您想在该类中观察数据模型的任何变化:

您的类(例如数据源,某些服务或什至某些视图控制器(如果您不使用任何MVVP或VIPER或其他设计模式))需要符合ListObserver协议,以防您不想只听一个对象。

这是这些功能:

    func listMonitorDidChange(monitor: ListMonitor<MyPersonEntity>) {
        // Here I reload my tableview and this monitor already has all needed info about sections and rows depend how you setup monitor.
        // So you classVariableMonitor which I provide below already has up to date state after any changes with data.
    }



    func listMonitorDidRefetch(monitor: ListMonitor<MyPersonEntity>) {
        // Not sure for which purposes it. I have not received this call yet
    }



typealias ListEntityType = ExerciseEntity

let classVariableMonitor = CoreStore.monitorSectionedList(
    From<ListEntityType>()
    .sectionBy(#keyPath(ListEntityType.muscle.name)) { (sectionName) -> String? in
        "\(String(describing: sectionName)) years old"
    }
        .orderBy(.ascending(\.name))
        .where(
            format: "%K == %@",
            #keyPath(ListEntityType.name),
            "Search string")
    )

此处记录所有其他内容因此您可以在tableview数据源功能中找到如何从监视器提取信息的信息。

感谢@MartinM的建议!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM