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 in Swift 3 (or 4). What is the preferred way to write this in Swift 3 (using the new Dispatch API)?

13 Answers

982
Rob On Best Solutions

The syntax is simply:

// to run something in 0.1 seconds

DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
    // your code here
}

Note, the above syntax of adding seconds as a Double seems to be a source of confusion (esp since we were accustomed to adding nsec). That "add seconds as Double" syntax works because deadline is a DispatchTime and, behind the scenes, there is a + operator that will take a Double and add that many seconds to the DispatchTime:

public func +(time: DispatchTime, seconds: Double) -> DispatchTime

But, if you really want to add an integer number of msec, μs, or nsec to the DispatchTime, you can also add a DispatchTimeInterval to a DispatchTime. That means you can do:

DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(500)) {
    os_log("500 msec seconds later")
}

DispatchQueue.main.asyncAfter(deadline: .now() + .microseconds(1_000_000)) {
    os_log("1m μs seconds later")
}

DispatchQueue.main.asyncAfter(deadline: .now() + .nanoseconds(1_500_000_000)) {
    os_log("1.5b nsec seconds later")
}

These all seamlessly work because of this separate overload method for the + operator in the DispatchTime class.

public func +(time: DispatchTime, interval: DispatchTimeInterval) -> DispatchTime
3
jjatie On

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

119
Hannes Sverrisson On

Swift 4:

DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)) {
   // Code
}

For the time .seconds(Int), .microseconds(Int) and .nanoseconds(Int) may also be used.

52
rockdaswift On

If you just want the delay function in

Swift 4

func delay(delay: Double, closure: @escaping () -> ()) {

     DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
          closure()
     }
}

You can use it like:

delay(delay: 1) { 
    print("Hi!")
}
16
Marco Pappalardo On

after Swift 3 release, also the @escaping has to be added

func delay(_ delay: Double, closure: @escaping () -> ()) {
  DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
    closure()
  }
}
0
Ankit garg On

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)")
}
5
Suhit Patil On

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")
}
0
Parth Dhorda On

You can use

DispatchQueue.main.asyncAfter(deadline: .now() + .microseconds(100)) {
        // Code
    }
4
Md. Ibrahim Hassan On

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)")
 }
0
A.Guz On

try this

let when = DispatchTime.now() + 1.5
    DispatchQueue.main.asyncAfter(deadline: when) {
        //some code
    }
0
iOS On

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
}
0
MANN On

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) {
    // ...
}
1
midhun p On

Swift 5 and above

DispatchQueue.main.asyncAfter(deadline: .now() + 2, execute: {
   // code to execute                 
})