我们有一个应用程序正在使用restkit与其他服务进行交互,并且它的工作性能很好。我们正在保存对核心数据的响应,一切正常。事实上,只要存在差异,服务器上的所有内容都会被拉下并保存。
但这并不完全是我们想要的。我们的架构上有一个updated_at字段,所以我们只希望restkit在服务器中的对象比设备更新时保存。如果设备较新,那么我们需要执行一些其他逻辑。我一直试图使用密钥值编码验证而没有运气。
有人可以解释为什么会发生以下情况吗?我用if语句挑出一个对象。此对象已更改值,并且更新的字段大于设备上的对象。
- (BOOL)validateUpdated_at:(NSDate **)ioValue error:(NSError **)outError {
if([self.uuid isEqualToString:@"4BE6FE9A-221C-41C7-A6C2-7669651ECD90"]){
NSLog(@"old date: %@, new date: %@", self.updated_at, *ioValue);
if([self.updated_at compare:*ioValue] == NSOrderedAscending){
// Local date is older so we must save
return YES;
}
else if ([self.updated_at compare:*ioValue] == NSOrderedDescending){
//Local date is newer so more logic
return NO;
}
else{
//Local date is same, do nothing
return NO;
}
}
return YES;
}
控制台输出是:
old date: 2014-05-30 14:29:46 +0000, new date: 2014-05-30 14:29:47 +0000
old date: 2014-05-30 14:29:46 +0000, new date: 2014-05-30 14:29:47 +0000
old date: 2014-05-30 14:29:47 +0000, new date: 2014-05-30 14:29:47 +0000
old date: 2014-05-30 14:29:47 +0000, new date: 2014-05-30 14:29:47 +0000
在映射期间,验证逻辑似乎会被调用四次。
答案 0 :(得分:0)
即使问题有点老,我也遇到了问题,最后找到了一个有效的解决方案。
// Request the objects from the server
[[RKObjectManager sharedManager] getObjectsAtPath:objectPath
parameters:nil
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
// Success handling
}
failure:^(RKObjectRequestOperation *operation, NSError *error) {
// Error handling
}];
每次Core Data更新NSManagedObject时都会调用validateForUpdate:
方法。通过调用super,我们确保验证所有其他属性(如果存在验证)并调用我们的自定义验证。
调用验证方法时,本地NSManagedObject已使用新值(!)进行更新。但是,您可以使用NSManagedObject上的[self committedValuesForKeys:]
访问最近的更改。
// YourNSManagedObject.m
- (BOOL)validateForUpdate:(NSError **)error
{
// Check if properties are valid in general by calling super
BOOL propertiesValid = [super validateForUpdate:error];
// Check if timestamp is valid and return result of validation
BOOL updatedAtTimestampValid = [self validateUpdatedTimestamp];
return (propertiesValid && updatedAtTimestampValid);
}
- (BOOL)validateUpdatedTimestamp
{
// Get value of the remote date (which is the updated local date timestamp)
NSDate *localDate = self.updatedAt;
// Get value of overwritten local date timestamp
NSDate *remoteDate = [self committedValuesForKeys:@[ @"updatedAt" ]]];
// Check if local date is newer than remote data
if ([[localDate laterDate:remoteDate] isEqualToDate:localDate])
{
// If local date is newer, revert changes, save the
// NSManagedObject and abort the validation
[self.managedObjectContext refreshObject:self mergeChanges:NO];
[self.managedObjectContext save:nil];
return NO;
}
}