如何序列化 NSPredicate 对象?

Posted

技术标签:

【中文标题】如何序列化 NSPredicate 对象?【英文标题】:How to serialize a NSPredicate object? 【发布时间】:2010-11-07 20:52:44 【问题描述】:

有没有办法检查 NSPredicate 对象以将其序列化为 URL?我正在尝试远程检索数据,并且需要将谓词对象转换为带有服务器可以理解的查询字符串参数的 URL。

这受到了 WWDC 2010 上一场名为“构建服务器驱动的用户体验”的演讲的启发,演讲者在演讲中谈到了使用 Core-Data 和服务器后端。我已经关注了会议视频和幻灯片,但被困在序列化点上。例如,有一个Person 对象,我试图获取所有名字为“John”的人。我正在使用NSManagedObjectContext 的子类RemoteManagedObjectContext,它覆盖executeFetchRequest 方法,并且应该将调用发送到服务器。提取请求被创建为(省略的非必要部分):

@implementation PeopleViewController

- (NSArray *)getPeople 
    RemoteFetchRequest *fetchRequest = [[RemoteFetchRequest alloc] init];
    NSEntityDescription *entity = ...
    NSPredicate *template = [NSPredicate predicateWithFormat:
                                @"name == $NAME AND endpoint = $ENDPOINT"];
    NSPredicate *predicate = [template predicateWithSubstitutionVariables:...];

    [fetchRequest setEntity:entity];
    [fetchRequest setPredicate:predicate];

    NSError *error = nil;
    // the custom subclass of NSManagedObjectContext executes this
    return [remoteMOC executeFetchRequest:fetchRequest error:&error];


@end

现在在NSManagedObjectContext 的自定义子类中,如何将获取请求序列化为适合服务器的查询字符串参数。所以给定上面的 fetch 请求,对应的 URL 是:

http://example.com/people?name=John

可以获得返回的谓词的字符串表示,

name == "John" AND endpoint == "people"

我可以解析得到参数nameendpoint。但是,是否可以在不解析字符串的情况下做到这一点?这是RemoteManagedObjectContext 类的部分实现。

@implementation RemoteManagedObjectContext

- (NSArray *)executeFetchRequest:(NSFetchRequest *)request error:(NSError **)error 
    // this gives name == "John" AND endpoint == "people"
    // don't know how else to retrieve the predicate data
    NSLog(@"%@", [[request predicate] predicateFormat]);

    ...


@end

【问题讨论】:

【参考方案1】:

甚至比字符串表示更好的是面向对象的表示!而且它是自动完成的!

首先,检查NSPredicate 的类。它将是NSCompoundPredicate。将其转换为适当的变量。

然后您会看到 compoundPredicateTypeNSAndPredicateType,正如您所期望的那样。

你还可以看到-subpredicates返回的数组揭示了2个NSComparisonPredicates

第一个子谓词有一个NSKeyPathExpressionType 类型的左表达式和一个@"name"-keyPath,运算符是NSEqualToPredicateOperatorType。正确的表达式将是 NSConstantValueExpressionType 类型的 NSExpression-constantValue 将是 @"John"

第二个子谓词类似,除了左侧表达式的keyPath 将是@"endpoint",右侧表达式的constantValue 将是@"people"

如果您想更深入地了解如何将 NSPredicates 转换为 HTTP Get 请求,请查看我的 *** framework, "StackKit",它就是这样做的。它基本上是一个行为类似于 CoreData 的框架,但使用 ***.com(或任何其他堆栈交换站点)来检索信息。在下面,它正在做 lotNSPredicate 对象转换为 URL。如果您有任何具体问题,也欢迎您给我发电子邮件。

【讨论】:

以上是关于如何序列化 NSPredicate 对象?的主要内容,如果未能解决你的问题,请参考以下文章

NSPredicate 匹配除数字之外的任何内容

一对多关系 iPhone - NSPredicate 核心数据查询

NSPredicate 和 BEGINSWITH with CloudKit:字段值类型不匹配

如何通过 NSPredicate 过滤 Core Data 托管对象?

如何使用 NSPredicate 捕获子对象?

如何在 NSPredicate 的帮助下使用自定义对象数组实现搜索?