如何在iOS中运行已经运行的任务使用beginBackgroundTaskWithExpirationHandler

Var*_*han 38 iphone background-process ios

在我的应用程序中,我将图像从iPhone上传到服务器.如果用户按下主页按钮同步,App将关闭.

我希望应用程序必须在后台运行,直到同步完成.

我的问题是:如何用" beginBackgroundTaskWithExpirationHandler" 添加当前正在运行的任务?

请分享您的想法.

Rob*_*ier 99

尽管它的名字,beginBackgroundTaskWithExpirationHandler:实际上并没有"开始"任务.它可能更好地被认为是"注册......"而不是"开始......"你只是告诉系统你正在做一些想要完成的事情,如果可以的话.

几点:

  • 在几乎所有情况下,beginBackgroundTaskWithExpirationHandler:当你开始做你想做的事情时,你想要打电话,然后endBackgroundTask:当你完成时.在用户按下Home按钮时,您几乎从不调用这些内容(除非这是您启动任务时的重点,例如将某些内容保存到服务器).

  • 您可以一次打开任意数量的"后台任务".他们什么都不花钱 他们就像保留计数.只要你还有一个打开(一个"开始"没有达到它的"结束"),那么系统会考虑更多时间的请求.调用"开始"和"结束"方法的成本非常低,因此使用这些方法可以将任何需要额外时间的方法包括在内.

  • 无法确定您是否可以完成同步.这些方法只是提出请求.操作系统仍可能拒绝该请求.操作系统可能仍然会在需要一些额外资源时终止您.操作系统不是无限耐心; 如果你花了太长时间(通常大约10分钟),它会在你调用你的到期处理程序之后杀死你.操作系统可能会因为手机被关闭而导致您死亡.您的应用必须能够处理无法完成.操作系统只为您提供此功能,以便您可以改善用户体验.

  • 你的答案非常棒,不仅仅是男人.只有一个更新:从iOS 7开始,你只有3分钟的后台任务,而不是10分钟. (20认同)

Var*_*han 16

我使用下面的代码作为后台任务处理程序

__block UIBackgroundTaskIdentifier backgroundTaskIdentifier = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{

    NSLog(@"Background Time:%f",[[UIApplication sharedApplication] backgroundTimeRemaining]);

    [[UIApplication sharedApplication] endBackgroundTask:backgroundTaskIdentifier];

    backgroundTaskIdentifier = UIBackgroundTaskInvalid;
}];
Run Code Online (Sandbox Code Playgroud)


Joe*_*e M 9

这是我使用beginBackgroundTaskWithExpirationHandler的方法,包括调用后台完成的方法.这包括用于启动新异步任务的代码.所以不完全是问题中的问题.在下面添加代码,认为有人可能正在寻找这种情况:

- (void)didReceiveObjList:(CFDataRef)message
{
  // Received Object List. Processing the list can take a few seconds.
  // So doing it in separate thread with expiration handler to ensure it gets some time to do     the task even if the app goes to background.

  UIApplication *application = [UIApplication sharedApplication];
  __block UIBackgroundTaskIdentifier bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
    [application endBackgroundTask:bgTask];
    bgTask = UIBackgroundTaskInvalid;
}];

  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
      [self processObjList:message];

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

  NSLog(@"Main Thread proceeding...");

}
Run Code Online (Sandbox Code Playgroud)


Duy*_*Hoa 6

看一下这个页面,Apple描述了如何让iOS应用程序在后台处于暂停状态. Apple文档

以下是我实施的内容:

UIBackgroundTaskIdentifier bgTask;

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    NSLog(@"=== DID ENTER BACKGROUND ===");
    bgTask = [[UIApplication  sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
        NSLog(@"End of tolerate time. Application should be suspended now if we do not ask more 'tolerance'");
        // [self askToRunMoreBackgroundTask]; This code seems to be unnecessary. I'll verify it.
    }];

    if (bgTask == UIBackgroundTaskInvalid) {
        NSLog(@"This application does not support background mode");
    } else {
        //if application supports background mode, we'll see this log.
        NSLog(@"Application will continue to run in background");  
    }
}

/*

- (void)askToRunMoreBackgroundTask
{
    [[UIApplication sharedApplication] endBackgroundTask:bgTask];
    NSLog(@"restart background long-running task");
    bgTask = [[UIApplication  sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
        NSLog(@"End of tolerate time. Application should be suspended now if we do not ask more 'tolerance'");
        [self askToRunMoreBackgroundTask]; 
    }];

}

*/

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    NSLog(@"=== GOING BACK FROM IDLE MODE ===");
    //it’s important to stop background task when we do not need it anymore
    [[UIApplication sharedApplication] endBackgroundTask:UIBackgroundTaskInvalid];  
}
Run Code Online (Sandbox Code Playgroud)