This is my first post in here and is not a repost, I have searched a lot in Stack Overflow for the answer, but without luck... The problem that I'm having is an intermittent error: "request body stream exhausted" with the code:-1021, I'm using AFNetworking 2.
This is what I use to create a RequestOperationManager:
- (AFHTTPRequestOperationManager *)createDefaultManager {
AFHTTPRequestOperationManager *postRequest = [[AFHTTPRequestOperationManager alloc]initWithBaseURL:[NSURL URLWithString:#"myURL"]];
postRequest.securityPolicy.allowInvalidCertificates = YES;
postRequest.responseSerializer = [AFXMLParserResponseSerializer serializer];
[postRequest.requestSerializer setValue:#"Keep-Alive" forHTTPHeaderField:#"Connection"];
[postRequest.requestSerializer setValue:#"text/xml" forHTTPHeaderField:#"Content-Type"];
[postRequest.requestSerializer setValue:#"en-US" forHTTPHeaderField:#"Content-Language"];
return postRequest;
}
Here is my post method:
- (void)postRequest:(AFHTTPRequestOperationManager *)request withURL:(NSString *)url withBody:(NSString *)body {
[request POST:url parameters:nil constructingBodyWithBlock:^(id <AFMultipartFormData>formData)
{
[formData throttleBandwidthWithPacketSize:kAFUploadStream3GSuggestedPacketSize
delay:kAFUploadStream3GSuggestedDelay];
NSMutableDictionary *mutableHeaders = [NSMutableDictionary dictionary];
[mutableHeaders setValue:[NSString stringWithFormat:#"text/xml"] forKey:#"Content-Type"];
[mutableHeaders setValue:[NSString stringWithFormat:#"any-value"] forKey:#"User-Agent"];
[formData appendPartWithHeaders:mutableHeaders body:[NSData dataWithBytes:[body UTF8String] length:[body length]]];
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
[self connectionSuccess:operation withResponse:responseObject];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
[self connectionFailed:operation withError:error];
NSLog(#"Here's the request: %#", operation.request.HTTPBody);
}];
}
I don't know what is wrong in what I'm doing. That should work all the time.
Thanks,
JJ
Related
Following is my code snippet. I am getting an error while runnning this code. I have added headers as part of the request. Is that the correct way ?
__block int i=1;
AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:[NSURL URLWithString:url]];
NSDictionary *parameters = #{#"wave_Id": [inputDictionary objectForKey:#"wave_Id"]};
AFHTTPRequestOperation *op = [manager POST:url parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
for(NSData *imageData in [inputDictionary objectForKey:#"images"])
{
[formData appendPartWithFileData:imageData name:[NSString stringWithFormat:#"file%d",i] fileName:[NSString stringWithFormat:#"abc%d.png",i] mimeType:#"image/png"];
i++;
}
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:&error];
NSAssert(jsonData, #"Failure building JSON: %#", error);
NSLog(#"Json Data Image Upload %#",jsonData);
NSAssert(jsonData, #"Failure building JSON: %#", error);
NSString *token = [SSKeychain passwordForService:RegistrationTokenKey account:LoggedInUserKey];
NSDictionary *jsonHeaders = #{#"Content-Disposition" : #"form-data; name=\"parameters\"",
#"Content-Type" : #"application/json",
#"Accept" : #"application/json",
#"Authorization" : token};
[formData appendPartWithHeaders:jsonHeaders body:jsonData];
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Success: %# ***** %#", operation.responseString, responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %# ***** %#", operation.responseString, error);
}];
[op start];
I need your complete method to be 100% sure, but please try writing this way and see if it helps:
__block int i = 1;
NSMutableArray *mutableOperations = [NSMutableArray array];
NSDictionary *parameters = #{#"wave_Id": [inputDictionary objectForKey:#"wave_Id"]};
for (NSData *imageData in [inputDictionary objectForKey:#"images"]) {
NSURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:#"POST"
URLString:url
parameters:parameters
constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileData:imageData
name:[NSString stringWithFormat:#"file%d",i]
fileName:[NSString stringWithFormat:#"abc%d.png",i]
mimeType:#"image/png"];
i++;
}
error:nil];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[mutableOperations addObject:operation];
}
NSArray *operations = [AFURLConnectionOperation batchOfRequestOperations:mutableOperations progressBlock:^(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations) {
NSLog(#"%lu of %lu images uploaded!", numberOfFinishedOperations, totalNumberOfOperations);
} completionBlock:^(NSArray *operations) {
NSLog(#"All images have been uploade!");
}];
[[NSOperationQueue mainQueue] addOperations:operations waitUntilFinished:NO];
Actually I modified the same code and its working now. Changed the "Content-Type" to "multipart/form-data".
Also added the key (parameter name) for my imagesArray in the API request to the following method
"formData appendPartWithFileData:imageData name:#"yourKey"..."
if (_isUploadImage) {
__block int i=1;
AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:[NSURL URLWithString:url]];
[manager.requestSerializer setValue:#"multipart/form-data" forHTTPHeaderField:#"Content-Type"];
[manager.requestSerializer setValue:#"application/json" forHTTPHeaderField:#"Accept"];
if (_shouldBeInHeader) {
NSString *token = [SSKeychain passwordForService:RegistrationTokenKey account:LoggedInUserKey];
[manager.requestSerializer setValue:[NSString stringWithFormat:#"Token %#",token] forHTTPHeaderField:#"Authorization"];
}
NSDictionary *parameters = #{#"wave_id": [inputDictionary objectForKey:#"wave_id"]};
AFHTTPRequestOperation *op = [manager POST:url parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
for (NSData *imageData in [inputDictionary objectForKey:#"images"])
{
[formData appendPartWithFileData:imageData name:[NSString stringWithFormat:#"images"] fileName:[NSString stringWithFormat:#"abc%d.png",i] mimeType:#"image/png"];
i++;
}
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Success");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Failed");
}];
[op start];
}
currently i am working on image uploading in ios application and here is my code
AFHTTPRequestOperationManager *man = [[AFHTTPRequestOperationManager alloc]init];
man.responseSerializer.acceptableContentTypes = [NSSet setWithObject:#"text/html"];
NSData *imageData = UIImagePNGRepresentation(self.imageView.image);
AFHTTPRequestOperation *op = [man POST:AddGroup parameters:#{ #"userid":#"6",
#"name":self.txtGroupName.text
#"description":self.textViewGroupDescription.text,
#"image":imageData }
constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileData:imageData name:#"image" fileName:filename mimeType:#"image/png"];
}
success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSLog(#"Success: %# ***** %#", operation.description, operation.responseString);
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Imani" message:#"New Group Succesfully Created.." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil] ;
[alertView show];
}
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(#"Error: %# ***** %#", operation.responseString, error);
}];
[op start];
now i am getting response from successfully from json but image data are passing null in to server any one have idea ?
Thank you.
try this cede to upload image on server.
AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:[NSURL URLWithString:#"your api link"]];
NSData *imageData = UIImageJPEGRepresentation(self.imgPost.image, 0.5);
NSDictionary *parameters = #{#"param": #"value",
#"param2" : #"value2"
};
AFHTTPRequestOperation *op = [manager POST:#"/api/store/posts/format/json" parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
//do not put image inside parameters dictionary as I did, but append it!
[formData appendPartWithFileData:imageData name:#"file" fileName:[NSString stringWithFormat:#"njoyful_%f.jpg",[NSDate timeIntervalSinceReferenceDate]] mimeType:#"image/jpeg"];
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Success: %# ***** %#", operation.responseString, responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %# ***** %#", operation.responseString, error);
}];
[op start];
I'm not familiar with AFHTTPRequestOperation so i'll just give you something i'm using that creates json request.
- (NSURLRequest *)convertToRequest:(NSString *)stringURL withDictionary:(NSDictionary *)dictionary
{
NSError *error = nil;
NSData *JSONData = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:&error];
NSURL *url = [NSURL URLWithString:stringURL];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
[request setHTTPBody: JSONData];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept-Encoding"];
[request setValue:[NSString stringWithFormat:#"%lu", (unsigned long)[JSONData length]] forHTTPHeaderField:#"Content-Length"];
return request;
}
Please check my answer here
This also work for multi image upload. Cheers! :)
I want to send a JSON String to server using AFNetworking POST request.
Currently I am trying following code
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
NSData * data = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:data];
[request setTimeoutInterval:120];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
AFHTTPRequestOperation *operation = [manager HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject)
{ NSLog(#"JSON: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(#"Error: %#", error);
}];
[operation start];`
Nothing is happening. The code neither enters success block nor the failure block. What can be the reason? Is there any alternate way of doing this in AFNetworking 2.
NOTE: Request is working perfectly on POSTMAN and returns response in less than 500 ms.
This is working code of mine
NSDictionary *parameters = [NSDictionary dictionary];//set values here
AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] init];
[manager POST:#"http://example.com/api" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
//Do success code
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//do failure code
}];
This is the function which configure HTTP body AFJSONRequestSerializer
#pragma mark - AFURLRequestSerialization
- (NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request
withParameters:(id)parameters
error:(NSError *__autoreleasing *)error
{
NSParameterAssert(request);
if ([self.HTTPMethodsEncodingParametersInURI containsObject:[[request HTTPMethod] uppercaseString]]) {
return [super requestBySerializingRequest:request withParameters:parameters error:error];
}
NSMutableURLRequest *mutableRequest = [request mutableCopy];
[self.HTTPRequestHeaders enumerateKeysAndObjectsUsingBlock:^(id field, id value, BOOL * __unused stop) {
if (![request valueForHTTPHeaderField:field]) {
[mutableRequest setValue:value forHTTPHeaderField:field];
}
}];
if (parameters) {
if (![mutableRequest valueForHTTPHeaderField:#"Content-Type"]) {
[mutableRequest setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
}
[mutableRequest setHTTPBody:[NSJSONSerialization dataWithJSONObject:parameters options:self.writingOptions error:error]];
}
return mutableRequest;
}
You are using AFJSONRequestSerializer as request serializer and it is meaning, you are sending JSON string from NSDictionary as HTTP body
[mutableRequest setHTTPBody:[NSJSONSerialization dataWithJSONObject:parameters options:self.writingOptions error:error]];
}
So you all need to do is make NSDictionary from JSON values, and call as above.
No need to make JSON string.
I am trying to use AFHTTPRequestOperationManager to make an HTTP request. I need to use AFHTTPRequestOperationManager because I want to be able to cancel all operations if necessary. I can't get this working for some reason. The completion blocks aren't called. Am I missing something?
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"https://twitter.com/%#", username]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setValue:#"MyUserAgent (iPhone; iOS 7.0.2; gzip)" forHTTPHeaderField:#"User-Agent"];
[request setHTTPMethod:#"GET"];
[self.manager HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSString *html = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
if ([html containsString:#"var h = decodeURI(l.hash.substr(1)).toLowerCase();"]) {
completion(YES, nil);
} else {
completion(NO, nil);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
completion(NO, error);
}];
This is working code, you need to use GET or POST method there.
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *params = #{#"email":emailfield.text};
[manager GET:#"http://example.com/api" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
While everyone else is right -- you should be using the modern AFNetworking constructs instead of the legacy features -- there is a quick way to get done what you're looking to get done.
By the looks of it, the method - (??? *) HTTPRequestOperationWithRequest:success:failure likely returns an AFHTTPRequestOperation. If I'm correct, you just need to actually start the operation. See below for your code, corrected.
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"https://twitter.com/%#", username]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setValue:#"MyUserAgent (iPhone; iOS 7.0.2; gzip)" forHTTPHeaderField:#"User-Agent"];
[request setHTTPMethod:#"GET"];
AFHTTPRequestOperation *op = [self.manager HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSString *html = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
if ([html containsString:#"var h = decodeURI(l.hash.substr(1)).toLowerCase();"]) {
completion(YES, nil);
} else {
completion(NO, nil);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
completion(NO, error);
}];
[op start];
HTTPRequestOperationWithRequest method returns AFHTTPRequestOperation. You have to add it to some operation queue to start it. For example
AFHTTPRequestOperation *operation = [self.manager HTTPRequestOperationWithRequest:request .........
[[NSOperationQueue currentQueue] addOperation:operation];
You can use AFHTTPSessionManager which is a little better than AFHTTPRequestOperationManager and cancel requests using method cancel of NSURLSessionDataTask. You can find some code examples here - AFNetworking 2.0 cancel specific task
Check this will work
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:#"application/json", nil];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
[manager POST:url parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
}];
I am updating an old application code which used ASIHTTPRequest with AFNetworking. In my case, I am sending a bench of data to API, these data are different types: Image and other.
Here is the code I adopt so far, implementing an API client, requesting a shared instance, prepare the params dictionary and send it to remote API:
NSMutableDictionary *params = [NSMutableDictionary dictionary];
[params setValue:#"Some value" forKey:aKey];
[[APIClient sharedInstance]
postPath:#"/post"
parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
//some logic
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//handle error
}];
What would be the case when I want to add an image to the params dictionary?
With ASIHTTPRequest, I used to do the following:
NSData *imgData = UIImagePNGRepresentation(anImage);
NSString *newStr = [anImageName stringByReplacingOccurrencesOfString:#"/"
withString:#"_"];
[request addData:imgData
withFileName:[NSString stringWithFormat:#"%#.png",newStr]
andContentType:#"image/png"
forKey:anOtherKey];
I digged into AFNetworking documentation and found they appending the image in an NSMutableRequest like this:
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];
NSData *imageData = UIImageJPEGRepresentation([UIImage imageNamed:#"avatar.jpg"], 0.5);
NSMutableURLRequest *request = [httpClient multipartFormRequestWithMethod:#"POST" path:#"/upload" parameters:nil constructingBodyWithBlock: ^(id <AFMultipartFormData>formData) {
[formData appendPartWithFileData:imageData name:#"avatar" fileName:#"avatar.jpg" mimeType:#"image/jpeg"];
}];
How should I mix this together on a neat way to integrate my image data into the APIClient request? Thanx in advance.
I have used same AFNetworking to upload image with some parameter. This code is fine working for me. May be it will help out
NSData *imageToUpload = UIImageJPEGRepresentation(uploadedImgView.image, 1.0);//(uploadedImgView.image);
if (imageToUpload)
{
NSDictionary *parameters = [NSDictionary dictionaryWithObjectsAndKeys:keyParameter, #"keyName", nil];
AFHTTPClient *client= [AFHTTPClient clientWithBaseURL:[NSURL URLWithString:#"http://------"]];
NSMutableURLRequest *request = [client multipartFormRequestWithMethod:#"POST" path:#"API name as you have" parameters:parameters constructingBodyWithBlock: ^(id <AFMultipartFormData>formData) {
[formData appendPartWithFileData: imageToUpload name:#"image" fileName:#"temp.jpeg" mimeType:#"image/jpeg"];
}];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSDictionary *jsons = [NSJSONSerialization JSONObjectWithData:responseObject options:kNilOptions error:nil];
//NSLog(#"response: %#",jsons);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
if([operation.response statusCode] == 403)
{
//NSLog(#"Upload Failed");
return;
}
//NSLog(#"error: %#", [operation error]);
}];
[operation start];
}
Good Luck !!
With AFNetworking 2.0.1 this code worked for me.
-(void) saveImage: (NSData *)imageData forImageName: (NSString *) imageName {
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSString *imagePostUrl = [NSString stringWithFormat:#"%#/v1/image", BASE_URL];
NSDictionary *parameters = #{#"imageName": imageName};
NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:#"POST" URLString:imagePostUrl parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileData:imageData name:#"image" fileName:imageName mimeType:#"image/jpeg"];
}];
AFHTTPRequestOperation *op = [manager HTTPRequestOperationWithRequest:request success: ^(AFHTTPRequestOperation *operation, id responseObject) {
DLog(#"response: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
DLog(#"Error: %#", error);
}];
op.responseSerializer = [AFHTTPResponseSerializer serializer];
[[NSOperationQueue mainQueue] addOperation:op];
}
If JSON response is needed use:
op.responseSerializer = [AFJSONResponseSerializer serializer];
instead of
op.responseSerializer = [AFHTTPResponseSerializer serializer];