当应用程序在iOS上进入后台时继续操作

当应用程序在iOS上进入后台时继续操作,ios,background-process,nsoperation,Ios,Background Process,Nsoperation,在我的应用程序中,我有一些操作,从在线数据库更新一些核心数据元素,有时更新需要几分钟,当iPhone屏幕锁定时,应用程序进入后台模式,并且此更新停止,因此我必须重新打开应用程序以继续更新,因此,我对堆栈溢出进行了大量搜索,并找到了以下信息: beginBackgroundTaskWithExpirationHandler 这是苹果公司的一种方法,在应用程序处于后台模式时也可以继续执行某些任务,我已经做到了: - (void)applicationDidEnterBackground:(UIAp

在我的应用程序中,我有一些操作,从在线数据库更新一些核心数据元素,有时更新需要几分钟,当iPhone屏幕锁定时,应用程序进入后台模式,并且此更新停止,因此我必须重新打开应用程序以继续更新,因此,我对堆栈溢出进行了大量搜索,并找到了以下信息:

beginBackgroundTaskWithExpirationHandler
这是苹果公司的一种方法,在应用程序处于后台模式时也可以继续执行某些任务,我已经做到了:

- (void)applicationDidEnterBackground:(UIApplication *)application
{

UIApplication  *app = [UIApplication sharedApplication];
UIBackgroundTaskIdentifier bgTask;

bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
    [app endBackgroundTask:bgTask];
}];
}
现在应用程序在后台继续执行任务,看起来一切正常,所以我的问题是,我使用的这种方法安全吗?还是有更好的模式


谢谢

你不是这样做的。要在后台运行的任何代码都必须正确包装。大概是这样的:

- (void)someMethodToKeepRunningInBackground {
    UIBackgroundTaskIdentifier taskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^(void) {
        // Uh-oh - we took too long. Stop task.
    }];

    // Perform task here        

    if (taskId != UIBackgroundTaskInvalid) {
        [[UIApplication sharedApplication] endBackgroundTask:taskId];
    }
}
uiapplicationelegate applicationidentinterbackground:
方法中不执行任何操作

当应用程序进入后台时,任何包装在“后台任务”调用中的任务都将被允许继续运行

这是真正重要的部分-任务最多只能完成10分钟。如果10分钟后仍在运行,您的应用程序将被终止。在应用程序不干净地终止之前,过期处理程序会给您几秒钟的时间来干净地结束任务。

Swift 5 在我的例子中,当应用程序进入后台时,我必须点击服务到后端。我是这样做的:

在AppDelegate中
是的,我在网上搜索,我以为解决方案是你刚刚写的,但我在问题中写的代码是有效的,我不知道怎么做,但如果我开始更新,然后按下home按钮,几分钟后打开应用程序,更新就正确完成了,你是怎么解释的?你发布的代码是有效的,但这是在浪费资源。如前所述,您的代码告诉操作系统,每次应用程序进入后台时,都应该给它10分钟的时间在后台保持活动状态。当时间用完时,您告诉操作系统停止后台活动。因此,你的应用程序每次进入后台都会在后台处于活动状态10分钟,而不管它实际需要多少时间来完成它的过程。在此期间,您的应用程序不必要地从其他应用程序中占用资源。这是可行的,但这是一种糟糕的方法。好吧,现在我明白了,谢谢,所以在我想要的代码的每一部分(不一定在dienterbackground方法中),我都使用您在解决方案中编写的代码,并且我必须在//Perferom任务和if(taskId!=UIBackgroundTaskInvalid)之间以bacgkround模式编写代码……对吗?对。您可以创建一个接受块参数的帮助器方法。然后执行块,其中显示
//Perform task here
。我必须调用如下内容:CheckForUpdate*checkUpdate=[[CheckForUpdate alloc]init];[sectionCheckUpdateQueue添加操作:checkUpdate];其中CheckForUpdate是一个NSOperation,该检查用于更新,如果发现某个更新,则创建另一个NSOperation,我可以在//此处执行任务后写下这两行?或者我必须写一个区块?检查张贴在这里的答案。。
func applicationDidEnterBackground(_ application: UIApplication)
{
    saveUserSession()
} 

// MARK: - Background Tasks

extension AppDelegate
{
    func saveUserSession()
    {
        var backgroundTask: UIBackgroundTaskIdentifier = .invalid

        // 1. request some time to execute task in background

        backgroundTask = UIApplication.shared.beginBackgroundTask {

            guard backgroundTask != .invalid else { return }

            // time is out, stop our background task or app will be killed
            // my background task is called through `Alamofire` 
            // so I stop all requests when time is out

            Alamofire.Session.default.cancelAllRequests() 
        }

        // 2. start the background task

        // the following line (singleton class) calls backend service through `Alamofire`
     
        UserSessionManager.shared.end {

            // when finishing service, mark background task as done

            UIApplication.shared.endBackgroundTask(backgroundTask)
            backgroundTask = .invalid
        }
    }
}