Reputation: 648
I've built an API client for communicating with my web-server and all HTTP requests in my app are done using this class: (subclass of AFHTTPRequestOperationManager)
+ (SNPAPIClient *)sharedClient {
static SNPAPIClient *_sharedClient = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSURL *baseURL = [NSURL URLWithString:BASE_URL];
_sharedClient = [[SNPAPIClient alloc] initWithBaseURL:baseURL];
_sharedClient.responseSerializer = [AFJSONResponseSerializer serializer];
_sharedClient.requestSerializer = [AFJSONRequestSerializer serializer];
});
return _sharedClient;
}
The class has 3 methods for POST, GET & POST-MULTIPART. While POST & GET methods work perfectly, I'm having issues with POST-MULTIPART.
-(void)httpPOSTMultiPartRequestWithPath:(NSString*)path Parameters:(NSDictionary*)parameters BodyBlock:(id)bodyBlock Completion:(APICompletionBlock)apiComp{
comp = apiComp;
[self POST:path
parameters:parameters
constructingBodyWithBlock:bodyBlock
success:^(NSURLSessionDataTask *task, id responseObject) {
comp(responseObject,nil);
}
failure:^(NSURLSessionDataTask *task, NSError *error) {
comp(nil,error);
}];
}
Specifically, I'm trying to send a simple JSON to the server followed by an image. I've tried doing something like this:
From my controller i'm calling:
NSDictionary *POSTpic = [NSDictionary dictionaryWithObjectsAndKeys:@"109",@"userId",@"P",@"contentType", nil];
NSURL *pictuePath = [NSURL fileURLWithPath:@"cat.JPG"];
[[SNPAPIClient sharedClient]httpPOSTMultiPartRequestWithPath:@"PATH_GOES_HERE"
Parameters:POSTpic
BodyBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileURL:pictuePath name:@"profile" error:nil];
}
Completion:^(id serverResponse, NSError *error){
if (serverResponse){
NSLog(@"success");
}else{
NSLog(@"error: %@",error);
}
}];
Sending this request I get the following error in debugger:
internal server error (500)" UserInfo=0xb681650 {NSErrorFailingURLKey=http://"my_path", AFNetworkingOperationFailingURLResponseErrorKey=<NSHTTPURLResponse: 0xb347d40> { URL: http://"my_path" } { status code: 500, headers {
"Content-Length" = 142;
"Content-Type" = "text/plain";
Date = "Wed, 06 Nov 2013 19:26:05 GMT";
"Proxy-Connection" = "Keep-alive";
Server = "nginx admin";
} }, NSLocalizedDescription=Request failed: internal server error (500)}
For some reason, even though I send an NSDictionary and my request serilaizer is set to AFJSONRequestSerializer, the JSON object is not created. Again, this only happens with POST MULTIPART, other requests done with the same client and settings, are processed correctly.
Thanks!
Upvotes: 2
Views: 2939
Reputation: 450
I encountered something similar on Rails 3.1 and upgrading to 3.2 solved it for me.
Upvotes: 0
Reputation: 648
It has been a while since I solved this but maybe this could still help someone. Eventually, in my case, the upper level httpPOSTMultiPartRequestWithPath method did not cut and I needed more flexibility in the message structure (for instance, setting custom boundaries). I ended up using the HTTPRequestOperationWithRequest method and created the URLrequest manually.
-(void)httpPOSTmultipartContentWithPath:(NSString*)path Parameters:(NSDictionary*)parameters Body:(NSData*)body Completion:(APICompletionBlock)apiComp{
NSURL *pathURL = [NSURL URLWithString:path];
NSURLRequest *request = [self POSTRequestWithURL:pathURL DataDictionary:parameters andBody:body];
AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request
success:^(AFHTTPRequestOperation *operation, id responseObject) {
apiComp(responseObject,nil);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
apiComp(nil,error);
}];
[operation start];
}
- (NSMutableURLRequest *)POSTRequestWithURL:(NSURL *)url DataDictionary:(NSDictionary *)dictionary andBody:(NSData*)body
{
// Create a POST request
NSMutableURLRequest *myMedRequest = [NSMutableURLRequest requestWithURL:url];
[myMedRequest setHTTPMethod:@"POST"];
// Add HTTP header info
NSString *boundary = @"*****";
NSString *lineEnd = @"\r\n";
NSString *twoHyphens = @"--";
[myMedRequest addValue:[NSString stringWithFormat:@"multipart/form-data;boundary= %@", boundary] forHTTPHeaderField:@"Content-Type"];
//create HTTP Body
NSMutableData *POSTBody = [NSMutableData data];
[POSTBody appendData:[[NSString stringWithFormat:@"boundary=%@%@%@",twoHyphens,boundary,lineEnd] dataUsingEncoding:NSUTF8StringEncoding]];
[POSTBody appendData:[[NSString stringWithFormat:@"Content-Type:multipart/related;type=application/json;boundary=%@%@%@%@",twoHyphens,twoHyphens,boundary,lineEnd] dataUsingEncoding:NSUTF8StringEncoding]];
[POSTBody appendData:[[NSString stringWithFormat:@"Content-Id:jsonTemp%@",lineEnd] dataUsingEncoding:NSUTF8StringEncoding]];
[POSTBody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"json\"%@%@", lineEnd,lineEnd] dataUsingEncoding:NSUTF8StringEncoding]];
//add JSON dictionary with request inforamtion
[POSTBody appendData:[[NSString stringWithFormat:@"%@%@",dictionary
,lineEnd] dataUsingEncoding:NSUTF8StringEncoding]];
[POSTBody appendData:[lineEnd dataUsingEncoding:NSUTF8StringEncoding]];
[POSTBody appendData:[[NSString stringWithFormat:@"%@%@%@",twoHyphens,boundary,lineEnd] dataUsingEncoding:NSUTF8StringEncoding]];
[POSTBody appendData:[[NSString stringWithFormat:@"Content-Type:image/jpg"] dataUsingEncoding:NSUTF8StringEncoding]];
[POSTBody appendData:[[NSString stringWithFormat:@"%@",lineEnd] dataUsingEncoding:NSUTF8StringEncoding]];
[POSTBody appendData:[[NSString stringWithFormat:@"Content-Id:%@",@"profile.jpg"] dataUsingEncoding:NSUTF8StringEncoding]];
[POSTBody appendData:[[NSString stringWithFormat:@"%@",lineEnd] dataUsingEncoding:NSUTF8StringEncoding]];
[POSTBody appendData:[[NSString stringWithFormat:@"%@",lineEnd] dataUsingEncoding:NSUTF8StringEncoding]];
// Add image data
[POSTBody appendData:body];
// Add the closing -- to the POST Form
[POSTBody appendData:[[NSString stringWithFormat:@"%@",lineEnd] dataUsingEncoding:NSUTF8StringEncoding]];
[POSTBody appendData:[[NSString stringWithFormat:@"%@%@%@%@",twoHyphens,boundary,twoHyphens, lineEnd] dataUsingEncoding:NSUTF8StringEncoding]];
// Add the body to the myMedRequest & return
[myMedRequest setHTTPBody:POSTBody];
return myMedRequest;
}
Upvotes: 1
Reputation: 19544
The server is sending back a response with status code 500, which means that your server encountered an error while attempting to process the request. There doesn't appear to be anything wrong with how you're using AFNetworking, but the only way to tell is to debug things on the server side first.
Upvotes: 1