I want the timer to run even when I close the application. I want it to work in the background counter. the timer goes back one second when I run it.(counter) How can I do that?
class TimerViewController: UIViewController {
var selectedDay: String?
var seconds =
var timer = Timer()
@IBAction func start(_ sender: AnyObject) {
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(TimerViewController.counter), userInfo: nil, repeats: true)
sliderOutlet.isHidden = true
startOutlet.isHidden = true
}
@objc func counter() {
seconds -= 1
favoriteDayTextField.text = String(seconds) + " Seconds"
var bgTask = UIBackgroundTaskIdentifier(rawValue: seconds)
bgTask = UIApplication.shared.beginBackgroundTask(expirationHandler: {
UIApplication.shared.endBackgroundTask(bgTask)
})
if (seconds == 0) {
timer.invalidate()
if self.button.isOn {
updateState()
} else {
updateState1()
}
}
}
}
I am not clear what you want to achieve. Suppose you want to update the label after the timer has started each 1 second. Then one approach will be:-
In application will terminate save the passed duration and terminated time to calculate remaining time in next launch.
var remainingDuration: TimeInterval!
override func viewDidLoad() {
super.viewDidLoad()
let remainingDurationFromLastLaunch = UserDefaults.standard.object(forKey: "duration") as? TimeInterval ?? 0
let lastTerminatedTime = UserDefaults.standard.object(forKey: "lastTerminatedDate") as? Date ?? Date()
if Date().timeInterval(since: lastTerminatedTime) > remainingDurationFromLastLaunch {
remainingDuration = remainingDurationFromLastLaunch - Date().timeInterval(since: lastTerminatedTime)
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(TimerViewController.counter), userInfo: nil, repeats: true)
NotificationCenter.default.addObserver(self, selector: #selector(TimerViewController.applicationWillTerminate), name: NSNotification.Name.UIApplicationWillTerminate, object: nil)
} else { //Duration is passed....Do whatever you want
}
}
@objc func counter() {
remainingDuration -= 1
if remainingDuration == 0 { //Duration is passed....Do whatever you want
timer.invalidate()
timer = nil
} else {
favoriteDayTextField.text = String(remainingDuration) + " Seconds"
}
}
@objc func applicationWillTerminate() {
if timer != nil {
backgroundTask = UIApplication.shared.beginBackgroundTask { [weak self] in
UserDefaults.standard.set(remainingDuration, forKey: "duration")
UserDefaults.standard.set(Date(), forKey: "lastTerminatedDate")
}
self?.endBackgroundTask()
}
}
func endBackgroundTask() {
UIApplication.shared.endBackgroundTask(backgroundTask)
backgroundTask = UIBackgroundTaskInvalid
}