CoreStore如何观察数据库中的变化

时间:2019-08-09 11:24:12

标签: ios swift core-data corestore

导入后,我需要观察Entity的变化。

目前我有下一个逻辑:

  1. 将带有临时标识符(Entity)的NSManagedObject.objectId保存到本地核心数据存储中。
  2. 通过Entity Alamofire请求将POST发送到服务器。
  3. 服务器生成JSON,并使用几乎相同的实体详细信息进行回复,但具有先前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) 
        }

    }

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

1 个答案:

答案 0 :(得分:0)

如果我错了,请纠正我:

据我了解,每次核心数据使用新更改进行更新时,监视器也将进行更新。我还没有通过一些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")
    )

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

感谢@MartinM的建议!