156

How do I check which one is the current thread in Swift 3?

In previous versions of Swift it was possible to check if the current thread was the main one by doing this:

NSThread.isMainThread()
Catalina T.
  • 3,456
  • 19
  • 29
BalestraPatrick
  • 9,944
  • 4
  • 30
  • 43
  • Most of the responses here are no longer (Swift 5+) valid. Thread.isMainThread is a warning (and does nothing) in Swift 5 and will be an error in Swift 6. – RobMac Sep 02 '23 at 18:46

7 Answers7

283

Looks like it's simply Thread.isMainThread in Swift 3.

BalestraPatrick
  • 9,944
  • 4
  • 30
  • 43
141

Thread.isMainThread will return a boolean indicating if you're currently on the main UI thread. But this will not give you the current thread. It will only tell you if you are on the main or not.

Thread.current will return the current thread you are on.

Brandon A
  • 8,153
  • 3
  • 42
  • 77
41

I've made an extension to print the thread and queue:

extension Thread {
    class func printCurrent() {
        print("\r⚡️: \(Thread.current)\r" + ": \(OperationQueue.current?.underlyingQueue?.label ?? "None")\r")
    }
}

Thread.printCurrent()

The result would be:

⚡️: <NSThread: 0x604000074380>{number = 1, name = main}
: com.apple.main-thread

Also recommend to use:

extension DispatchQueue {
    /// - Parameter closure: Closure to execute.
    func dispatchMainIfNeeded(_ closure: @escaping VoidCompletion) {
        guard self === DispatchQueue.main && Thread.isMainThread else {
            DispatchQueue.main.async(execute: closure)
            return
        }

        closure()
    }
}

DispatchQueue.main.dispatchMainIfNeeded { ... }
Nike Kov
  • 12,630
  • 8
  • 75
  • 122
33

Swift 4 and above:

Thread.isMainThread returns Bool stating that if the user is on Main Thread or Not, in case if someone wants to print the name of the queue/thread this extension will be helpful

extension Thread {

    var threadName: String {
        if let currentOperationQueue = OperationQueue.current?.name {
            return "OperationQueue: \(currentOperationQueue)"
        } else if let underlyingDispatchQueue = OperationQueue.current?.underlyingQueue?.label {
            return "DispatchQueue: \(underlyingDispatchQueue)"
        } else {
            let name = __dispatch_queue_get_label(nil)
            return String(cString: name, encoding: .utf8) ?? Thread.current.description
        }
    }
}

How to use:

print(Thread.current.threadName)
Suhit Patil
  • 11,748
  • 3
  • 50
  • 60
  • 2
    `__dispatch_queue_get_label` is not a part of Swift stdlib, it's not available outside of Apple platform-only frameworks. Can't call it on Ubuntu, for example. – Xander Dunn Sep 06 '20 at 19:24
  • `__dispatch_queue_get_label(nil)` FINALLY something that works, thanks! – J. Doe Aug 06 '21 at 12:24
17

Swift 5+

Normally, we only need to know which queue the code is dispatched. So I separate the threadName and queueName into different properties to make it more clear.

extension Thread {
    var threadName: String {
        if isMainThread {
            return "main"
        } else if let threadName = Thread.current.name, !threadName.isEmpty {
            return threadName
        } else {
            return description
        }
    }
    
    var queueName: String {
        if let queueName = String(validatingUTF8: __dispatch_queue_get_label(nil)) {
            return queueName
        } else if let operationQueueName = OperationQueue.current?.name, !operationQueueName.isEmpty {
            return operationQueueName
        } else if let dispatchQueueName = OperationQueue.current?.underlyingQueue?.label, !dispatchQueueName.isEmpty {
            return dispatchQueueName
        } else {
            return "n/a"
        }
    }
}

Use cases:

DispatchQueue.main.async {
   print(Thread.current.threadName)
   print(Thread.current.queueName)
}
// main
// com.apple.main-thread
DispatchQueue.global().async {
   print(Thread.current.threadName)
   print(Thread.current.queueName)
}
// <NSThread: 0x600001cd9d80>{number = 3, name = (null)}
// com.apple.root.default-qos
nahung89
  • 7,745
  • 3
  • 38
  • 40
13

When using GCD you can use dispatchPrecondition to check a dispatch condition necessary for further execution. This can be useful if you want to guarantee your code execution on correct thread. For example:

DispatchQueue.main.async {
    dispatchPrecondition(condition: .onQueue(DispatchQueue.global())) // will assert because we're executing code on main thread
}
Maxim Makhun
  • 2,197
  • 1
  • 22
  • 26
5

In latest Swift 4.0 ~ 4.2, we can use Thread.current

See Returns the thread object representing the current thread of execution

code4latte
  • 560
  • 9
  • 9