How to upload hundreds of pictures by AFNetworking? - ios

I would like to upload pictures, probably ranging from a few hundred to 1000, originally using AFNetwoking methods, but there is a drawback, it reads all image data one time, then memory is up,for example:
NSOperationQueue *operationQueue = [[NSOperationQueue alloc]init];
[operationQueue setMaxConcurrentOperationCount:1];
for (NSURL *fileURL in filesToUpload) {
NSURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:#"POST"
URLString:#"http://example.com/upload" parameters:nil
constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileURL:fileURL name:#"images[]" error:nil];
}];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operationQueue addOperation:operation];
}
this will read all pictures's data before upload, how can i create a queue reduced memory consumption

Related

Why AFNetworking Eating so many Memory?

When I sent 10000 requests in one second, Xcode showed that this program used 300 MB of memory between the requesting. Even after the request, it cost 190 MB and did not decrease, I do not know why.
This is my code. Forgive my English.
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
for (int i = 1; i <= 10000 ; i ++) {
NSURL *url = [NSURL URLWithString:#"http://www.baidu.com"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc]initWithRequest:request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Success!");
}failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error!%#",error);
}];
[queue addOperation:operation];
usleep(100);
}
10000 is not a little number.
You could use raw socket routine designed for large request,eg, AsyncSelect socket , or Completion socket...

Upload multiple images as file in iOS

In my iOS app I want to upload an image file and some other parameters through API. image file contains multiple images.
You can use custom image pickers like ELCImagePickerController
There is also some other library that can be used..
WSAssetPickerController
QBImagePickerController
These allow you to pick multiple images. let me know how things go
By Using AFNetworking You can upload multiple image as below code, download AFNetworking
Other Parameter :
NSDictionary *parametersAll = #{#"Value": #"Key"};
NSArray *imageArray;
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseUrl: my_url ];
NSMutableRequest *request = [httpClient multipartFormRequestWithMethod:#"POST" path:nil
parameters:parametersAll constructingBodyWithBlock: ^(id <AFMultipartFormData>formData) {
for(UIImage *img in imageArray)
{
[formData appendPartWithFileData: my_imageData name:#"image" fileName:#"myImage.jpg" mimeType:#"image/jpeg"];
}
}];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest: request];
[operation start];

AFNetworking upload image with PUT request?

I'm trying upload image to server using AFNetworking with PUT request.-
UIImage* snap = info[UIImagePickerControllerOriginalImage];
NSData *imageData = UIImageJPEGRepresentation(snap, 0.3);
NSMutableString * fullPath = [NSMutableString stringWithString:API_BASE_URL];
[fullPath appendFormat:#"%#%#",API_VERSION,req];
NSURL * url = [NSURL URLWithString:fullPath];
AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:url];
[manager.requestSerializer setValue:[NSString stringWithFormat:#"%#", #kPublicKey] forHTTPHeaderField:#"X-API-KEY"];
[manager.requestSerializer setValue:bodyStr forHTTPHeaderField:#"X-API-DATA"];
NSString *URLString = fullPath;
NSMutableURLRequest *request = [manager.requestSerializer multipartFormRequestWithMethod:#"PUT" URLString:URLString parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileData:imageData name:#"media" fileName:#"upload.jpg" mimeType:#"image/jpeg"];
} error:nil];
AFHTTPRequestOperation *requestOperation = [manager HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
//success
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"failure...");
}];
[requestOperation start];
I'm taking image using iPhone camera and upload it to server but it takes too much time to process and images uploaded on server are in huge size(~10-12MB) although i'm trying to compress the image?
What i'm doing wrong?Any suggestion or sample code would be appreciated.
NSData *imageData = UIImageJPEGRepresentation(snap, 1.0);
The second argument in UIImageJPEGRepresentation denotes the compression quality of the image.As per Apple documentation :
compressionQuality :
The quality of the resulting JPEG image, expressed as a value from 0.0 to 1.0. The value 0.0 represents the maximum compression (or lowest quality) while the value 1.0 represents the least compression (or best quality).
Try reducing this to a number which balances the quality of image and speed of upload.
// manager needs to be init'd with a valid baseURL
NSURL *baseURL = [AfarHTTPSessionManager sharedManager].baseURL;
AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:baseURL];
NSData *imageData = UIImageJPEGRepresentation(draftHighlight.largeImage, 1);
// need to pass the full URLString instead of just a path like when using 'PUT' or 'POST' convenience methods
NSString *URLString = [NSString stringWithFormat:#"%#%#", baseURL, _the_rest_of_your_path];
NSMutableURLRequest *request = [manager.requestSerializer multipartFormRequestWithMethod:#"PUT" URLString:URLString parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileData:imageData name:kCreateHighlightAPIKeyImage fileName:#"highlight_image.jpg" mimeType:#"image/jpeg"];
}];
// 'PUT' and 'POST' convenience methods auto-run, but HTTPRequestOperationWithRequest just
// sets up the request. you're responsible for firing it.
AFHTTPRequestOperation *requestOperation = [manager HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
// success
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// failure
}];
// fire the request
[requestOperation start];

