Ios Parse.com和AFNetworking 2.0日期查询

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运行以下查询。初始化共享客户端时,我首先设置请求和响应序列化

我正在尝试使用AFNetworking 2.0从Parse.com后端获取记录。我想在某个日期后更新记录。Parse.com文档说明,针对日期字段的比较查询需要采用以下格式进行url编码:

'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。