【问题标题】:upload file use uploadTaskWithRequest:fromFile: in background and use multipart/form-data上传文件使用 uploadTaskWithRequest:fromFile: 在后台并使用 multipart/form-data
【发布时间】:2016-12-12 14:29:39
【问题描述】:

情况如下:

  1. 我的服务器只接受 multipart/form-data 上传操作。
  2. 我的应用需要实现后台上传

我在下面尝试过:

  1. 如果我忽略background,我可以使用uploadTaskWithRequest:fromData:,构建所有边界、内容配置和文件数据,然后上传到支持的服务器。我确实成功地做到了这一点。 BUT我需要使用后台传输。

  2. 如果我在后台模式下强制使用此方法,则会出现错误:Upload tasks from NSData are not supported in background sessions.

  3. 1234563不是我需要的。

那么有什么办法可以做到这一点吗?由于服务器无法更改它的支持,我需要后台传输和 multipart/form-data 内容类型。

【问题讨论】:

  • 第三点可能表明您的表单数据中存在语法错误。您是否尝试过使用curlnc 等命令行工具上传这些数据?
  • @macmoonshine 问题是,我使用fromData 方法成功上传了我的文件,我通过代码生成了所有多部分数据。并使用fromFile方法,你不需要生成数据,那我为什么要测试这个data或者我怎么测试data。我记录了请求,fromFile 方法甚至没有发送任何正文数据、正文流和内容长度,那么,为什么这个方法存在......或者应该通过代码构建一些其他的东西?文档或演示在哪里?...
  • 该文件应该包含您的表单数据,您应该使用curl 测试这个文件。很抱歉造成混乱。
  • @macmoonshine 谢谢,但这似乎是 NSURLSession 的错误,我通过使用 AF 方便的方法将上传文件写入临时文件来解决这个问题。 see

标签: objective-c multipartform-data background-task


【解决方案1】:

最后,我发现这是一个 NSURLSession 错误,从这个issue,我找到了一种使用fromFile 方法成功上传文件的方法(并且许多 SO 答案已经使用了该方法,但它仍然没有显示在 AFNetworking 的文档中。

您只需将文件写入临时文件,并使用 AF 的便捷方法构建 multipart 部分。后端原因你可以自己找出来,这是我的代码

    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];
}];

【讨论】:

  • 我们还需要在appdelegate handleEventsForBackgroundURLSession 中编写代码来完成这个请求,对吗?
  • @iChirag 这是背景问题,而不是上传错误。你仍然会自己做这个功能需要的所有事情。
  • @walker,我尝试使用您的解决方案,但在写入StreamContentsToFile 时出错。你能分享我文件上传的完整代码吗?
猜你喜欢
  • 2015-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-01
  • 2016-12-14
相关资源
最近更新 更多