Can not upload video with multi part POST in AFNETWORKING on iOS

I tried below code to upload video with Multi part form POST in AFnetworking but when uploading, video sent about 80% is broken. This is my code:
-(void) uploadVideoAPI: (NSString*) emailStr andSumOfFiles: (NSString*) sumSizeFile andVideoNams:(NSMutableArray*) videoNameArr andUpFile :(NSMutableArray *) videoDataArray
{
NSURL *url = [NSURL URLWithString:#"http://myserver.com];
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL: url] ;
NSMutableURLRequest *request = [httpClient multipartFormRequestWithMethod:#"POST" path:nil parameters:nil constructingBodyWithBlock:^(id <AFMultipartFormData>formData) {
[formData appendPartWithFormData:[emailStr dataUsingEncoding:NSUTF8StringEncoding]
name:#"emailStr"]; //parametters1
[formData appendPartWithFormData:[sumSizeFile dataUsingEncoding:NSUTF8StringEncoding] name:#"sumSizeFile"];//parametters 2
for(int i=0;i<[videoDataArray count];i++)
{
NSString * videoName = [videoNameArr objectAtIndex:i];
NSData *videoData = [videoDataArray objectAtIndex:i];
[formData appendPartWithFileData:videoData
name:#"videos"
fileName:videoName mimeType:#"video/quicktime"];
}
}];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {
NSLog(#"Sent %lld of %lld bytes", totalBytesWritten, totalBytesExpectedToWrite);
}];
[httpClient enqueueHTTPRequestOperation:operation];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Upload Complete");
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"error: %#", operation.responseString);
NSLog(#"%#",error);
}];
[operation start];
}
My code has any problem? Please give me some advice. thanks in advance
I suggest you to use appendPartWithFileURL instead of appendPartWithFormData for files, to avoid memory problems (imagine big data like video or compressed data files).
I use something like this:
// Create request
NSMutableURLRequest *request = [httpClient multipartFormRequestWithMethod:#"POST" path:nil parameters:nil constructingBodyWithBlock:^(id <AFMultipartFormData>formData) {
// Important!! : file path MUST BE real file path (so -> "file://localhost/.../../file.txt") so i use [NSURL fileURLWithPath:]
NSError* err;
[formData appendPartWithFileURL:[NSURL fileURLWithPath:filePathToUpload] name:[fileInfo objectForKey:#"fileName"] error:&err];
}];

Upload Using AFNetworking

NSURL *url = [NSURL URLWithString:#"http://127.0.0.1:8000/photo/"];
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];
NSDictionary *headers = [NSDictionary dictionaryWithObject:data forKey:#"attachment"];
//NSLog(#"strimng");
NSMutableURLRequest *request = [httpClient multipartFormRequestWithMethod:#"POST" path:#"upload/" parameters:nil constructingBodyWithBlock: ^(id<AFMultipartFormData> formData) {
NSLog(#"strimng");
[formData appendPartWithFileData:data name:#"attachment" fileName:#"attachment.jpg" mimeType:#"image/jpeg"];
NSLog(#"strimng");
}];
NSLog(#"strimng");
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {
NSLog(#"Sent %lld of %lld bytes", totalBytesWritten, totalBytesExpectedToWrite);
}];
[operation start];
I am Trying to upload the image from the iphone using AFNetworking, but this is not working.
The NSLog just before formdata appenddata command is logged out. But the one after that doesnt seem to. I have also checked if NSdata is nil and thats also not the case. And obv the request is not being sent.
Please can anyone help me.
Assuming that you have to upload an image, why are you creating an NSDictionary with the data? It is not necessary, you just need to use data inside multipartFormRequestWithMethod.
Try the following
// Get the image that you want to upload via ImagePicker or a #property
UIImage *imageIWantToUpload = self.image;
// Create the NSData object for the upload process
NSData *dataToUpload = UIImageJPEGRepresentation(imageIWantToUpload, 0.5);
NSMutableURLRequest *request = [httpClient multipartFormRequestWithMethod:#"POST" path:#"upload/" parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileData:dataToUpload name:#"attachment" fileName:#"attachment.jpg" mimeType:#"image/jpg"];
}];
// You can add then the progressBlock and the completionBlock
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setUploadProgressBlock:progress];
[operation setCompletionBlockWithSuccess:success failure:failure];
You should also double check if your server side expects some parameters, because you are setting the NSMutableURLRequest parameters' field to nil.

Resources