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.

4
  • 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? Commented Dec 13, 2016 at 7: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?... Commented Dec 14, 2016 at 7:10
  • The file should contain your form data, and you should test this file with curl. Sorry for confusion. Commented Dec 14, 2016 at 8: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 Commented Dec 15, 2016 at 5:56

1 Answer 1

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];
}];
Sign up to request clarification or add additional context in comments.

3 Comments

we also need to do code in appdelegate handleEventsForBackgroundURLSession too to finish this request, correct?
@iChirag that's background thing, not the upload bug. you will still do all things that this feature needs by yourself.
@walker, i've tried to use your solution but got an error on writingStreamContentsToFile. could you share me full code for file upload ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.