Jasdeep Saini
Jasdeep Saini

Reputation: 51

Does AFNetworking V 2 support non streaming multi part background upload tasks?

A project I am working on needs to upload a video. The post API call for uploading a video needs a multipart body. The code I tried to use is included at the bottom of the question.

The code works perfectly for [NSURLSessionConfiguration defaultSessionConfiguration].

If I change the configuration to [NSURLSessionConfiguration backgroundSessionConfiguration:@"Test Id"], the code crashes because background sessions only support file uploads. The error is:

*** Terminating app due to uncaught exception 'NSGenericException', reason: 'Upload tasks in background sessions must be from a file'

All of the multipart append methods that can be used in the following method use the AFMultipartBodyStream class. This class streams the upload so it can not be used in a background session since a stream is not a file.

NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer]
                         multipartFormRequestWithMethod:@"POST"
                         parameters:params
                         constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
                             NSError *error = nil;
                             [formData appendPartWithFileURL:fileURL
                                                        name:@"uploadFile"
                                                    fileName:[fileURL lastPathComponent]
                                                    mimeType:@"video/quicktime"
                                                       error:&error];
                         } error:&error];

Is it possible to have a NSURLSessionUploadTask with a multi part body that can run in a AFHTTPSessionManager that is using a backgroundSessionConfiguration?

See sample code below:

NSURL *APIURL = [NSURL URLWithString:@"https://www.test.com/uploadVideo"];

NSError *error = nil;

NSDictionary *params = @{ @"token" : @"d5bcf6c2-99ec-4de7-bd87-71918b633b3a",
                          @"title" : @"Test_Video" };

NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer]
                         multipartFormRequestWithMethod:@"POST"
                         parameters:params
                         constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
                             NSError *error = nil;
                             [formData appendPartWithFileURL:fileURL
                                                        name:@"uploadFile"
                                                    fileName:filePath
                                                    mimeType:@"video/quicktime"
                                                       error:&error];
                         } error:&error];

[request addValue:@"Basic 12345678901234567890" forHTTPHeaderField:@"Authorization"];

NSLog(@"%@", error);

__weak __typeof(self)weakSelf = self;
__block NSURLSessionUploadTask *task =
[super
 uploadTaskWithStreamedRequest:request
 progress:progress
 completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
     [weakSelf handleCompletionForTask:task
                        responseObject:responseObject
                                 error:error
                               success:successBlock
                               failure:failureBlock];
 }];

[task setTaskDescription:endpoint.name];
[task resume];

Upvotes: 5

Views: 928

Answers (2)

tuttu47
tuttu47

Reputation: 519

I have made this work finally.This is possible by using AFHTTPRequestSerializer:requestWithMultipartFormRequest:writingStreamContentsToFile:completionHandler:. Refer https://github.com/AFNetworking/AFNetworking/issues/1874 - Lansing's answer.

Upvotes: 2

JVillella
JVillella

Reputation: 1030

There are some strict limitations with background NSURLSessions, regardless of AFNetworking. Upload tasks must use [NSURLSession uploadTaskWithRequest:fromFile:] I used Charles to monitor outgoing HTTP requests from this method and noticed it's using application/octet-stream. There is no way to get around this, at least nothing I've come across tinkering with it the past few days.

Upvotes: 6

Related Questions