Obj-C Afnetworking 2.0 Post Request Does Not Work

AFNetworking 2.0 post not working well

You returned JSON data as a response, but your assumption that you set Content-Type is incorrect. Create a response instance with the mimetype set to 'application/json'.

from flask import request, json

@app.route('/test', methods=['POST'])
def test():
data = json.dumps(request.get_json())
resp = app.response_class(data, mimetype='application/json')
return resp

AFNetworking Post Request

It's first worth adding (as this answer is still popular 6 years after I initially wrote it...) that the first thing you should consider is whether you should even use AFNetworking. NSURLSession was added in iOS 7 and means you don't need to use AFNetworking in many cases - and one less third party library is always a good thing.

For AFNetworking 3.0:

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
NSDictionary *params = @{@"user[height]": height,
@"user[weight]": weight};
[manager POST:@"https://example.com/myobject" parameters:params progress:nil success:^(NSURLSessionTask *task, id responseObject) {
NSLog(@"JSON: %@", responseObject);
} failure:^(NSURLSessionTask *operation, NSError *error) {
NSLog(@"Error: %@", error);
}];

For AFNetworking 2.0 (and also using the new NSDictionary syntax):

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *params = @{@"user[height]": height,
@"user[weight]": weight};
[manager POST:@"https://example.com/myobject" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"JSON: %@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error: %@", error);
}];

If you are stuck using AFNetworking 1.0, you need to do it this way:

NSURL *url = [NSURL URLWithString:@"https://example.com/"];
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];

NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:
height, @"user[height]",
weight, @"user[weight]",
nil];
[httpClient postPath:@"/myobject" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSString *responseStr = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
NSLog(@"Request Successful, response '%@'", responseStr);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"[HTTPClient Error]: %@", error.localizedDescription);
}];

POST request with AFNetworking 2.0 - AFHTTPSessionManager

This error means that your POST request went through, the server is successfully returning you some data, which NSJSONSerialization is having trouble parsing.

You probably need to set your AFJSONResponseSerializer to allow JSON fragments.

In the init method of your AFHTTPSessionManager subclass:

AFJSONResponseSerializer *responseSerializer = [AFJSONResponseSerializer serializerWithReadingOptions:NSJSONReadingAllowFragments];
[self setResponseSerializer:responseSerializer];

If this doesn't work, you probably have an encoding issue. From the NSJSONSerialization class reference:

The data must be in one of the 5 supported encodings listed in the JSON specification: UTF-8, UTF-16LE, UTF-16BE, UTF-32LE, UTF-32BE. The data may or may not have a BOM. The most efficient encoding to use for parsing is UTF-8, so if you have a choice in encoding the data passed to this method, use UTF-8.

Check the encoding type sent by your server.

Finally, you can either set breakpoints inside of AFNetworking, or set up AFNetworkActivityLogger, which will log requests as they are sent and received to your console. This tool is incredibly helpful for debugging this type of issue.

AFNetworking is not sending a request

The request runs asynchronously, and as a result the main function is ending, and thus the app is terminating, before the request is done.

You need to have an NSRunLoop running to keep the app alive and process AFNetworking's NSURLConnection events properly. The easiest way to do that is to not use a command line app, but instead use a standard Cocoa or Cocoa Touch app, and start the AFHTTPRequestOperation in the appropriate place. The NSRunLoop will keep running, the app won't immediately terminate, and AFNetworking's NSURLConnection will have a chance to process the request and await the response.

If you really want to do a command line app, then you can keep the run loop alive yourself:

int main(int argc, const char * argv[]) {
@autoreleasepool {
BOOL __block done = NO;
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];

AFHTTPRequestOperation *operation = ...
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
// do your success stuff

done = YES;
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// do your failure stuff

done = YES;
}];
[operation start];

while (!done && [runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]) {
// this is intentionally blank
}
}
return 0;
}

Can't make POST request - AFNetworking

You can better diagnose these issues if you translate the server's response into something you can parse/examine:

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters = @{@"fName": @"firstname", @"lName": @"lastname"};
[manager POST:@"http://00000.1111.ovh/api/Account/register" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"JSON = %@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error = %@", error);
if (operation.responseObject) {
NSLog(@"responseObject = %@", operation.responseObject);
} else {
NSLog(@"responseString = %@", operation.responseString);
}
}];

If you did that, you'd see that it responded with:

responseObject = {
message = "The request is invalid.";
modelState = {
"login.password" = (
"The Password field is required."
);
"login.username" = (
"The User name field is required."
);
};
}

Apparently, the request was missing the necessary authentication details.



Related Topics



Leave a reply



Submit