iOS 7背景上传和POST请求

3

我需要在后台上传文件,并在每次上传前后进行其他HTTP POST请求。

以前我使用的是beginBackgroundTaskWithExpirationHandler,在iOS 6之前完美运行,但从iOS 7开始仅限于约180秒,这是一个问题。

我已经阅读了关于NSURLSession的文档,其中包括后台传输服务。但是,问题在于它只允许在后台上传和下载,不允许我在后台上传后进行POST请求。

那么有没有办法在后台上传的同时进行POST请求呢?

非常感谢任何指向正确方向的提示。

3个回答

5

我认为你可以使用NSURLSessionDownloadTask发送POST请求。

在我看来,下载任务并不意味着只用于下载,而是指你的POST请求的响应(json/xml)将被下载到本地文件中。然后你可以打开该文件并解析它以获取请求。

如果需要,你甚至可以使用NSURLSessionDownloadTask将文件上传到S3,并将S3响应“下载”到本地文件中。

更多信息,请参见苹果开发者论坛上此问题:https://devforums.apple.com/thread/210515?tstart=0


3

在生产代码中,我成功地完成了一个背景任务回调期间的基本http调用。该回调函数是:

-[id<NSURLSessionTaskDelegate> URLSession:task:didCompleteWithError:]

你只有约30秒的时间来完成所需操作。在此期间进行的任何异步调用都必须在

标签中括起来。
-[UIApplication beginBackgroundTaskWithName:expirationHandler:]

如果你在等待异步进程的过程中从堆栈中弹出时,否则iOS将会杀掉该进程,所以需要使用“end task”版本。

顺便提一下,不要混淆 UIApplication 任务(我称之为“应用程序任务”)和 NSURLSession 任务(“会话任务”)。


不幸的是,当应用程序由后台传输的委托启动时创建后台任务并不会增加您的30秒窗口。 - user361526
2
不过,每个任务都有一个回调函数,它会给你另一个时间增量,在此期间你可以排队更多的任务。因此,你可以将无限数量的任务链接在一起。我已经在生产环境中运行了这个功能,比如可以完全在后台上传1000张照片。 - Clay Bridges
@Clay 没有测试过,但听起来很厉害。你能放一些源代码吗?谢谢。 - Sasho
@Sasho 我已经做了一些,但只是零散的。也许有一天我会在Github上发布完整的内容。与此同时,这里是我回答过的所有NSURLSession问题。 - Clay Bridges
Clay Bridges,你能否向我解释一下你是如何处理的?这个方法也适用于Amazon S3吗? - Xcoder
@Xcoder: 答案 #1:我发现这个问题非常棘手。我的问答是目前为止我所知道的最易于访问的形式。答案 #2:我们正在使用S3来完成这个任务。 - Clay Bridges

0

如果您使用uploadTaskWithRequest:fromData:completionHandler:,则可以通过完成处理程序块从中进行HTTP POST请求:

[backgroundSession uploadTaskWithRequest:request fromData:data completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
    if (httpResponse.statusCode == 200) {
        NSMutableURLRequest *postRequest = [NSMutableURLRequest requestForURL:[NSURL URLWithString:@"http://somethingorother.com/"]];
        request.HTTPMethod = @"POST";
        .
        .
        .
        NSURLResponse *postResponse;
        NSError *postError;
        NSData *postResponseData = [NSURLConnection sendSynchronousRequest:postRequest returningResponse:&postResponse error:&postError]; 
        // Check postResponse and postError to ensure that the POST succeeded
    }
}];

3
这仅适用于前台调用。对于后台任务,我们必须仅使用委托。 - Ekra

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接