Ios Parse.com和AFNetworking 2.0日期查询
我正在尝试使用AFNetworking 2.0从Parse.com后端获取记录。我想在某个日期后更新记录。Parse.com文档说明,针对日期字段的比较查询需要采用以下格式进行url编码:Ios Parse.com和AFNetworking 2.0日期查询,ios,parse-platform,afnetworking-2,Ios,Parse Platform,Afnetworking 2,我正在尝试使用AFNetworking 2.0从Parse.com后端获取记录。我想在某个日期后更新记录。Parse.com文档说明,针对日期字段的比较查询需要采用以下格式进行url编码: 'where={"createdAt":{"$gte":{"__type":"Date","iso":"2011-08-21T18:02:52.249Z"}}}' 这在使用curl时非常有效 在我的应用程序中,我使用AFNetworking 2.0运行以下查询。初始化共享客户端时,我首先设置请求和响应序列化
'where={"createdAt":{"$gte":{"__type":"Date","iso":"2011-08-21T18:02:52.249Z"}}}'
这在使用curl时非常有效
在我的应用程序中,我使用AFNetworking 2.0运行以下查询。初始化共享客户端时,我首先设置请求和响应序列化程序:
+ (CSC_ParseClient *)sharedClient {
static CSC_ParseClient *_sharedClient = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSURL *baseURL = [NSURL URLWithString:@"https://api.parse.com"];
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
[config setHTTPAdditionalHeaders:@{ @"Accept":@"application/json",
@"Content-type":@"application/json",
@"X-Parse-Application-Id":@"my app ID",
@"X-Parse-REST-API-Key":@"my api key"}];
NSURLCache *cache = [[NSURLCache alloc] initWithMemoryCapacity:10 * 1024 * 1024
diskCapacity:50 * 1024 * 1024
diskPath:nil];
[config setURLCache:cache];
_sharedClient = [[CSC_ParseClient alloc] initWithBaseURL:baseURL
sessionConfiguration:config];
_sharedClient.responseSerializer = [AFJSONResponseSerializer serializer];
_sharedClient.requestSerializer = [AFJSONRequestSerializer serializer];
});
return _sharedClient;
}
}
但这会从服务器产生400错误。解码后返回的url编码查询字符串如下所示:
where[updatedAt][$gte][__type]=Date&where[updatedAt][$gte][iso]=2014-01-07T23:56:29.274Z
我试着像这样对querystring的后端进行编码:
NSString *dateQueryString = [NSString stringWithFormat:@"{\"$gte\":{\"__type\":\"Date\",\"iso\":\"%@\"}}", dateString];
NSDictionary *params = @{@"where":@{@"updatedAt":dateQueryString}};
where[updatedAt]={"$gte":{"__type":"Date","iso":"2014-01-07T23:56:29.274Z"}}
ParseAPISessionManager *manager = [ParseAPISessionManager sharedSession];
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setDay:13];
[comps setMonth:2];
[comps setYear:2014];
[comps setHour:16];
[comps setMinute:0];
NSDate *feb13 = [[NSCalendar currentCalendar] dateFromComponents:comps];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.'999Z'"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"GMT"]];
NSString *feb13str = [dateFormatter stringFromDate: feb13];
NSString *queryStr = [NSString stringWithFormat:@"{\"updatedAt\":{\"$gte\":{\"__type\":\"Date\",\"iso\":\"%@\"}}}", feb13str];
NSDictionary *parameters = @{@"where": queryStr};
[manager GET:@"classes/TestClass" parameters:parameters success:^(NSURLSessionDataTask *operation, id responseObject) {
NSLog(@"%@", responseObject);
} failure:^(NSURLSessionDataTask *operation, NSError *error) {
NSLog(@"Error: %@", error);
}];
这让我更接近,但仍然是一个400错误;从服务器返回的查询字符串如下所示:
NSString *dateQueryString = [NSString stringWithFormat:@"{\"$gte\":{\"__type\":\"Date\",\"iso\":\"%@\"}}", dateString];
NSDictionary *params = @{@"where":@{@"updatedAt":dateQueryString}};
where[updatedAt]={"$gte":{"__type":"Date","iso":"2014-01-07T23:56:29.274Z"}}
ParseAPISessionManager *manager = [ParseAPISessionManager sharedSession];
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setDay:13];
[comps setMonth:2];
[comps setYear:2014];
[comps setHour:16];
[comps setMinute:0];
NSDate *feb13 = [[NSCalendar currentCalendar] dateFromComponents:comps];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.'999Z'"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"GMT"]];
NSString *feb13str = [dateFormatter stringFromDate: feb13];
NSString *queryStr = [NSString stringWithFormat:@"{\"updatedAt\":{\"$gte\":{\"__type\":\"Date\",\"iso\":\"%@\"}}}", feb13str];
NSDictionary *parameters = @{@"where": queryStr};
[manager GET:@"classes/TestClass" parameters:parameters success:^(NSURLSessionDataTask *operation, id responseObject) {
NSLog(@"%@", responseObject);
} failure:^(NSURLSessionDataTask *operation, NSError *error) {
NSLog(@"Error: %@", error);
}];
如何从AFNetworking获取正确的查询字符串?我一开始使用的是ParseSDK,这使得这个查询非常简单,但是他们的SDK太重了(30+MB)。来自parse.com REST文档: where参数的值应编码为JSON。因此,如果您查看请求的实际URL,它将是JSON编码的,然后是URL编码的 您与硬编码字符串非常接近,只需对整个查询进行URL编码。我在以下方面取得了成功:
NSString *dateQueryString = [NSString stringWithFormat:@"{\"updatedAt\":{\"$gte\":{\"__type\":\"Date\",\"iso\":\"%@\"}}}", dateString];
NSDictionary *parameters = @{@"where": dateQueryString};
以下内容使用NSDictionary来构造dateQueryString:
NSString *dateQueryString;
NSDictionary *query = @{ @"updatedAt": @{ @"$gte": @{@"__type":@"Date",@"iso":dateString}}};
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:query
options:nil
error:&error];
if (!jsonData) {
NSLog(@"Error: %@", [error localizedDescription]);
}
NSString *dateQueryString = [[NSString alloc] initWithData:jsonData
encoding:NSUTF8StringEncoding];
NSDictionary *parameters = @{@"where": dateQueryString};
为了完整性-我正在使用AFHTTPSessionManager子类的共享实例:
@implementation ParseAPISessionManager
+ (instancetype)sharedSession {
static ParseAPISessionManager *_sharedClient = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sharedClient = [[ParseAPISessionManager alloc] initWithBaseURL:[NSURL URLWithString:parseAPIBaseURLString]];
});
return _sharedClient;
}
- (id)initWithBaseURL:(NSURL *)url {
self = [super initWithBaseURL:url];
if (self) {
self.requestSerializer = [AFJSONRequestSerializer serializer];
[self.requestSerializer setValue:parseAPIApplicationId forHTTPHeaderField:@"X-Parse-Application-Id"];
[self.requestSerializer setValue:parseRESTAPIKey forHTTPHeaderField:@"X-Parse-REST-API-Key"];
}
return self;
}
并这样称呼它:
NSString *dateQueryString = [NSString stringWithFormat:@"{\"$gte\":{\"__type\":\"Date\",\"iso\":\"%@\"}}", dateString];
NSDictionary *params = @{@"where":@{@"updatedAt":dateQueryString}};
where[updatedAt]={"$gte":{"__type":"Date","iso":"2014-01-07T23:56:29.274Z"}}
ParseAPISessionManager *manager = [ParseAPISessionManager sharedSession];
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setDay:13];
[comps setMonth:2];
[comps setYear:2014];
[comps setHour:16];
[comps setMinute:0];
NSDate *feb13 = [[NSCalendar currentCalendar] dateFromComponents:comps];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.'999Z'"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"GMT"]];
NSString *feb13str = [dateFormatter stringFromDate: feb13];
NSString *queryStr = [NSString stringWithFormat:@"{\"updatedAt\":{\"$gte\":{\"__type\":\"Date\",\"iso\":\"%@\"}}}", feb13str];
NSDictionary *parameters = @{@"where": queryStr};
[manager GET:@"classes/TestClass" parameters:parameters success:^(NSURLSessionDataTask *operation, id responseObject) {
NSLog(@"%@", responseObject);
} failure:^(NSURLSessionDataTask *operation, NSError *error) {
NSLog(@"Error: %@", error);
}];
抱歉发了这么长的帖子,希望能有所帮助您的
请求序列化程序
是否设置为AFJSONRequestSerializer
的实例?看起来它仍然设置为默认值,AFHTTPRequestSerializer
。不,共享客户端设置为使用JSON序列化程序:谢谢Piskin;我已经放弃了对答案的希望……然而,与此同时,我将整个项目转移到了StackMob,在那里我可以使用核心数据方法和NSPredicates查询我的后端。不用担心@Alpinista,关于StackMob的警告-他们是在12月被Paypal收购的,并将在5月关闭!出于这个原因,我不得不从stackMob迁移到parse。