Easy Swift Timers

Learn how to easily schedule and run a Swift timer and how to configure the Swift timer for various use cases and scenarios. Copy and paste code snippets!
Written by

Chris C

Updated on

Apr 29 2024

Table of contents

    There comes a time in your swift development that you will find the need to schedule when to fire your code, or you might want to give your user some time to think about what they want to do like a countdown timer. In this article we will discuss about timers and how to use them.

    Timer is Swift is part of the Foundations framework so in order to use it in on your app you must import Foundations first. 

    import Foundation

    You  are now ready to to timers in your app!

    The Basics – Scheduled Timer

    The basic use for a timer is called the scheduledTimer where you need to set the timeInterval, selector, and repeats. The timeInterval is set to how many seconds elapsed to call the function/selector. The selector serves as the function/action that the timer calls when it fires. Finally, repeats is a boolean variable that indicates if the timer should be repeating or it fires only once.

    A Basic timer is declared as such:

    //declare blank timer variable
    	var timer = Timer()
    	
    	//in a function or viewDidLoad()
    timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(timerAction), userInfo: nil, repeats: true)
    
    
    //new function
    @objc func timerAction(){
           print(“timer fired!”)
        }
    

    Notice that the function has an @objc. This is because it is needed to create a selector which is a requirement for our timer.

    In order for the timer to only fire once the option repeats should be set to false

    timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(timerAction), userInfo: nil, repeats: false)
    

    In the instance that you have a repeating timer you can manually stop your timer according to  your preference by calling .invalidate, you can do this on your selector.

    //in a function or viewDidLoad()
    timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(timerAction), userInfo: nil, repeats: true)
    
    
    //new function
    @objc func timerAction(){
           print(“timer fired!”)
          timer.invalidate()
        }
    

    Scheduled Timer with Defined Selector

    A timer can also have an already defined selector, which means no need to create a separate function for it. In order to do so just do this:

    Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { timer in 
                	print("timer fired!")
                	timer.invalidate()
           	}
    
    

    Having this option also lets us easily create and manage what we want our timer to do, lets say we create a countdown timer we can simply define our timer like this:

    var timeLeft = 10
            
                  Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { timer in
                      	 print("timer fired!")
                    
                    	timeLeft -= 1
                    
                    	self.timerTextField.text = String(timeLeft)
                    	print(timeLeft)
                    
                  	if(timeLeft==0){
                        		timer.invalidate()
                        	}
                   }
    

    Notice how we can use variables in our selector, just be sure to declare a variable first if you plan on using one.

    Timer tolerance

    Timer tolerance is set when you can tolerate your timer fire to be a bit late. Why would you want your timer to be a bit late, you ask? Simply, it’s because it can contribute to power consumption. Remember that your app, specially when there is a timer running in the background, will have a hard time managing your state. By setting a tolerance we are letting the app have more time to properly execute different kinds of code and this in turn lowers  battery consumption of your app. 

    In order to set tolerance just define as:

     timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(timerAction), userInfo: nil, repeats: true)
            timer.tolerance = 0.3
    

    Note: it is important to note that tolerance can make your app late, but it will never execute your code early.

    Timer with RunLoop

    Most of the time when using Timers you would want your timer to run in the background while you are busy doing something else on your app. However, a normal Timer will run Synchronously on your thread. Meaning it will run only then you are already finished with your other tasks. It also only runs in your Main thread, which will pause when you begin interaction with the UI. 

    This is where RunLoop comes into play, Runloop will help set where on the thread do we want our Timer to run. In our case if we want to be able still loop the timer even though we are interacting with the UI. Thus, the thread we will be setting will be the RunLoop.Mode.common thread which is the thread that handles “common” input modes.

    In order to add a Timer to the “common” Runloop just do the following codes:

     RunLoop.current.add(timer, forMode: RunLoop.Mode.common)
    

    Conclusion

    Working with timers can be very rewarding and can add a level of depth in your app that is both fun and useful. Just be careful though! As an unmonitored timer loop can be a potential battery drainer/CPU consumer and may cause problems in the long run.


    Further Reading




    Get started for free

    Join over 2,000+ students actively learning with CodeWithChris