10

我一直在开发一个应用程序,用户可以在其中录制视频AVFoundation并发送到服务器,视频的最大大小为 15M,具体取决于互联网速度和类型,将视频传输到服务器大约需要 1 到 5 分钟. 我正在后台线程中将录制的视频传输到服务器,以便用户可以在将视频上传到服务器时继续应用程序上的其他内容。

在阅读 Apple Docs 以在后台实现长时间运行的任务时,我看到只有少数几种应用程序被允许在后台执行。
例如

音频——应用程序在后台向用户播放可听内容。(此内容包括使用 AirPlay 的流式音频或视频内容。)

它是否也使我的应用程序有资格在后台运行任务?或者我需要在主线程上传输视频?

4

3 回答 3

13

NSOperationQueue是执行多线程任务以避免阻塞主线程的推荐方式。后台线程用于您希望在应用程序处于非活动状态时执行的任务,例如 GPS 指示或音频流。

如果您的应用程序在前台运行,则根本不需要后台线程。

对于简单的任务,您可以使用块向队列添加操作:

NSOperationQueue* operationQueue = [[NSOperationQueue alloc] init];
[operationQueue addOperationWithBlock:^{
    // Perform long-running tasks without blocking main thread
}];

有关NSOperationQueue以及如何使用它的更多信息。

上传过程将在后台继续,但您的应用程序将有资格被暂停,因此上传可能会取消。为避免这种情况,您可以在应用程序委托中添加以下代码,以告知操作系统应用程序何时准备好挂起:

- (void)applicationWillResignActive:(UIApplication *)application {
    bgTask = [application beginBackgroundTaskWithExpirationHandler:^{

      // Wait until the pending operations finish
      [operationQueue waitUntilAllOperationsAreFinished];

      [application endBackgroundTask: bgTask];
      bgTask = UIBackgroundTaskInvalid;
    }]; 
}
于 2013-03-07T10:36:19.203 回答
5

根据您对 Dwayne 的回复,您不需要能够在后台模式下下载。相反,您需要在主线程旁边的另一个线程(后台线程)中进行下载。GCD 是这样的:

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//        Do you download here...
    });
于 2013-03-07T11:49:50.410 回答
4

您的要求有资格在后台运行。您不需要注册 info plist 中支持的任何后台模式。您需要做的就是,当应用程序即将进入后台时,使用后台任务处理程序请求额外的时间并在该块中执行您的任务。确保在 10 分钟之前停止处理程序,以免操作系统强制终止。

您可以使用 Apple 提供的以下代码。

- (void)applicationDidEnterBackground:(UIApplication *)application
{
bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
    // Clean up any unfinished task business by marking where you
    // stopped or ending the task outright.
    [application endBackgroundTask:bgTask];
    bgTask = UIBackgroundTaskInvalid;
}];

// Start the long-running task and return immediately.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    // Do the work associated with the task, preferably in chunks.

    [application endBackgroundTask:bgTask];
    bgTask = UIBackgroundTaskInvalid;
});}
于 2013-03-07T10:42:59.043 回答