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

Posted

技术标签:

【中文标题】在后台IOS实现长时间运行的任务【英文标题】:Implementing long running tasks in background IOS 【发布时间】:2013-03-07 10:28:02 【问题描述】:

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

在阅读implementing long running tasks in backround 的 Apple 文档时,我发现只有少数几种应用程序允许在后台执行。 例如

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

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

【问题讨论】:

ru要在后台上传录制视频吗? 是的,这就是我正在做的事情,因为我提到我希望用户在录制视频时继续在表单上做其他事情 上传时,你的应用会在前台(执行一些其他任务)还是完全进入后台? 只有上传过程在后台进行,所有其他内容都保留在主线程上,用户可以继续在应用程序中添加详细信息 后台运行并不关心您的上传在哪个线程上运行。如果您正在谈论在用户点击主页按钮后继续上传,那么后台任务就是您想要的。如果您正在谈论在前台运行时上传,那么您的意思是在后台线程上。后台线程和后台运行是两个概念。 【参考方案1】:

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

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

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

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

有关NSOperationQueue 和how to use it 的更多信息。

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

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

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

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

【讨论】:

这是否意味着如果用户单击电源按钮,NSOperationQueue 将继续其任务? 查看更新的答案以避免应用在不活动时被暂停。 * 加入NSOperationQueue *operationQueue 在这种情况下什么是 bgTask ?? @jesses.co.tt UIBackgroundTaskIdentifier【参考方案2】:

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

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

【讨论】:

它正在将数据上传到服务器,我担心如果互联网出现故障并在一段时间后变得可用,它会恢复我的任务吗?据我了解,将不得不在 NSOperationQueue 中添加任务,如果它们处于待处理状态,那么可以恢复吗? 在失去与服务器的连接后,您的上传任务是否能够恢复取决于您使用的库是否具有此功能。如果该库不支持该功能,则将任务作为后台任务或在后台线程中运行将无济于事。 哪些库可以恢复,哪些不能?【参考方案3】:

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

【讨论】:

来自 Apple Docs 不清楚,这就是我问的原因,我已经在后台线程中实现了我的上传过程并且我已经在使用多任务,我的问题是它会让我的应用程序如果它已经在后台线程中运行,会被拒绝吗?其次,我的应用程序可以处于活动或非活动状态,这无关紧要,因为它正在后台线程中执行任务。 @nsgulliver 否。Apple 不会拒绝,因为您使用后台处理程序上传。您需要做的就是确保在 10 分钟失败之前停止处理程序,否则应用程序可能会被操作系统强制终止。我已经在一些应用程序中这样做了,我对 Apple 没有任何问题。

以上是关于在后台IOS实现长时间运行的任务的主要内容,如果未能解决你的问题,请参考以下文章

关于ios中后台长时间下载任务的实现与走过的坑

长时间运行的后台任务完成后应用程序未挂起

保持程序在后台长时间运行-b

当应用程序进入后台时,在前台执行的长时间运行的任务被挂起

在后台运行长时间运行的并行任务,同时允许小型异步任务更新前台

带有进度通知的长时间运行的后台任务