这是来自RW教程的SyncEngine。我需要帮助了解如何只获取Web上的UPDATED记录并将其处理为Core Data。
- (void)processJSONDataRecordsIntoCoreData {
NSManagedObjectContext *managedObjectContext = [[SDCoreDataController sharedInstance] backgroundManagedObjectContext];
// Iterate over all registered classes --- CHECK!
for (NSString *className in self.registeredClassesToSync) {
if (![self initialSyncComplete]) {
NSDictionary *JSONDictionary = [self JSONDictionaryForClassWithName:className];
NSArray *records = [JSONDictionary objectForKey:@"results"];
for (NSDictionary *record in records) {
[self newManagedObjectWithClassName:className forRecord:record];
}
} else {
NSArray *downloadedRecords = [self JSONDataRecordsForClass:className sortedByKey:@"objectId"];
if ([downloadedRecords lastObject]) {
NSArray *storedRecords = [self managedObjectsForClass:className sortedByKey:@"objectId" usingArrayOfIds:[downloadedRecords valueForKey:@"objectId"] inArrayOfIds:YES];
int currentIndex = 0;
//if dl count is < current index, there is an updated object dl from the web
for (NSDictionary *record in downloadedRecords) {
NSManagedObject *storedManagedObject = nil;
//Quick check to see if they indeed match, if they do, update the stored object with remote service objects
if ([storedRecords count] > currentIndex) {
storedManagedObject = [storedRecords objectAtIndex:currentIndex];
}
//Othwerwise its a new object and you need to create a new NSManagedObject to represent it in CDdb
if ([[storedManagedObject valueForKey:@"objectId"] isEqualToString:[record valueForKey:@"objectId"]]) {
[self updateManagedObject:[storedRecords objectAtIndex:currentIndex] withRecord:record];
} else {
[self newManagedObjectWithClassName:className forRecord:record];
}
currentIndex++;
}
}
}
// After all NSMO are created in your context, save it!
[managedObjectContext performBlockAndWait:^{
NSError *error = nil;
if (![managedObjectContext save:&error]) {
NSLog(@"Unable to save context for class %@", className);
}
}];
// Cleanup time
[self deleteJSONDataRecordsForClassWithName:className];
[self executeSyncCompletedOperations];
}
[self downloadDataForRegisteredObjects:NO];
}
根据我的理解,在第一次或初始同步时,它会获取JSONDictionaryForClassWithName,它从磁盘读取下载的数据并创建newManagedObjectWithClassName。
我的困惑在于更新else块。 downloadedRecords是从JSONDataRecordsForClass填充的,它只调用JSONDictionaryForClassWithName。然后它检查该数组中是否至少有一个对象。如果它有这样做:
NSArray *storedRecords = [self managedObjectsForClass:className sortedByKey:@"objectId" usingArrayOfIds:[downloadedRecords valueForKey:@"objectId"] inArrayOfIds:YES];
这将获取所有managedObjectsForClass:sortedByKey,它位于:
- (NSArray *)managedObjectsForClass:(NSString *)className sortedByKey:(NSString *)key usingArrayOfIds:(NSArray *)idArray inArrayOfIds:(BOOL)inIds {
__block NSArray *results = nil;
NSManagedObjectContext *managedObjectContext = [[SDCoreDataController sharedInstance] backgroundManagedObjectContext];
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:className];
NSPredicate *predicate;
if (inIds) {
predicate = [NSPredicate predicateWithFormat:@"objectId IN %@", idArray];
} else {
predicate = [NSPredicate predicateWithFormat:@"NOT (objectId IN %@)", idArray];
}
[fetchRequest setPredicate:predicate];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:
[NSSortDescriptor sortDescriptorWithKey:@"objectId" ascending:YES]]];
[managedObjectContext performBlockAndWait:^{
NSError *error = nil;
results = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
}];
return results;
}
比较[storedRecords count]&gt;的下一位currentIndex令人困惑。有人可以解释一下吗?我认为我的困惑在于managedObjectsForClass方法对usingArraysOfIds&amp; inArrayOfIds。
我希望在某些时候它从下载的记录中获取updatedAt字段,并将其与CoreData提取的记录的updatedAt字段进行比较。
答案 0 :(得分:0)
此函数正在处理存储的JSON。实际的远程提取和updateAt检查发生在downloadDataForRegisteredObjects
和mostRecentUpdatedAtDateForEntityWithName
。
[storedRecords count] > currentIndex
有点疯狂。虽然在为原始程序员辩护时,编写任何体面的syncengine都会很快让你去googoo。基本上,他需要确定哪些记录存在,哪些记录是新的,并相应地更新本地数据存储,这就是全部。
我又看了一眼,这段代码实际上非常糟糕。它只有在本地和远程具有相同记录时才有效。或者,如果新对象具有objectId,该对象在本地商店具有的最后一个对象之后排序。 Parse objectId的情况并非如此。
如果您只使用一个设备进行测试,则可以使用,因为在推送到服务器之前,新对象将在本地插入。因此,您将始终拥有相同数量的记录。如果以其他任何方式插入其他记录,此代码将做奇怪的事情。