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

时间:2012-11-26 23:29:49

标签: ios background-process nsoperation

在我的应用程序中我有一些NSOperation从在线数据库更新一些核心数据元素,有时更新需要一分钟,当iPhone屏幕锁定时,应用程序进入后台模式,此更新停止,所以我必须重新打开应用程序继续更新,所以我已经搜索了很多堆栈溢出,我找到了一些信息:

beginBackgroundTaskWithExpirationHandler

这是一个来自苹果的方法,当应用程序处于后台模式时,让我们继续执行某项任务,并且我已经这样做了:

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

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

bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
    [app endBackgroundTask:bgTask];
}];
}

现在应用程序在后台继续执行任务,似乎一切正常,所以我的问题是,我使用的这种方法是安全的吗?还是有更好的模式?

感谢

2 个答案:

答案 0 :(得分:14)

那不是你怎么做的。您要在后台运行的任何代码都必须正确包装。像这样:

- (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];
    }
}

您不能使用UIApplicationDelegate applicationDidEnterBackground:方法做任何事情。

包含在"后台任务中的任何任务"当应用程序进入后台时,将允许调用继续运行。

这是真正重要的部分 - 任务最多只能达到10分钟。如果它在10分钟后仍在运行,您的应用将被终止。在不正确地终止应用程序之前,到期处理程序会让您在几秒钟内干净地结束任务。

答案 1 :(得分:0)

斯威夫特 5

就我而言,当应用程序进入后台时,我必须点击服务到后端。我是这样做的:

在 AppDelegate 中

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
        }
    }
}