Delegation using Protocols

Yessen
Deem.blogs
Published in
4 min readMay 17, 2021

--

I guess mostly everybody has heard the term “protocol” during iOS development. However, not everybody knows what is it and how to use it. More than that, those people are missing the huge advantage and easy usability of the protocols.

To be honest, even if you have not heard about what is protocol delegation, I assure you that you have already used it at least once in some of your projects. For instance, when you create your custom UITableVIew, in order to fill up UITableViewCells, you write:

self.tableView.delegate = self
self.tableView.dataSource = self
extension YourViewController: UITableViewDelegate, UITableViewDataSource{func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {return 1}func numberOfSections(in tableView: UITableView) -> Int {return self.videoData.count}func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {return self.tableView.frame.height}func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {guard let cell = tableView.dequeueReusableCell(withIdentifier: "videoCell", for: indexPath) as? FeedTableViewCell else{fatalError("Unable to create cell")}cell.setVideo(with: self.videoData[indexPath.section])//cell.playVideo() return cell }
}

where you should confirm to protocol of UITableViewDelegate and fill up the functions. Usually we just copy these codes automatically and do not pay detail attention to what we are doing. However, this is the pure example of protocol delegations.

What Apple official documentation tells us about this term:

According to Apple Documentation-

A protocol defines a blueprint of methods, properties, and other requirements that suit a particular task or piece of functionality. The protocol can then be adopted by a class, structure, or enumeration to provide an actual implementation of those requirements. Any type that satisfies the requirements of a protocol is said to conform to that protocol.

In addition to specifying requirements that conforming types must implement, you can extend a protocol to implement some of these requirements or to implement additional functionality that conforming types can take advantage of.

Sounds cool and awesome! And I do not see any limitation in here, which means it is totally up to you how and where to use protocols. You, for instance, heard about protocol oriented programming, which was introduced by swift in WWDC 2015, which is highly recommended to be used in stead of regular OOP. However, it is totally different article.

Alright, let me know explain to you from my perspective in what cases do I use delegation protocols in my projects.

I personally use it, if I can, instead of callback functions or reactive programming in communication between different classes.

So, let’s suppose, you have View and ViewModel, where View asks ViewModel to fetch the new data from api and after it is done, notify the View to update the layout. So basically there are 3 main different ways to do it. You can write callback and assign it to your ViewModel, or use Reactive programming, and leave the observant in View, when ViewModel will finish fetching the data. However, I do not prefer both of them.

In the picture above, you can see the communication between two ViewControllers. You initiate 2nd VC from 1st VC, which then will wait when 2nd VC will finish its functions(in this case it was to record the video).

In case of callbacks, it might be confusing in threads and syntax for junior developers in understanding the flow of data and process. I personally had tons of Thread bugs when I was working on the project which had million of threads created.

On the other hand, reactive programming is kind of solving the syntax issue. If you have a look at RxSwift’s documentation, it is clearly explaining that you just need to define observator and observable, the pattern of which looks similar to NSNotification in native swift. However, RxSwift made it more scalable and functional. However, still for me, when I was starting my iOS journey, it seemed pretty complicated to understand the concept and logic behind it. Besides that, in order to use it, you have to download the pod file, and be dependent on it, which I personally try to avoid every time I develop my projects.

Here comes the reason why I use protocol delegation. It is simple to use, and easy to understand, and it is recommended by swift! So basically, it solves the problem of communicating back to parent viewcontroller, by asking parent to conform to the child’s protocol.

So for instance, in our example of fetching data, let’s suppose we have two outcomes, where we want send the message to the view from viewModel:

1. There appeared some error in communicating with API. -> showError(with message: String)

2. We succeeded the fetch. -> didiFetch(with data: [FetchedData]

where, FetchedData is our model for the data we are fetching from the API.

So the syntax will look like this:

protocol FeedCollectionViewModelDelegate{func didFetch(with data: [VideoModel], page: Int)func showError(with error: String)}

In here we defined our protocol.

self.viewModel.delegate = selfextension FeedCollectionViewController: FeedCollectionViewModelDelegate{func didFetch(with data: [VideoModel], page: Int) {
//reload data
self.collectionView.reloadData()
}
func showError(){
//TODO: show error
}

In here, we conformed our parent viewcontroller to the delegate of our viewModel.

var delegate: FeedCollectionViewModelDelegate?func getDataFromAPI(){
//error appeared
self.delegate!.showError(with: "could not get data"
//succeeded
self.delegate!.didFetch(with: [data])
}

In here, we are sending message to our parent when we got the error, or finished fetching data.

That’s it! You have dong delegation using protocols. It was easy, fast, and did not require any pod files.

Every time I need to design communication between two views, I always try to use protocol delegation, due to its easy usage.

--

--