2

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.

Community
  • 1
  • 1
walker
  • 627
  • 1
  • 6
  • 19
  • The third point could indicate to a syntactic error in your form data. Have you tried to upload this data with a command line tool like `curl` or `nc`? – clemens Dec 13 '16 at 07:13
  • @macmoonshine the thing is , I successfully upload my file by use `fromData` method, which I generate all multi-part data by code. and use `fromFile` method, you don't need to generate data, so why should I test this `data` or how could I test the `data`. and I logged the request , the `fromFile` method even didn't send any body-data, body-stream and content-length, so, why does this method exists...or should build some other things by code? where is the doc or demo?... – walker Dec 14 '16 at 07:10
  • The file should contain your form data, and you should test this file with `curl`. Sorry for confusion. – clemens Dec 14 '16 at 08:00
  • @macmoonshine thanks, but it's seems a NSURLSession's bug, I solved this by write upload file to a temp file use a AF's convenient method. [see](https://github.com/AFNetworking/AFNetworking/issues/1874) – walker Dec 15 '16 at 05:56

1 Answers1

3

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];
}];
walker
  • 627
  • 1
  • 6
  • 19
  • we also need to do code in appdelegate handleEventsForBackgroundURLSession too to finish this request, correct? – Chirag Lukhi Apr 05 '17 at 13:19
  • @iChirag that's background thing, not the upload bug. you will still do all things that this feature needs by yourself. – walker Apr 11 '17 at 03:21
  • @walker, i've tried to use your solution but got an error on writingStreamContentsToFile. could you share me full code for file upload ? – gstream Apr 11 '17 at 03:25