2

I'm learning how to create a Pomodoro app, and am able to send notifications. However, I am totally clueless as to how to allow my timer label to update itself on reloading the app. Which means the timer works only when the app is open and not when it's in the foreground/background. Hoping to find a tutorial to learn from or just a quick answer code. Thanks!

Edit: Just to clear some misunderstandings, my app's Notification works fine with the timer, for example if 30mins is selected, the app would notify the user after 30mins. However, the problem is that when the app reopens, it resumes for example 29:57 seconds left on the timer label while the 30mins should have passed already.

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

What someone suggests from a different thread is cancel the timer and store a NSDate when the app goes to the background. He stated we can use this notification to detect the app going to the background:

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

Then cancel the timer and store the date:

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

} Use this notification to detect the user coming back:

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

Then calculate the difference from the stored date to the current date, update your counter and start the timer again:

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

However, I do not fully understand this code (namely, the difference between the "handler" and my own "seconds") as am new to programming... Hoping for an answer or helpful insight.


Solved: I managed to solve it myself from this video https://www.youtube.com/watch?v=V6ta24iBNBQ Using this concept of timeDifference as well as UserDefaults.standard.set.... I managed to adapt it to my personal app with the code

Cœur
  • 37,241
  • 25
  • 195
  • 267
  • This is a similar thread: [link](https://stackoverflow.com/questions/31862394/continue-countdown-timer-when-app-is-running-in-background-suspended) and it talks about how I should stop the timer and save it, then calculate the difference when app relaunches. However, I am not sure how to do it as the code is different, where my code is "let timer = Timer()" –  Nov 10 '17 at 12:49
  • `Timer()` is just the new name for `NSTimer()` in Swift. There's no important difference. The question you link is what you need. When you go into the background, save what time it is and stop your time. When you come back into the foreground, calculate the difference between when you left and now and adjust your timer accordingly, then restart it. That's the whole thing. – Rob Napier Nov 10 '17 at 15:00
  • I'm current having an error, as I'm trying to save the seconds instead of the timer. –  Nov 11 '17 at 09:06

1 Answers1

-2

You can call Timer to run the timmer when the view loads.

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()
}
Subrat Padhi
  • 128
  • 11