1
votes

How do you implement an upload file from disk with additional information (in my case caption & channel_id) using AFNetworking 3.0 uploadTaskWithRequest:fromFile:progress:completionHandler to take advantage of the new background session uploading?

I'm open to alternative solution if it works with AFNetworking and the background file uploading.

Here's what I've tried which the server responds with 400 bad request or 500 internal processing error (doing a multipart form post in cURL works):

@property (nonatomic, strong) AFURLSessionManager *uploadSession;

// Configured uploadSession as backgroundSession configuration with couple of headers

- (void)uploadMediafileFilename:(NSString *)filename
               filenameWithPath:(NSString *)filenameWithPath
                       progress:(void ( ^ ) ( NSProgress *uploadProgress ))progress
                        caption:(NSString *)caption
                        channel:(NSString *)channelId
              completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionBlock {

// ---------
// Create Request Method #1

   NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@%@/", kAPIBaseURL, kAPIMediafilesURL]]];

// Tried dictionary to JSON in body. Also tried a params string version.

   NSDictionary *dict = @{ @"channel_id" : channelId,
                            @"mediafile" : @{ @"filename" : filename, @"caption" : caption } };

   request.HTTPBody = [NSKeyedArchiver archivedDataWithRootObject:dict];
   request.HTTPMethod = @"POST";


// ---- OR ----
// Create Request Method #2

   NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:[NSString stringWithFormat:@"%@%@", kAPIBaseURL, kAPIMediafilesURL] parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
        [formData appendPartWithFormData:[caption dataUsingEncoding:NSUTF8StringEncoding] name:@"mediafile[caption]"];
        [formData appendPartWithFormData:[channelId dataUsingEncoding:NSUTF8StringEncoding] name:@"channel_id"];
        [formData appendPartWithFileURL:fileURL name:@"mediafile[filename]" fileName:filename mimeType:@"image/jpeg" error:nil];
    } error:nil];

// ----------

   NSURL *fileURL = [NSURL fileURLWithPath:filenameWithPath];
  [request setValue:[self token] forHTTPHeaderField:kTokenHeaderField];


// Tried using uploadTaskWithRequest - prefer due to its background capabilities. Also tried uploadTaskWithStreamedRequest.

  NSURLSessionUploadTask *uploadTask = [self.uploadSession uploadTaskWithRequest:request fromFile:fileURL progress:progress completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {

        if (error) {
            NSLog(@"%@", [response description]);
        }

        if (completionBlock) {
            completionBlock(response, responseObject, error);
        }
    }];
    [uploadTask resume];
}
1
I think that happen due to wrong parameter pass into the API calling for file uploading - Hitesh Surani
I think so too... so what's the correct way to get the params correctly? Any light you can shed on how the above methods encode params with files into a request will help me to debug it. - HM1
Dear we can show only our URL and Data send with it - Hitesh Surani
Please contact your API Developer investigate about parameter - Hitesh Surani
The API works, the issue is in getting AFNetworking and iOS to package the request in the same way as a cURL command does. - HM1

1 Answers

1
votes

I got this to work using the following:

  1. Configure the AFURLSessionManager *uploadSession as a defaultSessionConfiguration.
  2. Setup the NSMutableURLRequest using method #2 above.
  3. Use AFNetworking's uploadTaskWithStreamedRequest:progress:completionHandler:

Bottomline: backgroundSessionConfiguration does not work with streamed multi-part form and I could not get additional data to be included with uploadTaskWithRequest:fromFile:.