如何在Core Data中进行自定义验证(为了唯一性)?

时间:2012-01-17 07:38:32

标签: ios validation core-data

我在Core Data中有一个实体,它有一个需要唯一的属性。没有办法在可视化界面中设置它。我假设我需要创建一个继承自NSManagedObject的自定义类,然后编写自己的验证方法。

我通过在可视化编辑器中选择实体并选择文件 - >成功创建了自定义类。新 - >新文件 - > NSManagedObject子类。我用它来添加创建时间戳,所以我知道它有效。

但现在呢?我需要哪种方法?

NSManagedObject reference guide告诉我“实现表单validate:error:”的方法,但没有提供示例。

类似问题herehere,但我需要更多帮助。

一个完整的例子很棒,但是非常感谢任何帮助。

3 个答案:

答案 0 :(得分:6)

我们假设您有一个要验证的属性foo

来自Property-Level Validation

  

如果除了在托管对象模型中提供的约束之外还要实现逻辑,则不应覆盖validateValue:forKey:error:。相反,您应该实现validate<Key>:error:形式的方法。

<Key>是您的财产。你实际上会实现类似的东西:

-(BOOL)validateFoo:(id *)ioValue error:(NSError **)outError {
    return [self isUnique];
}

答案 1 :(得分:1)

虽然在批量插入上速度很慢,但您仍然需要创建一个NSError对象,这样做很有把握。

-(BOOL)validateValue:(__autoreleasing id *)value forKey:(NSString *)key error:(NSError *__autoreleasing *)error {
    [super validateValue:value forKey:key error:error];

    // Validate uniqueness of my_unique_id
    if([key isEqualToString:@"my_unique_id"]) {
        NSFetchRequest * fetch = [[NSFetchRequest alloc] init];
        [fetch setEntity:[NSEntityDescription entityForName:[self.entity name]
               inManagedObjectContext:self.managedObjectContext]];

        NSPredicate *predicate = [NSPredicate 
            predicateWithFormat:@"my_unique_id = %@",[self valueForKey:key]];

        fetch.predicate = predicate;

        NSError *error = nil;
        NSUInteger count = [self.managedObjectContext 
                           countForFetchRequest:fetch error:&error];

        if (count > 1) {
            // Produce error message...

            // Failed validation:
            return NO;
        }


    }

    return YES;
}

答案 2 :(得分:1)

下面提到的

validateValue将执行验证技巧(以及进行验证的正确位置)

但是,如果使用NSFetchedResultsController,请不要忘记从内存中删除对象,以避免UITableView中的重复对象出现故障。 像这样:

CustomManagedObject *obj = [NSEntityDescription insertNewObjectForEntityForName:@"<YourEntity>" inManagedObjectContext:self.managedObjectContext];
obj.property = @"some property";

if (![self.managedObjectContext save:&error]) {
   [self.managedObjectContext deleteObject:obj]; // delete from memory. Otherwise, you get duplicated value in UITableView even if save has failed
}