I want to upload multiple images using AFNetworking.
like this Please Check This Image
i have attached example of the postman.
My Code :
NSString *key = [[mediaInfo allKeys] objectAtIndex:0];
NSDictionary *dict = [[mediaInfo objectForKey:key] objectAtIndex:0];
UIImage *image = [dict objectForKey:IQMediaImage];
NSMutableDictionary *dictParam = [[NSMutableDictionary alloc] init];
[dictParam setValue:imageData forKey:#"Files"];
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
[manager POST:#BaseURL(#"/MediaUpload") parameters:dictParam progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { }];
AFNetworking 3.0
Check this method from AFURLSessionManager:
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request
fromFile:(NSURL *)fileURL
progress:(void (^)(NSProgress *uploadProgress)) uploadProgressBlock
completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler
Full code implementation:
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *sessionManager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
[[sessionManager uploadTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#BaseURL(#"/MediaUpload")]]
fromFile:[NSURL fileURLWithPath:#"/path/to/uploading_file"]
progress:^(NSProgress * _Nonnull uploadProgress) { }
completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) {
}] resume];
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
[manager.requestSerializer setValue:#"multipart/formĀdata" forHTTPHeaderField:#"Content-Type"];
[manager POST:[NSString stringWithFormat:#"%#/api/1.0/customer/sign-up", DEFAULT_URL] parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
if (userHaveImage == YES) {
[formData appendPartWithFileData:image name:#"img_profile" fileName:#"profileImage.jpg" mimeType:#"image/jpg"];
[formData appendPartWithFormData:image name:#"img_profile"];
}
Then converting image to UTF8 string and sending it in that format.
Related
I am trying to upload a picture on server with Multiparts using AFNetworking. I have tried to make a simple POST request without Image and it works fine. Now, can say that service URL is absolutely fine and there is no issue with server and I can see that image URL that is saved in document directory is also fine and all the other parameters are fine too, because they all are working with simple request. Can anyone find some error in my code? My Code is:
(void)uploadPicture:(NSMutableDictionary *)param
{
NSString *string=[NSString stringWithFormat:#"%#%#",base_url,#"register"];
NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:#"POST" URLString:string parameters:param constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileURL:[NSURL fileURLWithPath:getImagePath] name:#"picture" fileName:getImagePath mimeType:#"image/jpeg" error:nil];
} error:nil];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
AFJSONRequestSerializer *serializer = [AFJSONRequestSerializer serializer];
[serializer setStringEncoding:NSUTF8StringEncoding];
NSURLSessionUploadTask *uploadTask;
uploadTask = [manager
uploadTaskWithStreamedRequest:request
progress:^(NSProgress * _Nonnull uploadProgress) {
// This is not called back on the main queue.
// You are responsible for dispatching to the main queue for UI updates
dispatch_async(dispatch_get_main_queue(), ^{
//Update the progress view
});
}
completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) {
if (error) {
NSLog(#"Error: %#", error);
} else {
NSLog(#"%# %#", response, responseObject);
NSDictionary *dict= [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil];
NSDictionary *dic=responseObject;
NSLog(#"");
}
}];
[uploadTask resume];
}
Try this function :
First Solution
Note : You need to customise as per your need
-(void)getResponeseWithURL:(NSString *)url WithParameter:(NSDictionary *)parameter WithImage:(UIImage *)image ImageArray:(NSMutableArray *)arrImage WithImageParameterName:(NSString *)imagename WithCallback:(void(^)(BOOL success, id responseObject))callback {
NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:#"POST" URLString:[NSString stringWithFormat:#"%#%#",BASEURL,url] parameters:parameter constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
if (image) {
[formData appendPartWithFileData:UIImageJPEGRepresentation(image, 0.8) name:imagename fileName:#"Image.jpg" mimeType:#"image/jpeg"];
}
else if (arrImage){
int i = 1;
for (UIImage *recipeimage in arrImage) {
// this condition for maintain server side coloum format : ex name , name_2 , name_3
[formData appendPartWithFileData:UIImageJPEGRepresentation(recipeimage, 0.8) name:i == 1 ? imagename : [NSString stringWithFormat:#"%#_%d",imagename,i] fileName:#"Image.jpg" mimeType:#"image/jpeg"];
i++;
}
}
}error:nil];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
NSURLSessionUploadTask *uploadTask;
uploadTask = [manager
uploadTaskWithStreamedRequest:request
progress:^(NSProgress * _Nonnull uploadProgress) {
dispatch_async(dispatch_get_main_queue(), ^{
});
}
completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) {
if (error) {
[UtilityClass showAlertWithMessage: #"Please try again" andWithTitle:#"Network Error" WithAlertStyle:AFAlertStyleFailure];
NSLog(#"Error: %#", [[NSString alloc]initWithData:[[error valueForKey:#"userInfo"] valueForKey:#"com.alamofire.serialization.response.error.data"] encoding:NSUTF8StringEncoding]);
[UtilityClass removeActivityIndicator];
callback(NO,nil);
} else {
callback(YES,responseObject);
}
}];
[uploadTask resume];
}
Second
May you have forgot to add ATS in your project plist file so you need to add this .
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
NSString *string=[NSString stringWithFormat:#"%#%#",base_url,#"register"];
#autoreleasepool {
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
[manager POST:strurl
parameters:parameters
constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
NSMutableArray *allKeys = [[imgParameters allKeys] mutableCopy];
for (NSString *key in allKeys) {
id object = [imgParameters objectForKey:key];
int timestamp = [[NSDate date] timeIntervalSince1970];
NSString *str = [[NSString alloc] initWithFormat:#"%d", timestamp];
NSString *ranstrin = [self randomStringWithLength:8];
// if ([key isEqualToString:#"image"]) {
str = [NSString stringWithFormat:#"TestThumb_%d_%#.jpg",
timestamp, ranstrin];
[formData appendPartWithFileData:object
name:key
fileName:str
mimeType:#"image/jpeg"];
}
}
progress:^(NSProgress *_Nonnull uploadProgress) {
}
success:^(NSURLSessionDataTask *_Nonnull task,
id _Nullable responseObject) {
complete(responseObject, nil);
}
failure:^(NSURLSessionDataTask *_Nullable task,
NSError *_Nonnull error) {
complete(nil, error);
}];
i tried like this in webservices.m
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.requestSerializer=[AFHTTPRequestSerializer serializer];
manager.responseSerializer=[AFHTTPResponseSerializer serializer];
manager.responseSerializer.acceptableContentTypes =[NSSet setWithObject:#"text/html"];
[manager POST:meetingupdateurlparams parameters:meetingdictparams progress:nil
success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable
responseObject)
{
NSLog(#"Complete");
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull
error)
{
NSLog(#"Fail %#",error);
}];
i call this service in Viewcontroller.m
NSString *updateMeetingurl=#" url ";
NSDictionary *dictparms=#{ params };
[Servicecall meetingupdate:updateMeetingurl meetingupdatedict:dictparms];
[Servicecall setDelegate:self];
but i am getting error like this
-[AFHTTPSessionManager :parameters:progress:success:failure:] unrecognized selector sent to instance 0x792cfcb0'
*** First throw call stack:
so any one can help in this issuance...thanks in advance..
UPDATE:
I now see where you're doing wrong.
POST:meetingupdateurlparams this part.
Shouldn't you use
POST:meetingupdateurl instead?
I'm not sure which version of AFNetworking you're using.
But it seems like the method signature you're using does not exist.
Try POST:parameters:success:failure: instead of POST:parameters:progress:success:failure.
See the documentation.
I got same error.
It's a issue with Xcode,you should clean build folder(or delete your DerivedData folder,Xcode -> Preferences -> Location -> Locations -> Derived Data).Because Xcode didn't fully clean the older AFNetworking.
Try this USing Afnetworking 3
NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:#"POST" URLString:#"URL"parameters:#{#"paramter":#""} constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
//if you want to pass image file
if (image) {
[formData appendPartWithFileData:UIImageJPEGRepresentation(image, 0.8) name:imagename fileName:#"Image.jpg" mimeType:#"image/jpeg"];
}
}error:nil];
AFURLSessionManager *managers = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
managers.responseSerializer = [AFJSONResponseSerializer serializer];
NSURLSessionUploadTask *uploadTask;
uploadTask = [managers
uploadTaskWithStreamedRequest:request
progress:^(NSProgress * _Nonnull uploadProgress) {
dispatch_async(dispatch_get_main_queue(), ^{
});
}
completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) {
if (error) {
} else {
// here your response
}
}];
[uploadTask resume];
This is how I"m sending the request:
NSString *string = [NSString stringWithFormat:#"%#/API/Upload",BaseURLString];
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
[manager setRequestSerializer:[AFHTTPRequestSerializer serializer]];
[manager setResponseSerializer:[AFHTTPResponseSerializer serializer]];
NSError *error;
manager.responseSerializer.acceptableContentTypes = nil;
for(NSData *eachImage in self.fetchedAtt) {
NSString *mystring = #"786";
NSURLRequest *request = [manager.requestSerializer multipartFormRequestWithMethod:#"POST" URLString:string parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFormData:eachImage name:#"myImage"];
[formData appendPartWithFormData:[mystring dataUsingEncoding:NSUTF8StringEncoding]
name:#"PracticeCode"];
} error:&error];
NSURLSessionDataTask *task = [manager dataTaskWithRequest:request uploadProgress:nil downloadProgress:nil completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) {
if (error) {
NSLog(#"%#", error.localizedDescription);
return;
}
NSLog(#"%#", [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding]);
}];
[task resume];
}
}
Sometimes I get:
{ "Message": "Error writing MIME multipart body part to output
stream." }
//this is a 500 error
and sometimes I get
Request failed: unsupported media type (415)
You are trying to send multiple files in a single multiform request. Multipart doesn't work like this. You will have to make multiple multipart requests with 1 file at a time. So consider you have 20 files. You will create an async task that takes one file at a time, uploads it, and then performs the same function again for the next files.
And if you want to keep the references, you should return the file ids from the backend, and then append all the ids in a single array and send that array as a param in a separate api request to link the files with any object. Hope that makes sense.
Try this Afnetworking 3.0
NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:#"POST" URLString: [NSString stringWithFormat:#"%#/API/Upload",BaseURLString]; parameters:#{#"text":#"name"} constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileData:[NSData dataWithContentsOfURL:[NSURL URLWithString:imageurl]] name:#"bizcard" fileName:#"Businesscard.jpg" mimeType:#"image/jpeg"]; // you file to upload
} error:nil];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
NSURLSessionUploadTask *uploadTask;
uploadTask = [manager
uploadTaskWithStreamedRequest:request
progress:^(NSProgress * _Nonnull uploadProgress) {
dispatch_async(dispatch_get_main_queue(), ^{
});
}
completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) {
if (error) {
NSLog(#"Error: %#", [[NSString alloc]initWithData:[[error valueForKey:#"userInfo"] valueForKey:#"com.alamofire.serialization.response.error.data"] encoding:NSUTF8StringEncoding]);
callback(NO,nil);
[UtilityClass removeActivityIndicator];
} else {
callback(YES,responseObject);
}
}];
[uploadTask resume];
I'm sending multiple images to server using AFMultipartFormData using a for loop to fetch one image at a time:
NSString *string = [NSString stringWithFormat:#"%#/API/Upload",BaseURLString];
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
[manager setRequestSerializer:[AFHTTPRequestSerializer serializer]];
[manager setResponseSerializer:[AFHTTPResponseSerializer serializer]];
NSError *error;
NSString *mystring = #"noName";
//FOR Loop Start
for(NSData *eachImage in dataStringArray) {
NSURLRequest *request = [manager.requestSerializer multipartFormRequestWithMethod:#"POST" URLString:string parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFormData:eachImage name:#"myImage"];
[formData appendPartWithFormData:[mystring dataUsingEncoding:NSUTF8StringEncoding]
name:#"FileName"];
} error:&error];
NSURLSessionDataTask *task = [manager dataTaskWithRequest:request uploadProgress:nil downloadProgress:nil completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) {
if (error) {
NSLog(#"%#", error.localizedDescription);
return;
}
[uploadedImageIDs addObject:[[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding]];
}];
[task resume];
}//for end
[self makeJSON:uploadedImageIDs];
But somehow it calls makeJSON method before. As there are multiple images so I need it to call after the uploading is finished for all images.
Network processing will run by asynchronous so you need to count in network completionHanlder for knowing when all task finished. Like this
NSString *string = [NSString stringWithFormat:#"%#/API/Upload",BaseURLString];
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
[manager setRequestSerializer:[AFHTTPRequestSerializer serializer]];
[manager setResponseSerializer:[AFHTTPResponseSerializer serializer]];
NSError *error;
NSString *mystring = #"noName";
NSInteger count = 0;
//FOR Loop Start
for(NSData *eachImage in dataStringArray) {
NSURLRequest *request = [manager.requestSerializer multipartFormRequestWithMethod:#"POST" URLString:string parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFormData:eachImage name:#"myImage"];
[formData appendPartWithFormData:[mystring dataUsingEncoding:NSUTF8StringEncoding]
name:#"FileName"];
} error:&error];
NSURLSessionDataTask *task = [manager dataTaskWithRequest:request uploadProgress:nil downloadProgress:nil completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) {
count++;
if (error) {
NSLog(#"%#", error.localizedDescription);
} else {
[uploadedImageIDs addObject:[[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding]];
}
if (count == dataStringArray.count) {
[self makeJSON:uploadedImageIDs];
}
}];
[task resume];
}//for end
Hi server that I'm sending data is expecting image as file(jpg) not as NSData. This code works, but server can't recognize NSData as image. Any thoughts how to solve this?
+ (void)signupWithParameters:(NSDictionary *)parameters
andUserHaveImage:(BOOL)userHaveImage
andImage:(NSData *)image
successBlock:(void (^) (NSDictionary *response))successHandler
errorBlock:(void (^) (NSDictionary *error))errorHandler
{
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
[manager.requestSerializer setValue:#"multipart/formĀdata" forHTTPHeaderField:#"Content-Type"];
[manager POST:[NSString stringWithFormat:#"%#/api/1.0/customer/sign-up", DEFAULT_URL] parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
if (userHaveImage == YES) {
//
[formData appendPartWithFileData:image name:#"img_profile" fileName:#"profileImage.jpg" mimeType:#"image/jpg"];
[formData appendPartWithFormData:image name:#"img_profile"];
}
} progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
successHandler(responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
errorHandler(#{});
}];
}
Solved by converting image to UTF8 string and sending it in that format.