How to use background thread in swift? How to use background thread in swift? ios ios

How to use background thread in swift?


Swift 3.0+

A lot has been modernized in Swift 3.0. Running something on a background queue looks like this:

DispatchQueue.global(qos: .userInitiated).async {    print("This is run on a background queue")    DispatchQueue.main.async {        print("This is run on the main queue, after the previous code in outer block")    }}

Swift 1.2 through 2.3

let qualityOfServiceClass = QOS_CLASS_USER_INITIATEDlet backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0)dispatch_async(backgroundQueue, {    print("This is run on a background queue")    dispatch_async(dispatch_get_main_queue(), { () -> Void in        print("This is run on the main queue, after the previous code in outer block")    })})

Pre Swift 1.2 – Known issue

As of Swift 1.1 Apple didn't support the above syntax without some modifications. Passing QOS_CLASS_USER_INITIATED didn't actually work, instead use Int(QOS_CLASS_USER_INITIATED.value).

For more information see Apples documentation


Dan Beaulieu's answer in swift5 (also working since swift 3.0.1).

Swift 5.0.1

extension DispatchQueue {    static func background(delay: Double = 0.0, background: (()->Void)? = nil, completion: (() -> Void)? = nil) {        DispatchQueue.global(qos: .background).async {            background?()            if let completion = completion {                DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: {                    completion()                })            }        }    }}

Usage

DispatchQueue.background(delay: 3.0, background: {    // do something in background}, completion: {    // when background job finishes, wait 3 seconds and do something in main thread})DispatchQueue.background(background: {    // do something in background}, completion:{    // when background job finished, do something in main thread})DispatchQueue.background(delay: 3.0, completion:{    // do something in main thread after 3 seconds})


The best practice is to define a reusable function that can be accessed multiple times.

REUSABLE FUNCTION:

e.g. somewhere like AppDelegate.swift as a Global Function.

func backgroundThread(_ delay: Double = 0.0, background: (() -> Void)? = nil, completion: (() -> Void)? = nil) {    dispatch_async(dispatch_get_global_queue(Int(QOS_CLASS_USER_INITIATED.value), 0)) {        background?()        let popTime = dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC)))        dispatch_after(popTime, dispatch_get_main_queue()) {            completion?()        }    }}

Note: in Swift 2.0, replace QOS_CLASS_USER_INITIATED.value above with QOS_CLASS_USER_INITIATED.rawValue instead

USAGE:

A. To run a process in the background with a delay of 3 seconds:

    backgroundThread(3.0, background: {            // Your background function here    })

B. To run a process in the background then run a completion in the foreground:

    backgroundThread(background: {            // Your function here to run in the background    },    completion: {            // A function to run in the foreground when the background thread is complete    })

C. To delay by 3 seconds - note use of completion parameter without background parameter:

    backgroundThread(3.0, completion: {            // Your delayed function here to be run in the foreground    })