Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AFJSONParameterEncoding in AFNetworking 2.x.x

I am implementing following paypal REST API:

curl -v https://api.sandbox.paypal.com/v1/vault/credit-card \
-H 'Content-Type:application/json' \
-H 'Authorization: Bearer {accessToken}' \
-d '{
 "payer_id":"user12345",
 "type":"visa",
 "number":"4417119669820331",
 "expire_month":"11",
 "expire_year":"2018",
 "first_name":"Joe",
 "last_name":"Shopper"
}'

I have successfully implement this api in AFNetworking 1.3.3 with following Code. Where PPWebService is subclass of AFHTTPClient

[[PPWebService sharedClient] setParameterEncoding:AFJSONParameterEncoding];
    [[PPWebService sharedClient] setDefaultHeader:@"Content-Type" value:@"application/json"];
    [[PPWebService sharedClient] setDefaultHeader:@"Authorization" value:[NSString stringWithFormat:@"Bearer %@", accessToken]];

    [[PPWebService sharedClient] postPath:@"vault/credit-card"
                               parameters:creditCard
                                  success:^(AFHTTPRequestOperation *operation, id responseObject)
    {
        NSDictionary *response = [self JSONToObject:operation.responseString];

        creditCardId = response[@"id"];

        if(creditCardId)
        {
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Credit card" message:@"Saved !!" delegate:nil cancelButtonTitle:@"on" otherButtonTitles:nil];

            [alert show];
        }
    }
                                  failure:^(AFHTTPRequestOperation *operation, NSError *error)
    {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Credit card" message:error.description delegate:nil cancelButtonTitle:@"on" otherButtonTitles:nil];

        [alert show];
    }];

I want to use AFNetworking 2.x.x in my project. But I am not able to do it with this new version.

I have subclass AFHTTPRequestOperationManager. I search internet and people suggest me to use AFJSONRequestSerializer. All other code is very similar. But than also I am getting bad request error.

So how can I send raw JSON string in with POST method in AFNetworking 2.x.x?

EDIT

Code for AFNetworking 2.X.X

Error Status : 404 Bad Request

Response :

{"name":"MALFORMED_REQUEST","message":"The request JSON is not well formed.","information_link":"https://developer.paypal.com/docs/api/#MALFORMED_REQUEST","debug_id":"ab3c1dd874a07"}

I am getting proper response by using Postman as shown in following screenshot.

enter image description here

like image 231
CRDave Avatar asked Nov 11 '22 12:11

CRDave


1 Answers

So finally I got answer. I use subclass of AFHTTPSessionManager to implement API in my project. And use it with singleton object. So this is my singleton method.

+ (MASWebService *)APIClient
{
    static MASWebService *_sharedClient = nil;
    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^
    {
        NSURL *baseURL = [NSURL URLWithString:BaseURL];

        NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];

        _sharedClient = [[MASWebService alloc] initWithBaseURL:baseURL sessionConfiguration:config];

        _sharedClient.responseSerializer = [AFJSONResponseSerializer serializerWithReadingOptions:NSJSONReadingAllowFragments];

        _sharedClient.requestSerializer = [AFJSONRequestSerializer serializer];

        [_sharedClient.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    });

    return _sharedClient;
}

The main key line is setting Request Serializer HTTP Header "Content-Type" to "application/json"

If you are not subclassing AFHTTPSessionManager and using AFHTTPRequestOperationManager for single request than also it will work because AFHTTPRequestOperationManager is also conform to AFURLRequestSerialization protocol as property of AFHTTPRequestSerializer. I have not done it but it should look like this.

    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

    NSDictionary *parameters = @{@"foo": @"bar"};

    manager.responseSerializer = [AFJSONResponseSerializer serializerWithReadingOptions:NSJSONReadingAllowFragments];       
    manager.requestSerializer = [AFJSONRequestSerializer serializer];
    [manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];

    [manager POST:@"http://example.com/resources.json" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSLog(@"JSON: %@", responseObject);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Error: %@", error);
    }];

I hope this will work. Inform me in comment if I am wrong somewhere.

Source : AFNetworking 2.0 POST request working example code snippet

like image 191
CRDave Avatar answered Nov 15 '22 06:11

CRDave