2014-02-25 82 views
4

是否有任何解决方案获得整个Enity的最后修改日期?因为应用程序与Web服务同步(其中一些会在数据库中使用较早的日期),所以每个NSManagedObject的时间戳都不是一个好的解决方案。实体最后修改日期

每次用户决定更新列表时,我都需要为整个实体制作一个时间戳,以便我可以在SSPullToRefresh中提供此日期。

我的脑海里只有一个解决方案:NSUserDefaults但它是保持实体上次修改日期的好地方吗?

+0

你的意思是你想记录**任何**实体被修改时的最近日期? –

+0

@TomHarrington是的,确切的! – cojoj

+0

不知道这是否会解决您的需求,但您可以观察保存在managedObjectContext上并使用它记录上次保存的时间戳。为您的managedObjectContext交替集中保存方法,并且仅在hasChanges也为true时设置时间戳。 –

回答

1

我倾向于避免NSUserDefaults总是感觉像混合苹果和橘子。

当我需要存储这样的信息时,我喜欢把它放在NSPersistentStore本身的元数据中。这样它就会附加到我正在与Web服务同步的文件中。

NSPersistentStoreCoordinator上有方法允许您访问元数据并对其进行修改。然后,如果文件被移植到另一个设备(比如在还原或其他设备中),则元数据会随之一起移动。

+0

我真的很喜欢你的解决方案。它干净,光滑,“就像它应该的样子”。非常感谢! – cojoj

1

我过去为此使用的策略是查找实体类型的最近修改记录。

假设您有一个联系人实体,并且想要同步上次执行同步时发生的任何更改。查询您当地的所有联系人记录,并按lastModifiedDate降序排列。返回的第一个结果是查询Web服务时要使用的时间戳。

我写这篇教程的时候,How To Synchronize Core Data with a Web Service

最大的好处我有这个发现是,你不需要担心确保服务器时间同步了设备的本地时间使用这种策略。如果他们几分钟后关闭,你不会“错过”任何事情。

+0

但是这个解决方案有效吗?您必须获取所有内容并将其排序为几MB的RAM。 – cojoj

+0

这实际上取决于您的数据集,如果您发现提取速度太慢,您可能会在处理导入/同步时在其他位置始终保留该时间戳。 'NSUserDefaults'可能是一个很好的候选人。 –

2

这样做的一种方法是创建一个实体,其唯一目的是跟踪实体的修改。它可能看起来像:

LastModified: 
    date (NSDate*) 
    key (NSString*) 

你可以处理key属性作为实体名称

(如果需要的话),你可以在启动填充这些实体。
您也可以创建一个全局字典,在启动时将其key映射到objectID

你使用这个对象的方法是:
当您启动同步操作,你取应该更新的实体,并将其设置为当前的日期,如果你知道哪些实体将被更新(反映现实更好) 。

如果没有,你救你们过去的所有更新,插入,删除集环境中,让一组被改变了所有的实体类型和更新对应于那些键(实体名称)的LastModified对象。

这种方法的好处是:

  1. ,如果你确实设法提交/保存同步操作改变
  2. 你可以观察到这些对象的变化,您只更新“上次修改”日期使用KVO更新您的用户界面。
  3. 您不必经常询问店里的其它方法

缺点:

  1. 如果您CoreData实体彼此继承或者你有会影响相同不止一个实体key(并且您不知道哪些密钥会在同步中更新),维护起来会更加复杂(您可能希望使用实体userInfo字典来存储key,以便不同的实体可能会更新相同的修改日期)
1

您可以保持简单并使用NSUserDefaults。你可以添加一个观察者到NSManagedObjectContextWillSave通知。然后,使用ClassNSString名称创建/更新NSDate对象。我有这个在我的AppDelegate

在应用中:didFinishLaunchingWithOptions:

[[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(mocWillSave:) 
              name:NSManagedObjectContextWillSaveNotification 
              object:self.managedObjectContext]; 

选择

- (void)mocWillSave:(NSNotification*)note { 
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; 
    // Get array of classes that have been updated. 
    // This way, we don't loop through every updated Object...just the 
    // unique classes in the updatedObjects set. 
    NSArray *updatedObjectClasses = [self.managedObjectContext.updatedObjects valueForKeyPath:@"class"]; 

    for (id obj in updatedObjectClasses) { 
     [userDefaults setObject:[NSDate date] forKey:obj]; 
    } 

    [userDefaults synchronize]; 
} 

注:当然,这只是发生在占updatedObjects。你当然可以这样做insertedObjects