Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

can't start beginBackgroundTask swift 3

Sorry I am stuck, but I am trying to start background task (XCode8, swift 3)

Example from here: https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html#//apple_ref/doc/uid/TP40007072-CH4-SW3

In AppDelegate.swift:

func applicationDidEnterBackground(_ application: UIApplication) {
    var bgTask: UIBackgroundTaskIdentifier = 0;
    bgTask = application.beginBackgroundTask(withName:"MyBackgroundTask", expirationHandler: {() -> Void in
        print("The task has started")
        application.endBackgroundTask(bgTask)
        bgTask = UIBackgroundTaskInvalid
    })
}

The app has never shown "The task has started" message. What am I doing wrong?

like image 308
Alex Avatar asked Oct 04 '17 14:10

Alex


2 Answers

Your use of the background task is all wrong.

Waiting for the expiration handler to be called to call endBackgroundTask is poor practice and makes your app waste more resources than it needs. You should tell iOS immediately when your background task is complete.

So you should do something like:

func applicationDidEnterBackground(_ application: UIApplication) {
    var finished = false
    var bgTask: UIBackgroundTaskIdentifier = 0;
    bgTask = application.beginBackgroundTask(withName:"MyBackgroundTask", expirationHandler: {() -> Void in
        // Time is up.
        if bgTask != UIBackgroundTaskInvalid {
            // Do something to stop our background task or the app will be killed
            finished = true
        }
    })

    // Perform your background task here
    print("The task has started")
    while !finished {
        print("Not finished")
        // when done, set finished to true
        // If that doesn't happen in time, the expiration handler will do it for us
    }

    // Indicate that it is complete
    application.endBackgroundTask(bgTask)
    bgTask = UIBackgroundTaskInvalid
}

Also note that you should use beginBackgroundTask/endBackgroundTask around any code in any class that you want to keep running for a short period time even if the app goes into the background.

In this setup if the task isn't finished while the while loop is still working then the expirationHandler is called in parallel on a different thread. You should use the handler to stop your code and allow it to reach the application.endBackgroundTask(bgTask) line.

like image 119
rmaddy Avatar answered Nov 08 '22 15:11

rmaddy


The expiration handler block gets called after a period of time in background (usually 5 minutes or so). This is meant to be used to write the clean up logic if in case you background task is taking a lot of time to complete.

There is nothing wrong with your code, you just need to wait in the background for the background task to expire.

like image 4
Puneet Sharma Avatar answered Nov 08 '22 16:11

Puneet Sharma