Reputation: 33
So I am stuck I am building a bingo app and I want the app to stop the timer when the app goes into the background. my code looks like this
var timer = Timer()
func ViewDidLoad(){
// other stuff
timer = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(numberPicker), userInfo: nil, repeats: true)
}
In other posts I've read about this I've seen people recommend defining timer as a weak variable. When I try this My app crashes when it try's to make the timer.
Upvotes: 2
Views: 1833
Reputation: 285180
A modern solution is a DispatchSourceTimer
which can be suspended and resumed.
The two notification observers use also modern swifty block based API, no @objc
needed.
let timer = DispatchSource.makeTimerSource(queue: DispatchQueue.global())
override func viewDidLoad() {
super.viewDidLoad()
timer.schedule(deadline: .now() + .seconds(5), repeating: 5.0)
timer.setEventHandler {
print("Timer fired")
}
NotificationCenter.default.addObserver(forName: UIApplication.didEnterBackgroundNotification, object: nil, queue: .main) { [weak self] _ in
self?.timer.suspend()
}
NotificationCenter.default.addObserver(forName: UIApplication.didBecomeActiveNotification, object: nil, queue: .main) { [weak self] _ in
self?.timer.resume()
}
timer.activate()
}
Upvotes: 5
Reputation: 227
Swift 5:
override func viewDidLoad() {
super.viewDidLoad()
let notificationCenter = NotificationCenter.default
notificationCenter.addObserver(self, selector: #selector(appMovedToBackground), name: UIApplication.willResignActiveNotification, object: nil)
}
@objc func appMovedToBackground() {
timer.invalidate()
}
Upvotes: 1
Reputation: 16038
Try this. The timer will be restarted when the application returns from the background, as well.
class ViewController: UIViewController {
var timer = Timer()
var timerPaused = false
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default
.addObserver(self,
selector: #selector(applicationDidEnterBackground),
name: UIApplication.didEnterBackgroundNotification,
object: nil)
NotificationCenter.default
.addObserver(self,
selector: #selector(applicationDidBecomeActive),
name: UIApplication.didBecomeActiveNotification,
object: nil)
timer = Timer.scheduledTimer(timeInterval: 5,
target: self,
selector: #selector(numberPicker),
userInfo: nil,
repeats: true)
}
@objc
func applicationDidEnterBackground(_ notification: Notification) {
if !timerPaused {
timer.invalidate()
timerPaused = true
}
}
@objc
func applicationDidBecomeActive(_ notification: Notification) {
if timerPaused {
timer = Timer.scheduledTimer(timeInterval: 5,
target: self,
selector: #selector(numberPicker),
userInfo: nil,
repeats: true)
timerPaused = false
}
}
@objc
func numberPicker(_ sender: Any) {
}
}
Upvotes: 1