DispatchQueue vs Delegates vs Closures in Swift

Viewed 1191

Excuse me if this a noobish question but I don't know the difference between executing a block of code after an API request is received and parsed via GCD, delegates and closures.

As far as I know, a creating a session to download data from an API URL is done on the main thread unless I execute the code inside a a GCD block or a delegate or a closure.

Here are two examples: Using GCD

DispatchQueue.global(qos: .utility).async {

        let requestURL = URL(string: "http://echo.jsontest.com/key/value/one/two")
        let session = URLSession.shared
        let task = session.dataTask(with: requestURL!) {
            (data, response, error) in

            print(data as Any)

            DispatchQueue.main.async {
                print("Hello")
            }
        }
        task.resume()
    }

Using Delegate:

import Foundation
import UIKit

protocol WeatherDataDownloaderProtocol {
    func setData(weatherData: WeatherData)
}

class WeatherDataDownloader {
var weatherData = WeatherData()
var delegate: WeatherDataDownloaderProtocol?

func downloadWeatherData() {
    let API_URL = WEATHER_FORECAST_URL
    guard let URL = URL(string: API_URL) else {
        print("Error: No valid URL")
        return
    }
    let config = URLSessionConfiguration.default
    let session = URLSession(configuration: config)

    let task = session.dataTask(with: URL) { (data, response, error) in
        guard error == nil else {
            print("Error getting data")
            print("\(error)")
            return
        }

        guard let responseData = data else {
            print("Error: Did not receive data")
            return
        }

        do {
            guard let JSON = try JSONSerialization.jsonObject(with: responseData, options: []) as? Dictionary<String, AnyObject> else {
                print("Error: Error trying to convert data to JSON")
                return
        }

            print(JSON)

            self.sendDataBack()

        } catch {
            print("Error: Parsing JSON data error")
            return
        }
    }
    task.resume()
}

    func sendDataBack() {
        if let _delegate = delegate {
            _delegate.setData(weatherData: weatherData)
        }
    }
}

Both, print("Hello") and print(JSON) + self.sendDataBack() will execute after the JSON is retrieved and parsed. What's the difference between both methods? Does it have anything to do with whether my app would crash if I navigate out of the viewController while waiting for the network response?

Thanks a lot

3 Answers
Related