In Swift 2, I was able to use dispatch_after
to delay an action using grand central dispatch:
var dispatchTime: dispatch_time_t = dispatch_time(DISPATCH_TIME_NOW, Int64(0.1 * Double(NSEC_PER_SEC)))
dispatch_after(dispatchTime, dispatch_get_main_queue(), {
// your function here
})
But this no longer seems to compile since Swift 3. What is the preferred way to write this in modern Swift?
This question is related to
swift
swift4
grand-central-dispatch
swift5
Swift 4:
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)) {
// Code
}
For the time .seconds(Int)
, .microseconds(Int)
and .nanoseconds(Int)
may also be used.
after Swift 3 release, also the @escaping has to be added
func delay(_ delay: Double, closure: @escaping () -> ()) {
DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
closure()
}
}
In Swift 4.1 and Xcode 9.4.1
Simple answer is...
//To call function after 5 seconds time
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
//Here call your function
}
You can use
DispatchQueue.main.asyncAfter(deadline: .now() + .microseconds(100)) {
// Code
}
call DispatchQueue.main.after(when: DispatchTime, execute: () -> Void)
I'd highly recommend using the Xcode tools to convert to Swift 3 (Edit > Convert > To Current Swift Syntax). It caught this for me
This worked for me in Swift 3
let time1 = 8.23
let time2 = 3.42
// Delay 2 seconds
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
print("Sum of times: \(time1 + time2)")
}
A somewhat different flavour of the Accepted Answer.
Swift 4
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1 + .milliseconds(500) +
.microseconds(500) + .nanoseconds(1000)) {
print("Delayed by 0.1 second + 500 milliseconds + 500 microseconds +
1000 nanoseconds)")
}
If you just want the delay function in
Swift 4 & 5
func delay(interval: TimeInterval, closure: @escaping () -> Void) {
DispatchQueue.main.asyncAfter(deadline: .now() + interval) {
closure()
}
}
You can use it like:
delay(interval: 1) {
print("Hi!")
}
try this
let when = DispatchTime.now() + 1.5
DispatchQueue.main.asyncAfter(deadline: when) {
//some code
}
None of the answers mentioned running on a non-main thread, so adding my 2 cents.
On main queue (main thread)
let mainQueue = DispatchQueue.main
let deadline = DispatchTime.now() + .seconds(10)
mainQueue.asyncAfter(deadline: deadline) {
// ...
}
OR
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + .seconds(10)) {
// ...
}
On global queue (non main thread, based on QOS specified) .
let backgroundQueue = DispatchQueue.global()
let deadline = DispatchTime.now() + .milliseconds(100)
backgroundQueue.asyncAfter(deadline: deadline, qos: .background) {
// ...
}
OR
DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + .milliseconds(100), qos: .background) {
// ...
}
Swift 5 and above
DispatchQueue.main.asyncAfter(deadline: .now() + 2, execute: {
// code to execute
})
Swift 4
You can create a extension on DispatchQueue and add function delay which uses DispatchQueue
asyncAfter function internally
extension DispatchQueue {
static func delay(_ delay: DispatchTimeInterval, closure: @escaping () -> ()) {
DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: closure)
}
}
and use
DispatchQueue.delay(.milliseconds(10)) {
print("task to be done")
}
Source: Stackoverflow.com