在今天的分机中创建记录并在应用程序中更新时的更改在今天的分机中不可见

时间:2017-01-05 19:49:41

标签: ios swift core-data magicalrecord

我只有一个应用程序,今天扩展。此外,我还有两个实体:目标服务

@objc(Goal)
class Goal: NSManagedObject {

    @NSManaged var identifier: String
    @NSManaged var startDate: Date
    @NSManaged var endDate: Date

    private var services: [Service] {

        let predicate = NSPredicate(format: "date >= %@ && date <= %@", startDate as NSDate, endDate as NSDate)

        return Service.mr_findAll(with: predicate) as! [Service]
    }

    var duration: Int64 {
        return services.reduce(0) { $0 + $1.duration }
    }
}

当我在今天的扩展程序中创建与service相关的goal并在应用内更新时,更新的结果在今天的扩展程序中不可见,同时在应用中正确显示。为什么呢?

这是我在扩展程序或扩展程序中创建和更新记录的方式:

MagicalRecord.save({ context in

    Service.createOrUpdate(withDuration: duration, date: Date(), identifier: identifier, in: context)

}, completion: { _, error in

        //do sth on completion
})

2 个答案:

答案 0 :(得分:4)

扩展程序和应用程序是共享一些相同代码的不同程序。所以两者都在创建自己的 persistentStoreCoordinator和context(s)。

通常在同一个应用程序中,您将有多个上下文全部附加到同一个persistentStoreCoordinator,其中一个中的更改将由通过notificationCenter发送然后合并的通知处理。在这种情况下,有两个问题 - 1)应用程序和扩展程序之间不共享notificationCenter,因此无法轻松进行通信; 2)上下文不共享persistentStoreCoordinator,因此您可以&即使您确实传递了这些信息,也要使用&#39; mergeChangesFromContextDidSaveNotification`。

我以前没有尝试过这个,但这是我会尝试的:

  1. 设置某种方式来触发发生更改。有很多解决方案。
  2. 设置managedObjectContext(s)以stalenessInterval为0
  3. 当有更改时,您必须更新核心数据。您可以通过在所有核心数据对象上调用refreshObject:mergeChanges:来执行此操作,或者执行另一次获取操作。诀窍是你必须从商店和商店获取上下文来从文件中获取,而不是点击中间的任何缓存。

答案 1 :(得分:1)

基于@JonRose回答我的问题的最终解决方案是:

获取我感兴趣的记录,在在我从获取的相同上下文中刷新它们,然后再次获取它们:

private var services: [Service] {

    let predicate = NSPredicate(format: "date >= %@ && date <= %@", startDate as NSDate, endDate as NSDate)

    for service in Service.mr_findAll(with: predicate, in: NSManagedObjectContext.mr_rootSaving())! {
        NSManagedObjectContext.mr_rootSaving().refresh(service, mergeChanges: false)
    }

    return Service.mr_findAll(with: predicate) as! [Service]
}