Using AFNetworking for asynchronous POST json requests

22,057

You are using AFHTTPRequestOperation and not AFJSONRequestOperation.

Also you can use the AFHttpClient directly:

NSDictionary *parameter = @{@"username":self.username.text, @"password":self.password.text};
[httpClient setParameterEncoding:AFJSONParameterEncoding];
[httpClient registerHTTPOperationClass:[AFJSONRequestOperation class]];

[httpClient postPath:@"api/v1/user/login/" parameters:parameter success:^(AFHTTPRequestOperation *operation, id responseObject) {
    // Print the response body in text
    BOOL *success = [[responseObject objectForKey:@"success"] boolValue];
    NSLog(@"Response: %@",responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    [self handleConnectionError:error];
}];

I would also suggest creating a creating only one instance of the AFHTTPClient using clientWithBaseURL: method.

Share:
22,057
Jonathan
Author by

Jonathan

Updated on February 05, 2020

Comments

  • Jonathan
    Jonathan over 4 years

    I've been trying to use POST json using AFNetworking. After some research I finally got this to work

    - (IBAction)go:(id)sender {
        //Some POST
        AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:@"https://www.test.com/"]];
        [httpClient setParameterEncoding:AFJSONParameterEncoding];
        NSMutableURLRequest *request = [httpClient requestWithMethod:@"POST"
                                                                path:@"https://www.test.com/user/login/"
                                                          parameters:@{@"username":self.username.text, @"password":self.password.text}];
        AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
        [httpClient registerHTTPOperationClass:[AFHTTPRequestOperation class]];
        [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
            // Print the response body in text
            NSDictionary *jsonDict = (NSDictionary *) responseObject;
            BOOL *success = [[jsonDict objectForKey:@"success"] boolValue];
            NSLog(@"Response: %@", [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding]);
        } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            NSLog(@"Error: %@", error);
        }];
        [operation start];
    }
    

    This is fine for demonstation purposes, but now I want to finally use NSDirectory to split out my json objects, so I tried doing something like this, but my app crashes whenever I enter click on the button

    - (IBAction)go:(id)sender {
        //Some POST
        AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:@"https://www.test.com/"]];
        [httpClient setParameterEncoding:AFJSONParameterEncoding];
        NSMutableURLRequest *request = [httpClient requestWithMethod:@"POST"
                                                                path:@"https://www.test.com/user/login/"
                                                          parameters:@{@"username":self.username.text, @"password":self.password.text}];
        AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
        [httpClient registerHTTPOperationClass:[AFHTTPRequestOperation class]];
        [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
            // Print the response body in text
            NSDictionary *jsonDict = (NSDictionary *) responseObject;
            BOOL success = [[jsonDict objectForKey:@"success"] boolValue];
            if (success) {
                NSLog(@"yes!!!");
            }else{
                NSString *reason = [jsonDict objectForKey:@"reason"];
                NSLog(@"reason: %@",reason);
            }
        } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            NSLog(@"Error: %@", error);
        }];
        [operation start];
    }
    

    error

    2013-03-08 03:27:34.648 test[18253:c07] -[__NSCFData objectForKey:]: unrecognized selector sent to instance 0x888a6b0
    2013-03-08 03:27:34.648 test[18253:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFData objectForKey:]: unrecognized selector sent to instance 0x888a6b0'
    *** First throw call stack:
    (0x1ce0012 0x111de7e 0x1d6b4bd 0x1ccfbbc 0x1ccf94e 0x24608 0x12e71 0x4a4453f 0x4a56014 0x4a467d5 0x1c86af5 0x1c85f44 0x1c85e1b 0x1c3a7e3 0x1c3a668 0x61ffc 0x21ad 0x20d5)
    libc++abi.dylib: terminate called throwing an exception
    
  • Jonathan
    Jonathan over 11 years
    rckoenes, thats because that is the only post example I could find. can you please elaborate it for me if you dont mind? what changes should be made to the existing code?
  • rckoenes
    rckoenes over 11 years
    Also read the documentation on github.com/AFNetworking/AFNetworking it does explain how to correctly use the AFHTTPClient. Have a look at the AFAppDotNetAPIClient this will give you a good example on how to use the AFHTTPClient.
  • Jonathan
    Jonathan over 11 years
    Thank you so much rckoenes. but what is handleConnectionError? also, do I not need [operation start]; anymore? and is this method asynchronous as well?
  • rckoenes
    rckoenes over 11 years
    The handleConnectionError: is a method that I made my self, such a methods will handle the NSError and present the user with a message. Yes the methods is asynchronous.
  • Jonathan
    Jonathan over 11 years
    okay, that makes sense. But I just tested this code. it gives me the same error as my code from above
  • rckoenes
    rckoenes over 11 years
    Are you sure that you [httpClient registerHTTPOperationClass:[AFJSONRequestOperation class]]; add this line. This tells AFHTTPClient to use JSON. And add this as well: [httpClient setDefaultHeader:@"Accept" value:@"application/json"]; By the way this is all in the AFNetworking example apps.
  • rckoenes
    rckoenes over 11 years
    If you are still using your old code dit you also replace the AFHTTPRequestOperation *operation with AFJSONRequestOperation *operation
  • Sheharyar
    Sheharyar about 10 years
    I'm literally crying. Thankyou. Thankyou!
  • Ben
    Ben over 9 years
    Please edit your answer, and explain how this solves the problem.