Difference between a Callback and Competition Handler in Swift

Viewed 1696

In the Combine framework, I have found following text

The Combine framework provides a declarative approach for how your app processes events. Rather than potentially implementing multiple delegate callbacks or completion handler

Can somebody tell me what is the difference between completion handler and callback in Swift?

5 Answers

A delegate callback is when you have a delegate that you know in advance implements a method (e.g. because it adopts a protocol), and you call that method by name.

A completion handler is when someone hands you a function and you just call it blindly by reference.

to be clear actually you can achieve the same functionality with both ways however the there are completely different approach for designing your app

let me clarify with simple example the difference between both with the same function is making network call

  • delegate protocol
    // enum to define the request type

enum RequestTypes {

    case UserRegister
    case UserLogin

}

protocol ServiceDelegate {

    func didCompleteRequest(responseModel: AnyObject, tag: RequestTypes)

}

// you can also add default impl to the methods here

extension ServiceDelegate {

    func didCompleteRequest(responseModel: AnyObject, tag: RequestTypes){}

}


class BaseService<ResponseModel: Codable> {

    var session: URLSession!
    var delegate: ServiceDelegate?

    // MARK: Rebuilt Methods
    func FireRequest(){

        // Request Preparation
        let serviceUrl = URL(string: /* your url */)!
        var request = URLRequest(url: serviceUrl)
        request.httpMethod = "GET"


        // Firing the request
        session = URLSession.init(configuration: URLSessionConfiguration.default)
        session.dataTask(with: request) { (data, response, error) in
            if let data = data {
                do {
                    guard let object = try? JSONDecoder().decode(ResponseModel.self , from: data) else {/* handle error or call delegate error method here */ return }
                    delegate?.didCompleteRequest(responseModel: object, tag: .UserLogin)
                }
            }
            }.resume()
    }

}



class ViewController: UIViewController, ServiceDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        fetchNewData()
    }

    func fetchNewData(){
        let service = BaseService<YourModel>()
        service.delegate = self
        service.FireRequest()
    }

    func didCompleteRequest(responseModel: AnyObject, tag: RequestTypes) {
        if tag == /* the tag you are waiting */ .UserLogin {
            // YourModel is available here
        }
    }


}

  • completion handler

class BaseService<ResponseModel: Codable> {

    var session: URLSession!

    // MARK: Rebuilt Methods

    func FireRequest(completion: ((ResponseModel?) -> Void)?){

        // Request Preparation
        let serviceUrl = URL(string: /* your url */)!
        var request = URLRequest(url: serviceUrl)
        request.httpMethod = "GET"


        // Firing the request
        session = URLSession.init(configuration: URLSessionConfiguration.default)
        session.dataTask(with: request) { (data, response, error) in
            if let data = data {
                do {
                    guard let object = try? JSONDecoder().decode(ResponseModel.self , from: data) else {/* handle error or call delegate error method here */ return }
                    DispatchQueue.main.async {
                        completion?(object)
                    }
                }
            }
            }.resume()
    }

}

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        fetchNewData()
    }

    func fetchNewData(){

        let service = BaseService<YourModel>()

        service.FireRequest(completion: { [weak self] (response) in
            // yourModel Available here once the request completed
        })

    }

}

A delegate callback is one to one communication between various ViewControllers and classes. It basically lets you know that a particular change has been done in particular view or any where else and now you can make change after this action.

While completion handler is a block executed after completing a particular process or task.

Callback is a way to sending data back to some other function on some particular occasion. there are 2 ways to implement callbacks in swift.

  1. Using Protocols / Delegate
  2. Using Completion Handler

Using Protocols / Delegate Example:

Declare Protocol

protocol MyDelegate {
     public method(param: String);
}

Your ViewController should extend the delegate

class YourViewController: MyDelegate {
     // Your Other methods

     func method(param: String) {
      // Do your stuff
     }
 }

Now in your other classes you can send callback to ViewController through delegate object like

delegate.method(param: "your_param");

Using Completion Handler Example:

public func method(param: String, completionHandler: @escaping (_ param: String) -> Void)
{
    ...
    // now you can send data back to the caller function using completionHandler on some particular occasion 
     completionHandler("param");
}

We can call this function like

method(param: String, completionHandler: { (result, alreadyUserId) in
      // here you will receive callback
});

Callbacks and Completion Handlers are synonymous when referring to asynchronous methods.

I’ve found the main difference being in how its used in defining what’s returned to the caller where a callback is used when referring to a method where the scope is returned to the previous calling method and a completion handler refers to a method when it returns some Result type to the caller.

Related