Недопустимые токены AFHttpClient в словаре при использовании AFFormURLParameterEncoding

Я просмотрел SO и Google и не нашел подобной проблемы. Я чувствую, что ответ смотрит мне прямо в лицо, и мне просто нужна еще одна пара глаз.

Я использую AFNetworking для подключения к API Stripe.com. В частности, я использую AFHTTPClient postPath для отправки данных в конечную точку, сборы. Stripe требует, чтобы запрос был закодирован как application/x-www-form-urlencoded, поэтому я не могу использовать кодировку JSON.

Проблема, с которой я сталкиваюсь, заключается в том, что у меня есть объект Charge и объект Card. Card является свойством Charge, и я конвертирую как Charge, так и Card в NSDictionary (Card — это словарь внутри словаря Charge), а затем передаю их в качестве параметров запроса следующим образом:

NSDictionary *parameters = [ChargeRequest convertToDictionary:request];

[[StripeAPIClient sharedClient] postPath:@"charges" parameters:parameters 
success:^(AFHTTPRequestOperation *operation, id responseObject) 
{        
    NSLog(@"Response: %@", responseObject);
} 
failure:^(AFHTTPRequestOperation *operation, NSError *error) {        
    NSLog(@"Error: %@", [error localizedDescription]);
    NSLog(@"Response: %@", operation.responseString);
}];

Когда я делаю это со свойством AFHttpClient ParameterEncoding, установленным в AFFormURLParameterEncoding, Stripe возвращает эту ошибку:

"error": {
    "message": "Invalid token id: {\n    \"exp_month\" = 10;\n    \"exp_year\" = 2016;\n      number = 4242111111111111;\n}",
    "type": "invalid_request_error"
}

Значения в ошибке — это, в частности, ключ/значения объекта Card после его преобразования. Вот код, который я использую для преобразования:

   return [[NSDictionary alloc] initWithObjectsAndKeys:request.number, @"number", [NSNumber numberWithInt:10], @"exp_month", [NSNumber numberWithInt:2016], @"exp_year", nil];

Любые советы о том, что делать, чтобы избавиться от недопустимых токенов, помещенных в этот NSDictionary? Я фокусируюсь не на том?

Спасибо!


person Tony Zatelli    schedule 07.03.2012    source источник


Ответы (1)


AFNetworking поддерживает только AFFormURLParameterEncoding с 1 уровнем параметров.

Я пишу исправление для этого

заменить реализацию AFQueryStringFromParametersWithEncoding в AFHTTPClient на

extern NSArray * AFQueryParametersFromParametersAtBaseKeyWithEncoding(id parameters, NSString *baseKey, NSStringEncoding encoding);
extern NSArray * AFQueryParametersFromParametersDictionaryAtBaseKeyWithEncoding(NSDictionary *parameters, NSString *baseKey, NSStringEncoding encoding);
extern NSArray * AFQueryParametersFromParametersArrayAtBaseKeyWithEncoding(NSArray *parameters, NSString *baseKey, NSStringEncoding encoding);
extern NSArray * AFQueryStringComponentFromParameterAtBaseKeyWithEncoding(id parameter, NSString *key, NSStringEncoding encoding);

NSString * AFQueryStringFromParametersWithEncoding(NSDictionary *parameters, NSStringEncoding encoding) {
    NSMutableArray *mutableParameterComponents = [NSMutableArray array];
    [mutableParameterComponents addObjectsFromArray:AFQueryParametersFromParametersAtBaseKeyWithEncoding(parameters,nil,encoding)];   
    return [mutableParameterComponents componentsJoinedByString:@"&"];
}

NSArray * AFQueryParametersFromParametersAtBaseKeyWithEncoding(id parameters, NSString *baseKey, NSStringEncoding encoding)
{
    NSMutableArray *mutableParameterComponents = [NSMutableArray array];

    if([parameters isKindOfClass:[NSDictionary class]]) {
        [mutableParameterComponents addObjectsFromArray:AFQueryParametersFromParametersDictionaryAtBaseKeyWithEncoding(parameters,baseKey,encoding)];
    }
    else if([parameters isKindOfClass:[NSArray class]]) {
        [mutableParameterComponents addObjectsFromArray:AFQueryParametersFromParametersArrayAtBaseKeyWithEncoding(parameters,baseKey,encoding)];
    }
    else {
        [mutableParameterComponents addObject:AFQueryStringComponentFromParameterAtBaseKeyWithEncoding(parameters,baseKey,encoding)];
    } 

    return mutableParameterComponents;
}

NSArray * AFQueryParametersFromParametersDictionaryAtBaseKeyWithEncoding(NSDictionary *parameters, NSString *baseKey, NSStringEncoding encoding)
{
    NSMutableArray *mutableParameterComponents = [NSMutableArray array];

    id key = nil;

    NSEnumerator *enumerator = [parameters keyEnumerator];
    while ((key = [enumerator nextObject])) {
        NSString *newKey = baseKey?[NSString stringWithFormat:@"%@[%@]",baseKey,key]:key;
        [mutableParameterComponents addObjectsFromArray:AFQueryParametersFromParametersAtBaseKeyWithEncoding([parameters valueForKey:key],newKey,encoding)];
    }

    return mutableParameterComponents;
}

NSArray * AFQueryParametersFromParametersArrayAtBaseKeyWithEncoding(NSArray *parameters, NSString *baseKey, NSStringEncoding encoding)
{
    NSMutableArray *mutableParameterComponents = [NSMutableArray array];

    for (id value in parameters) {
        NSString* newKey = [NSString stringWithFormat:@"%@[]",newKey];
        [mutableParameterComponents addObjectsFromArray:AFQueryParametersFromParametersAtBaseKeyWithEncoding(value,newKey,encoding)];
    }

    return mutableParameterComponents;
}

NSArray * AFQueryStringComponentFromParameterAtBaseKeyWithEncoding(id parameter, NSString *key, NSStringEncoding encoding)
{
    return [NSString stringWithFormat:@"%@=%@", AFURLEncodedStringFromStringWithEncoding([key description], encoding), AFURLEncodedStringFromStringWithEncoding([parameter description], encoding)];
}

Я просто пишу тот же код для составных запросов и отправляю запрос на включение в AFNetworking.

person Mathieu Hausherr    schedule 07.03.2012
comment
Спасибо. Похоже, вам не хватает AFQueryStringComponentFromParameterAtBaseKeyWithEncoding в опубликованном вами коде реализации? - person Tony Zatelli; 07.03.2012