walker
walker

Reputation: 767

upload file use uploadTaskWithRequest:fromFile: in background and use multipart/form-data

here is the situation:

  1. my server only accept multipart/form-data upload action.
  2. my app need to implement background upload.

I've tried below:

  1. if I ignore background, I can use uploadTaskWithRequest:fromData:, build all boundary, content-disposition, and file data, then upload to a supported server. and I do successfully have done this. BUT I need to use background transfer.

  2. if I force this method in background mode, I got an error: Upload tasks from NSData are not supported in background sessions.

  3. if I use background mode, and use uploadTaskWithRequest:fromFile:, I got something like 'stream ended unexpectedly' from the server, as this question mentions, the best answer suggest people to use fromData which apparently is not my need.

so is there any way to accomplish this? since the server can't change it's support, I NEED background transportation and multipart/form-data content-type both.

Upvotes: 2

Views: 1474

Answers (1)

walker
walker

Reputation: 767

Finally, I figure out it's a NSURLSession bug, from this issue, I find a way to upload file with fromFile method successfully (and many SO answers used that already, but it's still not shown in AFNetworking's document.

you just need to write your file to a temp file, and use AF's convenient method the build the multipart part. the backend reason you can find out yourself, here's my code

    NSMutableURLRequest *multipartRequest = [[AFHTTPRequestSerializer serializer]
                                     multipartFormRequestWithMethod:@"POST"
                                     URLString:[url absoluteString]
                                     parameters:nil
                                     constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
                                         [formData appendPartWithFileURL:[NSURL URLWithString:filename]
                                                                    name:@"file"
                                                                fileName:short_name
                                                                mimeType:@"application/octet-stream"
                                                                   error:nil];
                                     } error:nil];

[[AFHTTPRequestSerializer serializer] requestWithMultipartFormRequest:multipartRequest writingStreamContentsToFile:[NSURL URLWithString:temp_file_name] completionHandler:^(NSError * _Nullable error) {
NSURLSessionUploadTask *task = [bgsession uploadTaskWithRequest:multipartRequest
                                                       fromFile:[NSURL URLWithString:temp_file_name]
                                              completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
                                                  [[NSFileManager defaultManager] removeItemAtPath:temp_file_name error:nil];
                                                  NSLog(@"=========response=========\n%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
                                              }];
[task resume];
}];

Upvotes: 3

Related Questions