使用AFFormURLParameterEncoding时,AFHttpClient在字典中的标记无效

时间:2012-03-07 16:22:44

标签: objective-c ios afnetworking

我已经浏览了SO和Google,但没有找到类似的问题。我觉得答案是盯着我的脸,我只需要另一双眼睛。

我正在使用AFNetworking连接到Stripe.com API。具体来说,我正在使用AFHTTPClient postPath将数据发送到端点,收费。 Stripe要求将请求编码为application / x-www-form-urlencoded,以便我不能使用JSON编码。

我遇到的问题是我有一个Charge对象和一个Card对象。卡是Charge的一个属性,我将Charge和Card转换为NSDictionary(卡是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中的无效令牌的任何建议?我专注于错误的事情吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

AFNetworking仅支持带有1级参数的AFFormURLParameterEncoding。

我正在为此修补

替换AFHTTPClient中的AFQueryStringFromParametersWithEncoding实现

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提交拉取请求