https://medium.cobeisfresh.com/why-you-shouldn-t-use-delegates-in-swift-7ef808a7f16b
The difference between delegates and callbacks is that
with delegates, the NetworkService is telling the delegate “There is something changed.”
We declare a protocol that says, whatever object conforms to this, must implement func didCompleteRequest(result: String):
This is so that we can pass the result String to that object.
1 2 3 |
protocol NetworkServiceDelegate { func didCompleteRequest(result: String) } |
Hence, we have a NetworkService object, it has a delegate to some object A that conforms to NetworkServiceDelegate. This means that object A will implement
func didCompleteRequest(result: String).
That way, whenever something is fetched from a URL, we can call on the delegate (reference that object A), and pass the result String via the protocol method
didCompleteRequest:
1 2 3 4 5 6 7 8 9 10 11 |
class NetworkService { var delegate: NetworkServiceDelegate? func fetchDataFromUrl(url: String) { API.request(.GET, url) { result in // service object telling the delegate "There is something changed" delegate?.didCompleteRequest(result) } } } |
Hence, the delegate (the object that conforms to the protocol) is notified of the change
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
class MyViewController: UIViewController, NetworkServiceDelegate { let networkService = NetworkService() override func viewDidLoad() { super.viewDidLoad() networkService.delegate = self } // the delegate is notified of the change func didCompleteRequest(result: String) { print("I got \(result) from the server!") } } |
With callbacks, the delegate is observing the NetworkService
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
// the service object class NetworkService { var onComplete: ((String)->())? //an optional function func fetchDataFromUrl(url:String) { print("calling fetchDataFromUrl") sleep(2) onComplete?(" yay! data completed ") } } // the delegate is observing the service object class MyViewController: UIViewController { let networkService = NetworkService() override func viewDidLoad() { super.viewDidLoad() // observes here networkService.onComplete = { result in print("I got \(result) from the server!") } } public func queryTheWeb() { // calls the service object // the onComplete callback definition will then observe for the result in viewDidLoad() networkService.fetchDataFromUrl(url: "http://www.google.com") } } |
It will call “networkService.fetchDataFromUrl(url: “http://www.google.com”)” somewhere. Then it will observe for the data to pass through from fetchDataFromURL, and finally to the defined definition of onComplete as declared in viewDidLoad.