NSPredicate嵌套字典动态密钥

时间:2015-04-15 09:52:06

标签: ios objective-c core-data nsdictionary nspredicate

我正在使用核心数据来获取对象列表。这些对象具有名为“categories”的属性。这个categories属性是一个由json构建的NSDictionary,如:

@{@"A":@YES, @"B":@NO, @"C":@YES}

我想获取所有核心数据对象,对于给定的类别键,哪个类别为true。 我试过了:

NSString *categoryKey = @"A";
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"categories.%K == YES", categoryKey]];
// or
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF.categories.%@ == YES", categoryKey]];
// or
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"categories[%@] == YES", categoryKey];
// Throws exception : Unsupported function expression categories["A"]
// or
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"categories[%K] == YES", categoryKey];
// Throws exception : Unsupported function expression categories[A]
// or
NSString *categoryKeyPath = [NSString stringWithFormat:@"categories.%@", categoryKey];
NSPredicate *p = [NSPredicate predicateWithFormat:@"%K == YES", categoryKeyPath]];

但是在执行我的提取时它总是返回空数组(当然我有一些categories[@"A"] = YES的对象)。 我认为问题来自嵌套字典键路径,但我找不到用一个谓词来实现这个目的的方法。

修改

澄清我会用

NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
    return [[evaluatedObject.categories objectForKey:categoryKey] boolValue];
}];

但在获取核心数据时不支持predicateWithBlock:

2 个答案:

答案 0 :(得分:1)

如果我理解正确categories是您实体的字符串属性,其中包含JSON数据,并且您的托管对象会解析此JSON,以便将其作为字典读取。

问题是在执行提取之前不会创建托管对象。此时,categories只是一个字符串,没有关键路径可以从中提取您想要的信息。您将需要获取所有对象,以便他们可以构建其字典,然后过滤该集合。对于大型数据集,这可能会很慢。

核心数据旨在通过显式建模数据来使用;如果您在字符串中插入自己的数据结构,Core Data无法帮助您。更惯用的设计是使Categories实体与对象的实体具有to-many / to-many关系。这使得通过获取类别A然后遵循关系来查找类别A中的所有对象变得微不足道。

答案 1 :(得分:0)

试试这个

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF.categories LIKE \"%@\":true", categoryKey]];