Swift how to use NSTimer background?

孤街醉人 提交于 2019-11-27 21:39:50
garetmckinley

You can use beginBackgroundTaskWithExpirationHandler to get some background execution time.

class ViewController: UIViewController {
    var backgroundTaskIdentifier: UIBackgroundTaskIdentifier?

    override func viewDidLoad() {
        super.viewDidLoad()
        backgroundTaskIdentifier = UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler({
            UIApplication.sharedApplication().endBackgroundTask(self.backgroundTaskIdentifier!)
        })
        var timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "update", userInfo: nil, repeats: true)
    }

    func update() {
        println("Something cool")
    }
}

Swift 3.0

backgroundTaskIdentifier = UIApplication.shared.beginBackgroundTask(expirationHandler: {
    UIApplication.shared.endBackgroundTask(self.backgroundTaskIdentifier!)
})

This code was inspired by this answer, but I ported to swift.

This apparently only runs for 3 minutes on iOS 7+.

I'm willing to bet that you don't need to run a timer in the background, what you need is to know the time that has elapsed while you were suspended. That is a much better use of your resources than trying to play an empty sound file.

Use applicationWillResignActive and applicationDidBecomeActive to determine how much time has elapsed. First save the fireDate of your timer and invalidate it in applicationWillResignActive

func applicationWillResignActive(application: UIApplication) {
    guard let t = self.timer else { return }
    nextFireDate = t.fireDate
    t.invalidate()
}

Next, determine how much time is left for the timer in applicationDidBecomeActive by comparing the time now to the fireDate you saved in the applicationWillResignActive call:

func applicationDidBecomeActive(application: UIApplication) {
    guard let n = nextFireDate else { return }
    let howMuchLonger = n.timeIntervalSinceDate(NSDate())
    if howMuchLonger < 0 {
        print("Should have already fired \(howMuchLonger) seconds ago")
        target!.performSelector(selector!)
    } else {
        print("should fire in \(howMuchLonger) seconds")
        NSTimer.scheduledTimerWithTimeInterval(howMuchLonger, target: target!, selector: selector!, userInfo: nil, repeats: false)
    }
}

If you need a repeating one, just do math to figure out how many times the timer should have fired while in the background

let howManyTimes = abs(howMuchLonger) / repeatInterval

when I tapped the home button and make my app run background

No, that's a false assumption. When you tap the home button, you do not make your app run in the background. You make your app suspend in the background. Your code does not run when you are in the background.

Apps can get special permission to run in the background just in order to perform certain limited activities, like continuing to play music or continuing to use Core Location. But your app does none of those things, so it goes into the background and stops.

add this code in appdelegate for run a task in background , its working finely,

var backgroundUpdateTask: UIBackgroundTaskIdentifier = 0

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    return true
}

func applicationWillResignActive(application: UIApplication) {
    self.backgroundUpdateTask = UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler({
        self.endBackgroundUpdateTask()
    })
}

func endBackgroundUpdateTask() {
    UIApplication.sharedApplication().endBackgroundTask(self.backgroundUpdateTask)
    self.backgroundUpdateTask = UIBackgroundTaskInvalid
}

func applicationWillEnterForeground(application: UIApplication) {
    self.endBackgroundUpdateTask()
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!