Hi
If developing a app at times you are required to upload files. As i got stuck many times so i thought about writing most common way of uploading.
UpDate for AFNetworking 3.0
AFNetworking 3.0 is NSURLSession based.
NSMutableURLRequest *upload_request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:@"<path_URL>" parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) { [formData appendPartWithFileData:data name:@"upload_file" fileName:@"<your_filename>" mimeType:@"text/plain"] // you file to upload /*appendPartWithFileURL used if you want to upload large saved files and not data*/ } error:nil]; AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; NSURLSessionUploadTask *uploadFileTask; uploadFileTask = [manager uploadTaskWithStreamedRequest:upload_request progress:^(NSProgress * _Nonnull uploadProgress) { dispatch_async(dispatch_get_main_queue(), ^{ //since the call back is not on main queue we get the main queue ourself NSLog(@"%d",uploadProgress.fractionCompleted);//Log the progress or pass it to progressview }); } completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) { if (error) { NSLog(@"OOPS!!!! %@", error); } else { NSLog(@"%@ %@", response, responseObject); } }]; [uploadFileTask resume];
LATEST SWIFT INTERVIEW QUESTION
If you get ” Transport security has blocked clear text” Error you can read all about App Transport Security from here
UpDate For AFHTTPSessionManager
_WEAKREF(self); AFHTTPSessionManager *manager2 = [AFHTTPSessionManager manager]; manager2.requestSerializer = [AFHTTPRequestSerializer serializer]; [ manager2.requestSerializer setValue:@"multipart/form-data; boundary=0484d4db-ff8e-4ea4-a401-4589fd5a16a7" forHTTPHeaderField:@"Content-Type"]; [ manager2.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Accept"]; [ manager2.requestSerializer setValue:@"gzip" forHTTPHeaderField:@"Accept-Encoding"]; manager2.responseSerializer = [AFHTTPResponseSerializer serializer]; manager2.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"application/hal+json"]; [manager2 POST:@"http://path" parameters:idVal constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) { _STRONGREF(strongSelf); //for loop is for multiple images for (NSUInteger i=0;i<strongSelf->arrayOfFiles.count;i++) { NSString *path= <your path> NSString *name=[NSString stringWithFormat:@"images[%d]",(uint)i]; //using appending with file URL to upload from memory [formData appendPartWithFileURL:[NSURL fileURLWithPath:path] name:name fileName:[strongSelf-> arrayOfFiles objectAtIndex:i] mimeType:@"image/png" error:nil];// } } progress:^(NSProgress * _Nonnull uploadProgress) { dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"Error: %@", uploadProgress); }); } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { NSLog(@"%@ ", responseObject); } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { NSLog(@"Error: %@", error); }];
In the above code _WEAKREF(self); and _STRONGREF(strongSelf); are macros to pass weak ref of self inside block
Prerequisites :-
1. Get latest AFNetworking library Link
Suggestion:- I very strongly recommend that you first check the post service using a good REST client from Firefox or Chrome. You don’t want to bang your head over a nonworking API.
Now once you have tested your API using any REST client i suppose you have
1. Base URL e.g http:// <your domain>.com
2.Path eg /first/second
3.Header field key value pair e.g. “Source” : “web”
4.Parameter key value pair e.g. “action_name” :”postimage”
now here is a simple function just go through it and understand.
-(void)call { //the image name is Denise.jpg i have used image you can use any file //just convert it to NSData in an appropriate way UIImage *image= [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Denise" ofType:@"jpg"]]; // getting data from image NSData *photoData= UIImagePNGRepresentation(image); // making AFHttpClient AFHTTPClient *client= [AFHTTPClient clientWithBaseURL:[NSURL URLWithString:@"http://<your domain>.com/"]]; //setting headers [client setDefaultHeader:@"multipart/form-data; charset=utf-8; boundary=0xKhTmLbOuNdArY" value:@"Content-Type"]; [client setDefaultHeader:@"source" value:@"web"]; NSMutableURLRequest *request1 = [client multipartFormRequestWithMethod:@"POST" path:@"application/uploadfile" parameters:nil constructingBodyWithBlock: ^(id <AFMultipartFormData>formData) { //setting body [formData appendPartWithFormData:[[NSString stringWithFormat:@"signup"] dataUsingEncoding:NSUTF8StringEncoding] name:@"action_name"]; [formData appendPartWithFormData:[[NSString stringWithFormat:@"28"] dataUsingEncoding:NSUTF8StringEncoding] name:@"id"]; [formData appendPartWithFileData:photoData name:@"file_data" fileName:@"file.png" mimeType:@"image/png"]; }]; [request1 setTimeoutInterval:180]; AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request1]; [operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) { NSLog(@"Sent %lld of %lld bytes", totalBytesWritten, totalBytesExpectedToWrite); float progress = totalBytesWritten / (float)totalBytesExpectedToWrite; // use this float value to set progress bar. }]; [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { NSDictionary *jsons = [NSJSONSerialization JSONObjectWithData:responseObject options:kNilOptions error:nil]; NSLog(@"%@",responseObject); NSLog(@"response headers: %@", [[operation response] allHeaderFields]); NSLog(@"response: %@",jsons); } failure:^(AFHTTPRequestOperation *operation, NSError *error) { if([operation.response statusCode] == 403) { NSLog(@"Upload Failed"); return; } NSLog(@"error: %@", [error debugDescription]); }]; [operation start]; }
USING :-AFHTTPRequestOperationManager
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; manager.requestSerializer=[AFJSONRequestSerializer serializer]; NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=0xKhTmLbOuNdArY"]; [manager.requestSerializer setValue:contentType forHTTPHeaderField:@"Content-Type"]; [manager.requestSerializer setValue:<your value> forHTTPHeaderField:<header feild>]; [manager POST:<URL STRING>parameters:@{<dictionary of parameters>} constructingBodyWithBlock:^(id<AFMultipartFormData> formData) { _STRONGREF(strongSelf); NSString *name=<file name>; [formData appendPartWithFileURL:<file path document directory/you can also used data directly> name:name fileName:fileName mimeType:@"image/png" error:nil];} success:^(AFHTTPRequestOperation *operation, id responseObject) {} failure:^(AFHTTPRequestOperation *operation, NSError *error) { }];