在后台IOS中实现长时间运行的任务

时间:2013-03-07 10:28:03

标签: ios avfoundation

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

在阅读implementing long running tasks in backround的Apple文档时,我发现只允许几种应用在后台执行。
e.g。

  

audio-该应用程序在后台播放用户的可听内容。 (此内容包括使用AirPlay播放音频或视频内容。)

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

3 个答案:

答案 0 :(得分:13)

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

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

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

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

有关NSOperationQueuehow to use it的更多信息。

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

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

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

      [application endBackgroundTask: bgTask];
      bgTask = UIBackgroundTaskInvalid;
    }]; 
}

答案 1 :(得分:5)

根据您对Dwayne的回复,您无需在后台模式下载。而你需要的是在主线程旁边的另一个线程(后台线程)中进行下载。对于GCD来说是这样的:

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//        Do you download here...
    });

答案 2 :(得分:4)

您的要求有资格在后台运行。您无需注册信息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;
});}