ios – Swift Timer.scheduledTimer() doesnt work
ios – Swift Timer.scheduledTimer() doesnt work
Timers dont work on background queues (without some sleight of hand involving creating run loops or manually scheduling it on an existing run loop). But you should never initiate any UI update from anything other than the main queue, anyway.
So, since youre calling performSegue
from a URLSession
completion closure (which runs on a background queue), its actually running viewDidLoad
from the background queue, too. Thus the attempt to schedule the timer is failing. To get around this, you have to manually dispatch the performSegue
code to the main queue:
let task = URLSession.shared.dataTask(with: url!) { data, response, error in
...
if isPassed != null {
DispatchQueue.main.async {
self.performSegue(withIdentifier: gotoGame, sender: ...)
}
}
}
If youre ever unsure whether some code is running on the main queue or not, refer to the documentation. Or you can use a dispatch precondition:
dispatchPrecondition(condition: .onQueue(.main))
That way it will (in debug builds) stop the app if youve accidentally invoked the code from a background queue.
Unrelated to your current problem, but as an aside, to avoid a strong reference cycle between the timer and the view controller, you generally want to keep a reference to the timer so that you can invalidate
it when the view disappears (e.g. create timer in viewDidAppear
and remove it in viewDidDisappear
). Otherwise you can end up retaining the GameViewController
after it was dismissed, e.g.:
class GameViewController: UIViewController {
weak var timer: Timer?
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
timer = Timer.scheduledTimer(timeInterval: 1.0, target:self, selector: #selector(setCalculationLs(_:)), userInfo: nil, repeats: true)
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
timer?.invalidate()
}
@objc func setCalculationLs(_ timer: Timer) {
print(Tick)
}
}
Or in iOS 10 or later, you can use the block-based variant with weak
reference to self
, and invalidate
in deinit
:
class GameViewController: UIViewController {
weak var timer: Timer?
override func viewDidLoad() {
super.viewDidLoad()
timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { [weak self] timer in
self?.setCalculationLs()
}
}
deinit {
timer?.invalidate()
}
func setCalculationLs() {
print(Tick)
}
}
ios – Swift Timer.scheduledTimer() doesnt work
Related posts on IOSĀ :
- Why is my app stuck on installing iOS?
- How do I find keyboard shortcuts in IOS?
- How do I download IOS 10.10 on my Mac?
- What is the user agent for iOS?
- How do I save a Web page as a PDF iOS 15?
- How do I download iOS on an old iPad?
- What is the iOS button?
- How do I get a refund on IOS?
- Is there a Google Forms app on iOS?
- How do I install iOS on an old iPod touch?