Open In App

Non Repeating Timers in Swift

Last Updated : 26 Feb, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Developers may create effective and efficient applications using a number of tools with Swift, a strong and versatile programming language. The Timer class is one such tool that enables programmers to define timed events that run at predetermined intervals. In this post, we’ll go over how to make a non-repeating timer using Swift’s Timer class. Swift uses timers to create repeating jobs that may be scheduled with a delay. It’s a class that used to go by the name NSTimer. Swift’s timer class offers a flexible way to plan tasks that will happen either once or periodically in the future.

Timer You must import Foundations using Swift because it is a part of the Foundations framework.

Ref: https://developer.apple.com/documentation/foundation/timer

Ref: https://developer.apple.com/documentation/foundation

import Foundation

At this point, your app can start using timers.

Why are timers usually required?

You often see situations where you must repeatedly do a specific activity within a specific time frame or situations where you must complete specific actions after a specified period of time. These are the best circumstances for using timers in your codebase.

Some typical use cases for timers include:

  • Let’s say you have to call a specific method automatically every 5 seconds.
  • On app termination, you want to send a local notification.
  • Send new information after X times to sync your cart details with the backend.

To achieve the repeating and scheduling behavior in the aforementioned instances, timers can be used.

The Basic: ScheduledTimer

The scheduledTimer is the input provided for a timer, and it requires that you set the timeInterval, selector, and repeats. The timeInterval is set to the number of seconds since the function or selector was called. When the timer fires, the selector acts as the function or action that is invoked. Last but not least, the repeats boolean variable lets you choose whether the timer should trigger repeatedly or just once.

Swift




///create the empty 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 fire()
    {
      print("timer fired!")
    }


Output: 

timer fired!

In the code mentioned above, a few things happen:

  • The Timer.scheduledTimer(…) class method is used to create a timer. The constant timer receives the method’s return value. 
  • The 1-second timer interval is one of scheduledTimer(parameters. )’s It makes use of the target-action mechanism, some userInfo that is set to nil, and the repeats parameter set to true.
  • We also created a function called fire(). This function is used when the timer activates, which happens approximately once every second. When you set the target to self and the selector to #selector (fire), you’re telling the timer to call self’s function fire() anytime it fires.

Explanation of the parameter:

This code generates a timer with 5 parameters.

  • timeInterval: The time in seconds between timer fires is provided by the Double variable.
  • target: It specifies the class instance on which to call the selector function.
  • selector: It specifies the code to be invoked when the timer goes off using #selector(…)
  • userInfo: This parameter either specifies a dictionary of data provided to the selector or null.
  • repeats: The word “repeats” indicates whether or not this timer is repeating.

To ensure that the timer will only activate once, the repeats option should be set to false.

Swift




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


In the event that your timer is set to repeat, you can manually halt it whenever you like by executing the function .invalidate() on your selector.

Swift




//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(“Hello geeks!”)
     timer.invalidate()
   }


Output: 

Hello geeks!

Repeating Vs Non-repeating Timers

A timer’s repeating or non-repeating status must be specified when it is first created. The main distinction between the two is as follows:

A non-repeating timer only fires once before automatically invalidating itself to stop it from firing again.

A repeating timer fires, runs on the same run loop, then restarts. In contrast to the actual firing time, a repeating timer always schedules itself based on the intended firing time.

For example, even if the actual firing time is delayed, if a timer is set to fire at a given time and then every 10 seconds after that, the scheduled firing time will always coincide with the initial 10-second time intervals.

Creating a Non-repeating Timer

Simply change the repeats option to false to create a non-repeating timer. Only one firing will occur before the timer invalidates itself.

Swift




let timer = Timer.scheduledTimer(timeInterval: 5.0, target: self
                                 selector: #selector(fire), 
                                 userInfo: nil, repeats: false)
@objc func fire()   
{  
    print("Firing the function after specific interval")
}


Output: 

Firing the function after specific interval

Example 1: Display a message after a delay

Swift




let timer = Timer.scheduledTimer(withTimeInterval: 5, repeats: false) { timer in
    print("Time's up!")
}


Time's up!

In this example, we develop a timer that, after a delay of five seconds, prints the message “Time’s up!” to the console. This Timer will only fire once because the repeats option is set to false.

Example 2: Show a loading indicator for a fixed amount of time

Swift




@IBOutlet weak var loadingIndicator: UIActivityIndicatorView!
  
override func viewDidLoad() {
    super.viewDidLoad()
      
    loadingIndicator.startAnimating()
    let timer = Timer.scheduledTimer(withTimeInterval: 10, repeats: false) { timer in
        self.loadingIndicator.stopAnimating()
    }
}


In this example, a UIActivityIndicatorView is started to display a loading indicator, and a Timer is created to cause the indicator to disappear after a 10-second delay. This Timer will only fire once because the repeats option is set to false.

Example 3: Schedule a notification for a specific time

Swift




let content = UNMutableNotificationContent()
content.title = "Reminder"
content.body = "Don't forget to take your medicine!"
  
let date = Date(timeIntervalSinceNow: 3600) // schedule notification for 1 hour from now
let trigger = UNCalendarNotificationTrigger(dateMatching: Calendar.current.dateComponents([.year, .month, .day, 
                                                                                           .hour, .minute, .second],
                                                                                          from: date), repeats: false)
let request = UNNotificationRequest(identifier: UUID().uuidString, 
                                    content: content, trigger: trigger)
  
UNUserNotificationCenter.current().add(request)


In this example, we’ll create a notification with a reminder message and use a non-repeating Timer to set it to go off at a particular time. A trigger that shoots the notification at the specified date and time is made using the UNCalendarNotificationTrigger class. This Timer will only fire once because the repeats option is set to false.

Timer Tolerance

When your timer fires a little bit late, your timer tolerance is established. You may wonder why you would want your timer to start a little later. It can increase power usage. Keep in mind that your programme will struggle to manage your status, especially if a timer is running in the background. Setting a tolerance allows the app to have more time to execute various types of code correctly, which reduces your app’s battery usage.

Define ” the tolerance as follows:

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

Note: Tolerance can cause your programme to run slowly, but it will never execute your code before its scheduled time.

Timer with RunLoop

When using a timer, you typically want it to run in the background while you are using your app for anything else. A typical timer, however, will operate synchronously on your thread. meaning that it won’t start until you’ve finished all of your other tasks. Additionally, it only executes in your Main thread, which pauses whenever you interact with the user interface.
RunLoop will help us decide where on the thread we want our timer to run, which is where it comes into play. In our scenario, even if we are engaging with the UI, we still want to be able to loop the timer. Therefore, the RunLoop will be the thread we set. The thread is known as mode.common, which manages “common” input modes

Simply enter the following lines to add a Timer to the “common” Runloop:

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

Conclusion

Working with timers can be a rewarding experience that adds depth to your program, which is both interesting and useful. Be cautious, though! Unchecked timer loops can drain batteries and use CPU resources, which could lead to long-term issues.



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads