如何序列化 NSPredicate 对象?
有没有办法检查 NSPredicate 对象以将其序列化为 URL?我正在尝试远程检索数据,并且需要将谓词对象转换为带有服务器可以理解的查询字符串参数的 URL。
这是受到 WWDC 2010 上一次名为“构建服务器驱动的用户体验”的演讲的启发,其中演讲者谈论了使用 Core-Data 和服务器后端。我已关注会议视频和幻灯片,但仍停留在序列化点上。例如,有一个 Person
对象,我试图获取所有名字为“John”的人。我正在使用名为 RemoteManagedObjectContext
的 NSManagedObjectContext 子类,它重写了 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 的自定义子类中,如何将获取请求序列化为适合服务器的查询字符串参数。因此,给定上述获取请求,相应的 URL 将是:
http://example.com/people?name=John
可以获得返回的谓词的字符串表示形式,
name == "John" AND endpoint == "people"
我可以解析它以获取参数 name
和 endpoint< /代码>。但是,是否可以在不解析字符串的情况下完成此操作?下面是
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
Is there a way to inspect a NSPredicate object for the purposes of serializing it into a URL? I am trying to retrieve the data remotely and need to translate the predicate object into a URL with querystring parameters that the server understands.
This was inspired by a talk given in WWDC 2010 called "Building a Server Driven User EXperience" where the speakers talk about using Core-Data and with a server backend. I have followed the session video and slides, but am stuck on the serializing point. For example, there is a Person
object, and I'm trying to fetch all people whose first name is "John". I am using a subclass of NSManagedObjectContext
called RemoteManagedObjectContext
, which overrides the executeFetchRequest
method, and is supposed to send the call to the server instead. The fetch request is being created as (ellipsed non-essential parts):
@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
Now inside the custom subclass of NSManagedObjectContext
, how can I serialize the fetch request into querystring parameters suitable for the server. So given the above fetch request, the corresponding URL would be:
http://example.com/people?name=John
It is possible to get a string representation of the predicate which returns,
name == "John" AND endpoint == "people"
that I can parse to get the parameters name
, and endpoint
. However, is it possible to do it without parsing the string? Here's a partial implementation of the RemoteManagedObjectContext
class.
@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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
甚至比字符串表示更好的是面向对象的表示!而且它是自动完成的!
首先,检查
NSPredicate
的类。它将是一个 NSCompoundPredicate。将其转换为适当的变量。然后您会看到它的
compoundPredicateType
是NSAndPredicateType
,就像您所期望的那样。您还可以看到
-subpredicates
返回的数组显示了 2 个NSComparisonPredicates
。第一个子谓词具有
NSKeyPathExpressionType
类型的左表达式和@"name"
的-keyPath
,运算符为NSEqualToPredicateOperatorType
代码>.正确的表达式将是NSConstantValueExpressionType
类型的NSExpression
,-constantValue
将为@"John"
。第二个子谓词类似,只是左侧表达式的
keyPath
将为@"endpoint"
,右侧表达式的constantValue
将为>@“人”
。如果您想了解有关将
NSPredicates
转换为 HTTP Get 请求的更多深入信息,请查看我的 StackOverflow 框架“StackKit” 就是这样做的。它基本上是一个行为类似于 CoreData 的框架,但使用 StackOverflow.com(或任何其他堆栈交换站点)来检索信息。在下面,它执行大量操作将NSPredicate
对象转换为 URL。如果您有任何具体问题,也欢迎您给我发电子邮件。Even better than a string representation is an object-oriented representation! And it's done automatically!
First, check the class of the
NSPredicate
. It will be anNSCompoundPredicate
. Cast it to an appropriate variable.You'll then see that it's
compoundPredicateType
isNSAndPredicateType
, just like you'd expect.You can also see that the array returned by
-subpredicates
reveals 2NSComparisonPredicates
.The first subpredicate has a left expression of type
NSKeyPathExpressionType
and a-keyPath
of@"name"
, the operator isNSEqualToPredicateOperatorType
. The right expression will be anNSExpression
of typeNSConstantValueExpressionType
, and the-constantValue
will be@"John"
.The second subpredicate will be similar, except that the left expression's
keyPath
will be@"endpoint"
, and the right expression'sconstantValue
will be@"people"
.If you want more in-depth information on turning
NSPredicates
into an HTTP Get request, check out my StackOverflow framework, "StackKit", which does just that. It's basically a framework that behaves similarly to CoreData, but uses StackOverflow.com (or any other stack exchange site) to retrieve information. Underneath, it's doing a lot to convertNSPredicate
objects into a URL. You're also welcome to email me any specific questions you have.