Restkit键值验证 - 仅在对象较新时保存

时间:2014-06-03 08:58:52

标签: ios objective-c restkit

我们有一个应用程序正在使用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

在映射期间,验证逻辑似乎会被调用四次。

1 个答案:

答案 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;
    }
}