Swift:计时器在前景/后台运行

时间:2017-11-10 09:42:24

标签: ios swift timer countdown background-foreground

我正在学习如何创建Pomodoro应用,并能够发送通知。但是,我完全不知道如何允许我的计时器标签在重新加载应用程序时更新自己。这意味着计时器仅在应用程序打开时工作,而不是在前景/后台时工作。希望找到一个可以学习的教程,或者只是快速回答代码。谢谢!

编辑:为了清除一些误解,我的应用程序的通知可以正常使用计时器,例如,如果选择30分钟,应用程序将在30分钟后通知用户。然而,问题在于,当应用程序重新打开时,它会恢复,例如计时器标签上还剩29分57秒,而30分钟已经过去了。

*Added in AppDelegate*
var seconds = 0 //Timer countdown seconds
var currentDate = NSDate()
var setDate: Int = 0

func pauseApp(){
    viewC.timer.invalidate() //invalidate timer
    UserDefaults.standard.set(seconds, forKey: "current") //error occurs here where "Cannot assign value of type NSDate to type Timer"
    setDate = UserDefaults.standard.integer(forKey: "current")
}
func startApp(){
    let difference = currentDate.timeIntervalSince(NSDate() as Date) as Double
    seconds = Int(Double(setDate) - difference)
    viewC.updateTimer()
}

有人在不同的帖子中建议取消计时器并在应用程序进入后台时存储NSDate。他说我们可以使用此通知来检测应用程序到后台:

NSNotificationCenter.defaultCenter().addObserver(self, selector: "pauseApp", name: UIApplicationDidEnterBackgroundNotification, object: nil)

然后取消计时器并存储日期:

func pauseApp(){
self.stop() //invalidate timer
self.currentBackgroundDate = NSDate()

} 使用此通知检测用户是否会回来:

 NSNotificationCenter.defaultCenter().addObserver(self, selector: "startApp", name: UIApplicationDidBecomeActiveNotification, object: nil)

然后计算从存储日期到当前日期的差异,更新计数器并再次启动计时器:

func startApp(){
let difference = self.currentBackgroundDate.timeIntervalSinceDate(NSDate())
self.handler(difference) //update difference
self.start() //start timer }

然而,我并不完全理解这段代码(即“处理程序”和我自己的“秒”之间的区别),因为我是编程新手......希望得到答案或有用的见解。

解决:我设法通过此视频https://www.youtube.com/watch?v=V6ta24iBNBQ自行解决 使用timeDifference的概念以及UserDefaults.standard.set .... 我设法使用代码

将其改编为我的个人app

1 个答案:

答案 0 :(得分:-2)

您可以在视图加载时调用计时器来运行timmer。

var runTimer : Timer?

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    runTimer = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(myFun), userInfo: nil, repeats: true)
}

func myFun(){
 //do your logic
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    runTimer?.invalidate()
}