我没有从我给Simperium的NSManagedObjectContext获取NSManagedObjectContextDidSaveNotification通知。
基本上我喜欢做的是在由于更新simperium而发生数据库更新时通知我的应用程序。
因此我使用2个NSManagedObjectContexts,一个用于我的应用程序,另一个用于Simperium。一旦我的应用程序保存其上下文,更改将通过mergeChangesFromContextDidSaveNotification:
合并到NSManagedObjectContextDidSaveNotification通知中的simperium上下文。
然而问题是,只要有Simperium NSManagedObjectContext的更新,我就不会得到NSManagedObjectContextDidSaveNotification,因此我无法将更改从远程合并到我的应用程序上下文。我检查过它实际上是将数据保存到持久存储中。
一些代码:
- (void) setSyncingEnabled:(BOOL)syncingEnabled
{
if (syncingEnabled && !self.simperium)
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(syncingObjectContextDidSaveNotification:)
name:NSManagedObjectContextDidSaveNotification
object:self.syncingObjectContext];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(objectContextDidSaveNotification:)
name:NSManagedObjectContextDidSaveNotification
object:self.objectContext];
self.simperium = [[Simperium alloc] initWithRootViewController:App.delegate.window.rootViewController];
self.simperium.authenticationOptional = YES;
[self.simperium addDelegate:self];
[self.simperium startWithAppID:kSimperiumAppId
APIKey:kSimperiumAPIKey
model:self.objectModel
context:self.syncingObjectContext
coordinator:self.storeCoordinator];
}
else if (self.simperium) {
self.simperium = nil;
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextDidSaveNotification object:self.syncingObjectContext];
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextDidSaveNotification object:self.objectContext];
}
}
- (void) objectContextDidSaveNotification:(NSNotification*)notification
{
if (self.simperium) {
[self.syncingObjectContext mergeChangesFromContextDidSaveNotification:notification];
}
}
- (void) syncingObjectContextDidSaveNotification:(NSNotification*)notification
{
[self.objectContext mergeChangesFromContextDidSaveNotification:notification];
/* Inform Application */
[[NSNotificationCenter defaultCenter] postNotificationName:DatabaseDidUpdateExternallyNotification object:self];
}
答案 0 :(得分:1)
我深入挖掘并发现Simperium SDK没有使用您提供的对象上下文,而是另一个私有创建的对象上下文。这就是为什么你给它的上下文永远不会被保存的原因。目前没有公共API可以访问私有并发上下文。
如果您不想使用NSFetchedResultsController,因为您同步了很多对象并且性能不是很好,您还可以在更新对象后处理一个通知,以处理更新UI。
以下代码似乎有用(主分支):
-(void)objectKeysChanged:(NSSet *)keyArray entityName:(NSString *)entityName
{
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(informAppAboutExternalChange) object:nil];
[self performSelector:@selector(informAppAboutExternalChange) withObject:nil afterDelay:0.5];
}
- (void) informAppAboutExternalChange
{
[[NSNotificationCenter defaultCenter] postNotificationName:kObjectsDidChangeExternallyNotification object:nil];
}
只需在需要更新UI的地方观察通知即可。延迟执行还应该防止过于频繁地触发通知,这也会降低性能。
答案 1 :(得分:0)
由于您的目标是在通过Simperium发生更新时通知您的应用,因此有更好的选择,而不是使用单独的上下文(无论如何Simperium在内部执行):
1)您可以使用NSFetchedResultsController
,当插入,更改和删除对象时,将调用SimperiumDelegate
。
2)您可以使用SimperiumDelegate
对特定更改做出反应。这在当前正在GitHub上的“iosupdate”分支中测试的版本中有所不同。 SPBucketDelegate
协议将替换为{{1}},以便您更好地控制您关注的通知。
如果由于某种原因你确实需要使用第二个上下文,请get in touch,以便我们再谈谈你的用例。