AFNetworking 2.0 Get JSON from code 400 in failure block
Asked Answered
C

4

7

I'm using AFHTTPRequestOperationManager for a POST request. Now I'm deliberately entering incorrect information to handle a 400 error code. Now, the web service actually returns a JSON with a message explaining to the user what they've done wrong. I would very much like to get this JSON to display the message in a UIAlertView. However, the failure block of:

[operationManager POST:ServerURL parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"Success: Status Code: %d", operation.response.statusCode);
}
 failure:^(AFHTTPRequestOperation *operation, NSError *error) {
     NSLog(@"Failed: Status Code: %d", operation.response.statusCode);
 }];

doesn't pass down a responseObject like the one in the success block. So does anyone know how I can access the JSON returned by the Web Service with the 400 error? The NSError *error simply gives me Request failed: bad request (400) and not the JSON returned.

Any help would be appreciated,
Mike

Crooked answered 26/10, 2013 at 15:56 Comment(2)
I am getting the same response, did you get any solution to the problem?Masonite
This answer worked for me, https://mcmap.net/q/343156/-afnetworking-2-0-afhttpsessionmanager-how-to-get-status-code-and-response-json-in-failure-blockAvant
F
8

Looking at the code for - responseObject, it appears that an HTTP error prevents it from being populated. You can grab the responseData directly and parse it yourself, but I would say this is either a bug or a good enhancement request. (It looks like - responseObject probably should be checking self.responseSerializationError, not self.error, when deciding if it should try to build a response object.)

Filemon answered 26/10, 2013 at 16:44 Comment(5)
Hey Jesse thanks for the great answer, very detailed. I'll probably have snoop around myself now and see if I can't make a little change, but we'll see.Crooked
Is there any way it would return the server response in json. yet!Leathaleather
You have probably got around this but you can get the responseObject from the AFHTTPRequestOperation object in the failure blockClosegrained
@Closegrained The problem is that the responseObject is nil in the failure block.Filemon
There are many issues on Github about this, but Matt says it will break API designTusker
T
5

You can do either of these solutions

1) Set the acceptableStatusCodes to accept your 400 statusCode, and you handle in the success block

manager.responseSerializer.acceptableStatusCodes = [NSIndexSet indexSetWithIndex:400];

2) Create a custom ResponseSerializer, like this JSONResponseSerializerWithData, to insert the responseObject into the NSError userInfo, and handle in the failure block

Pro tip: AFNetworking is opensource, just take a look at AFHTTPRequestOperation for methods

setCompletionBlockWithSuccess:failure:

responseObject

error
Tusker answered 23/7, 2014 at 10:0 Comment(0)
N
0

Following code worded for me:

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    manager.responseSerializer = [AFJSONResponseSerializer serializer];
    manager.requestSerializer = [AFJSONRequestSerializer serializer];

    [manager.requestSerializer setValue:@"parse-application-id-removed" forHTTPHeaderField:@"X-Parse-Application-Id"];
    [manager.requestSerializer setValue:@"parse-rest-api-key-removed" forHTTPHeaderField:@"X-Parse-REST-API-Key"];
    [manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    manager.securityPolicy.allowInvalidCertificates = YES;

    NSString *URLString = [NSString stringWithFormat:@"%@/%@", BASE_URL,methodName];



    [manager POST:URLString parameters:requestDict success:^(AFHTTPRequestOperation *operation, id responseObject)
    {
        NSLog(@"JSON: %@", responseObject);

        [myDelegate StopIndicator];
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Error: %@", error);
        [myDelegate StopIndicator];
    }];
Nazler answered 30/3, 2015 at 7:28 Comment(0)
H
0

I also faced same problem in AFNetworking, as instead of using

- (NSURLSessionDataTask *)POST:(NSString *)URLString
                parameters:(id)parameters
                  progress:(void (^)(NSProgress * _Nonnull))uploadProgress
                   success:(void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success
                   failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure

Please try to use that one :-

- (NSURLSessionDataTask *)POST:(NSString *)URLString
                parameters:(id)parameters
 constructingBodyWithBlock:(void (^)(id <AFMultipartFormData> formData))block
                  progress:(nullable void (^)(NSProgress * _Nonnull))uploadProgress
                   success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
                   failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure

thanks,

Harrod answered 9/2, 2016 at 12:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.