Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?

iOS Swift - Cancellable Task with GCD

#iOSBySheldon

I think most of you guys know GCD pretty well. Basically, GCD is a high level API to handle multi-threading operations. We use GCD almost on daily basis to switch thread and execute codes like:

DispatchQueue.main.async { //execute some codes here } 
//switch to main queue and execute codes asynchronously

DispatchQueue.main.sync { //execute some codes here } 
//switch to main queue and execute codes synchronously

DispatchQueue.global().async { //execute some codes here }
//switch to background queue and execute codes asynchronously

DispatchQueue.global().sync { //execute some codes here }
//switch to background queue and execute codes synchronously

Note: “asynchronously” means current queue’s codes will NOT wait for the codes you wrote in the block and then execute. “synchronously” means current queue’s codes will wait for the codes you wrote in the block to be finished first and then continue executing. We use GCD a lot but GCD is way more powerful than this. Here is a scenario, imagine you are building a e-commerce app, the most important feature of your shopping app will be the search feature. You will be having a UISearchBar to let users typing in keywords to search your products. Of course, we need to implement the delegate function of UISearchBar to trigger the search, it might be like:

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
    // call a web service with the keywords - searchBar.text
}

But wait a moment, do we really want to trigger the search every time users type a character? Of course the answer is NO. A better solution might be adding a buffer time, for example 0.2 second, if user type another character with in 0.2 second, we cancel the search triggered by the previous character. We used to have to use NSTimer to cancel previous search, but now, we can do it easily with GCD. The ViewController class will be like:

class ViewController: UIViewController, UISearchBarDelegate {
    // Create a searching work item
    private var searchingWorkItem: DispatchWorkItem?

    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        // Cancel the searching item
        searchingWorkItem?.cancel()

        // Define our searching item to do the search
        let currentWorkItem = DispatchWorkItem {
            // call a web service with the keywords - searchBar.text
        }

        // Save the new work item and execute it after 250 ms
        searchingWorkItem = currentWorkItem
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.2,
                                      execute: currentWorkItem)
    }
}

Hope you learned something useful today!

Reference Links:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.