[英]How to handle Parse.com Rest API error with AFNetworking 2.0
[英]Parse.com and AFNetworking 2.0 Date Queries
我正在嘗試使用AFNetworking 2.0從Parse.com后端獲取記錄。 我希望在某個日期之后更新記錄。 Parse.com文檔聲明針對日期字段的比較查詢需要以以下格式進行url編碼:
'where={"createdAt":{"$gte":{"__type":"Date","iso":"2011-08-21T18:02:52.249Z"}}}'
這完全適用於卷曲。
在我的應用程序中,我使用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;
}
- (NSURLSessionDataTask *)eventsForSalesMeetingID:(NSString *)meetingID sinceDate:(NSDate *)lastUpdate completion:( void (^)(NSArray *results, NSError *error) )completion {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
NSTimeZone *gmt = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
[dateFormatter setTimeZone:gmt];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];
NSString *dateString = [dateFormatter stringFromDate:lastUpdate];
NSLog(@"date = %@", dateString);
NSDictionary *params = @{@"where": @{@"updatedAt": @{@"$gte": @{@"__type":@"Date", @"iso": dateString}}}};
NSURLSessionDataTask *task = [self GET:@"/1/classes/SalesMeetingEvents"
parameters:params
success:^(NSURLSessionDataTask *task, id responseObject) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)task.response;
NSLog(@"Response = %@", httpResponse);
if (httpResponse.statusCode == 200) {
dispatch_async(dispatch_get_main_queue(), ^{
completion(responseObject[@"results"], nil);
});
} else {
dispatch_async(dispatch_get_main_queue(), ^{
completion(nil, nil);
});
NSLog(@"Received: %@", responseObject);
NSLog(@"Received HTTP %d", httpResponse.statusCode);
}
} failure:^(NSURLSessionDataTask *task, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
completion(nil, error);
});
}];
return task;
}
但這會從服務器產生400錯誤。 解碼后返回的url編碼查詢字符串如下所示:
where[updatedAt][$gte][__type]=Date&where[updatedAt][$gte][iso]=2014-01-07T23:56:29.274Z
我嘗試對查詢字符串的后端進行硬編碼,如下所示:
NSString *dateQueryString = [NSString stringWithFormat:@"{\"$gte\":{\"__type\":\"Date\",\"iso\":\"%@\"}}", dateString];
NSDictionary *params = @{@"where":@{@"updatedAt":dateQueryString}};
這讓我更接近,但仍然是400錯誤; 從服務器返回的查詢字符串如下所示:
where[updatedAt]={"$gte":{"__type":"Date","iso":"2014-01-07T23:56:29.274Z"}}
如何從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;
}
並稱之為:
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);
}];
對不起,很長的帖子,希望它有所幫助
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.