File Upload using AFNetworking in iOS application.

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"]];
//&nbsp; 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) {
}];

 


A pat on the back !!