Sometimes you need to create a wait or delay in your Swift code.
To run a block of code after a time delay, use asyncAfter
:
let secondsToDelay = 5.0
DispatchQueue.main.asyncAfter(deadline: .now() + secondsToDelay) {
print("This message is delayed")
// Put any code you want to be delayed here
}
To call a function after a certain period of time, you can use the perform
function:
let secondsToDelay = 5.0
perform(#selector(delayedFunction), with: nil, afterDelay: secondsToDelay)
@objc func delayedFunction() {
print("This message is delayed")
}
To sleep execution after a period of time use the sleep
function
print("hello")
sleep(5.0)
print("delayed message")
Be careful! Calling sleep
will halt execution of the rest of your program. Usually this isn’t what you want. This function is typically only used in tests.
You can use the Timer
class to also delay execution.
let timer = Timer.scheduledTimer(withTimeInterval: 5.0, repeats: false) { (timer) in
print("delayed message")
}
Note that the timer runs in the default run loop mode. This means it can be frozen when certain user behaviors are detected, such as a scrolling a UIScrollView
.
You can solve this by adding the timer for RunLoop.Mode.common
.
RunLoop.current.add(timer, forMode: RunLoop.Mode.common)
There are couple of situations where a wait or delay is useful.
During an automated test such as a KIF test or other type of test, a wait can be useful in ensuring an element has appeared on screen. It’s better however to wait for a specific action or element becoming visible rather than to wait on a fixed time limit.
In XCTests, you can use waitForExpectations
to wait for a condition to be true and also specify a time out as well. To read more, check out the official Apple documentation here.
In KIF tests, you can use functions waitForTappableViewWithAccessibilityLabel
and waitForViewWithAccessibilityLabel
.
Sometimes you want to run a function on a timer. This can be used to detect when a user is inactive or to refresh data on a certain interval.
There are times when you want to prevent a user from doing a repetitive action too frequently. For example, you may want to limit how many times a user can refresh the data or how often a user can request a confirmation email or text.
This will prevent your server from being spammed.
Depending on your use case, there can be a better solution than using a wait or a delay.
Callbacks or closures are blocks of code that can be executed when certain conditions are met. If you know your app is able to check for these conditions during execution, it is better to use a callback or closure as opposed to a wait.
Delegates are similar to callbacks, they are objects that are used to communicate between view controllers or objects. These delegates can execute functions when certain code conditions occur.
Of course, instead of a timer, you could just write an if statement
. You just have to make sure this if statement
will be called during the right time and that it works for your use case.
Waits or delays are rarely the way you want to handle things. Time based actions add complexity to your application, making it hard to predict it’s state at any given time.
The only place I’ve used waits frequently is in test files, however, I’d recommend avoiding those too if possible.
The Complete iOS App Development Bootcamp
Disclosure: This website may contain affiliate links, meaning when you click the links and make a purchase, we receive a commission.