Ios 此代码如何仅使用核心数据的更新?
这是RW教程中的SyncEngine。我需要帮助了解如何仅从web获取更新的记录并将其处理为核心数据Ios 此代码如何仅使用核心数据的更新?,ios,core-data,Ios,Core Data,这是RW教程中的SyncEngine。我需要帮助了解如何仅从web获取更新的记录并将其处理为核心数据 - (void)processJSONDataRecordsIntoCoreData { NSManagedObjectContext *managedObjectContext = [[SDCoreDataController sharedInstance] backgroundManagedObjectContext]; // Iterate over all registe
- (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];
}
这将获取所有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]>currentIndex的下一位比较混乱。有人能解释一下吗?我认为我的困惑在于managedObjectsForClass方法如何使用ArraySofids和inArrayOfIds
我希望在某个时刻,它从下载的记录中获取updatedAt字段,并将其与CoreData获取的记录的updatedAt字段进行比较。此函数正在处理存储的JSON。实际的远程获取和更新检查发生在
downloadDataForRegisteredObjects
和mostrecentupdatedatedateforentitywithname
中
[storedRecords count]>currentIndex
有点疯狂。尽管是为了保护原程序员,但编写任何像样的同步引擎都会让你很快变得棒极了。基本上,他需要找出哪些记录是存在的,哪些是新的,并相应地更新本地数据存储,仅此而已
我又看了一眼,这个代码实际上坏得很厉害。只有在本地和远程都有相同记录的情况下,它才会起作用。或者,如果新对象的objectId排序方式在本地存储的最后一个对象之后。这与Parse objectId的情况不同
如果您只使用一台设备进行测试,这是有效的,因为新对象将在推送到服务器之前在本地插入。因此,您将始终拥有相同数量的记录。如果以任何其他方式插入其他记录,此代码将执行奇怪的操作。这正是我想了解其工作原理的原因,即“确定哪些记录存在,哪些记录是新的”。相信我,我一直在努力理解这段代码,我很欣赏它的复杂性!:)。你能解释一下现有的和新的是如何工作的吗?
- (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;
}