This is a very common question. If you follow the MVC pattern, like all the tutorials and Apple sample code, your view controllers conform to a lot of protocols.
UICollectionViewDelegate are the most common ones.
If your UI collects user inputs, you also have
What if you show a map? You can count on having
Almost all apps fetch data from APIs, so you also have some of these:
I can keep going, but let’s just stop here.
Your view controllers conform to many of these Apple provided protocols, plus any custom protocols you define for your app. Each of these protocols has several delegate methods your view controllers need to implement. It can easily get out of hand.
This is one reason contributing to your massive view controllers. Let’s see how Clean Swift tackles this problem.
Move ’em outta here
You may think: “Let’s just move these delegate methods out of the view controllers. Then my view controllers will have fewer lines of code.”
You can create a new, custom data source or delegate class to define an API. Then, you can instantiate an instance from your view controller, and invoke methods on.
Or, you can simply move these methods to a Swift extension in a separate file(s). This is super easy and doesn’t require any API design decisions. I wrote about how you can do that in more details in this post.
Although it cuts down the number of lines of code, but deep inside your mind, you know you’re just moving code around. You sense there is still something wrong. You want to do better. But you just don’t know how.
Yes, there’s a much better way.
This will never be a problem using Clean Swift
If you apply the Clean Architecture to your app, this is never a problem. You’ll never have too many delegate methods in your view controllers. Your view controllers conform only to protocols that should belong there.
How do you determine what protocols should belong in your view controllers?
When you implement your features using the VIP cycle, all your business logic naturally stay in your interactors and workers. As a result, any protocol without the
UI prefix are conformed to and have their delegate methods in the interactors and workers. And any protocol with the
UI prefix stay in your view controllers.
In particular, if the feature calls for adding a map to the UI, the VIP cycle drives your design. You’ll end up conforming to the
CLLocationManagerDelegate protocols in your interactor.
Your interactor will decide how to respond to events when the user moves or zooms in the map. It’ll then ask the presenter to format an appropriate response before handing it to the view controller to update the display.
You most likely deal with networking throughout your app. Fetch some feeds in this screen. Display a user profile in that screen. Create a post there. Using Clean Swift, you’ll create a shared worker(s) to encapsulate all your networking code. So, your worker will conform to those
Your worker creates a session configuration and a download task, and then call
resume() to start the task asynchronously. When the data becomes available, your callback is invoked. At that time, your worker notifies your interactor which in turn invokes your presenter to format the data for display in the view controller.
When it comes to your view controller, now that all those other protocols are out of the way, it’s suddenly not too bad to conform to the
UI prefixed data source and delegate protocols. The UI prefix means they have to deal with the UI.
Even if you have a super bloated UI, you can still create a custom class or pull the methods out to an extension.
What does this all mean? It means you’ll never have to refactor because of massive view controllers. Massive view controller is not a thing anymore.