Swift如何使用NSTimer背景?

时间:2015-01-12 03:20:42

标签: ios swift background ios-simulator nstimer

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        var timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector:    Selector("update"), userInfo: nil, repeats: true)
    }

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

对模拟器来说没关系,我会通过点击主页按钮获得连续的“Something cool”。但是当我用我的iPhone调试应用程序时,它就解决了。当我点击主页按钮并使我的应用程序运行背景时,我没有得到任何东西。 有人告诉我,我可以播放一段很长的空白音乐,让我的应用程序在后台运行。但我不知道如何用快速的@matt在后台播放音乐

4 个答案:

答案 0 :(得分:19)

您可以使用beginBackgroundTaskWithExpirationHandler获取一些后台执行时间。

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 answer,但我移植到了swift。

这显然只能在iOS 7 +上运行3分钟。

答案 1 :(得分:7)

我愿意打赌你不需要在后台运行计时器,你需要知道你被暂停时已经过去的时间。这比使用空声音文件更好地利用您的资源。

使用applicationWillResignActiveapplicationDidBecomeActive确定已经过了多长时间。首先保存计时器的fireDate,并在applicationWillResignActive

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

接下来,通过将现在的时间与您在applicationDidBecomeActive电话中保存的fireDate进行比较,确定applicationWillResignActive中的计时器剩余时间:

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

如果你需要一个重复的,只需做数学计算定时器应该在后台触发的次数

let howManyTimes = abs(howMuchLonger) / repeatInterval

答案 2 :(得分:3)

  

当我点按主页按钮并让我的应用运行背景

不,这是一个错误的假设。当您点按主屏幕按钮时,您让您的应用在后台运行。您可以在后台将应用暂停。当您在后台时,您的代码无法运行

应用可以获得在后台运行的特殊权限,以便执行某些有限的活动,例如继续播放音乐或继续使用核心位置。但是你的应用程序没有做任何事情,因此它会进入后台并停止。

答案 3 :(得分:0)

将此代码添加到appdelegate中,以便在后台运行任务,其工作正常,

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