How I Refactored a (Massive) MVC iOS App? (Part 4)

Tadeh Alexani
Formaloo
Published in
3 min readMay 11, 2020

Don’t forget to read part 3 before moving to this article.

So let’s finish up our refactoring process by refactoring our data source and delegate protocols.

Refactoring Table View Data Source/Delegate

As the easiest solution, what I did, was moving just the data sources in new classes. Why I didn’t move my delegate?

Because the delegate needs to talk to its data source and it can cause more complex code which is against refactoring our code. Also, the difference between delegate and data source functions is confusing. For example, the titleForHeaderInSection is in data source whereas viewForHeaderInSection is in delegate 🥵

So let’s refactor our data sources:

First, go to the File menu and choose New > File. Select Cocoa Touch Class from the list that Xcode offers you, then press Next. Make it a subclass of NSObject, give it the name “YourModelDataSource”, then click Next and Create.

Now move every data source functions to the new class, finally, it should look like something like this:

class ClinicListDataSource: NSObject, UITableViewDataSource { var clinics = [Clinic]() func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {  return clinics.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {  let cell = tableView.dequeue(ListClinicTableViewCell.self, for: indexPath) as ListClinicTableViewCell  let clinic = clinics[indexPath.row]  let viewModel = ClinicViewModel(model: clinic)  cell.setupWith(viewModel)  return cell } func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {  return ListClinicTableViewCell.height }}

Not that we also moved our array of objects and make our class confirming the UITableViewDataSource protocol.

Now in your view controller file, the only 2 things you should do is first, declaring an instance of this data source class, e.g.:

var dataSource = ClinicListDataSource()

then replacing all the object model arrays with dataSource.arrayOfObject (E.g. clinics.removeAll() -> dataSource.clinics.removeAll())

And the second is assigning the new data source to your table view outlet like this:

self.tableView.dataSource = dataSource

Note: Don’t forget to remove the old data source from your table view if you connected it via storyboard or in the code itself.

Expand this for any controller in your app and you are DONE! 🙌

Bonus Part!

As you may see through the refactoring process bunch of crashes can happen in unexpected ways. I know that the best solution is writing tests for this situation but if you don’t have time or the company doesn’t give you the needed resource to write tests (especially unit tests) I suggest you use at least one crash logger or reporter tools, whether it’s test flight built-in crash reporter or frameworks such as Instabug, Crashlytics or App Center by Microsoft.

Conclusion 🎉

Congrats making to the end of the fourth and final part of refactoring Massive MVC apps. In this series of articles, my only point was to share my 2 weeks' experience with you. I can say that these 4 parts are the gist of what I learned from different articles anywhere on the internet so you can just search for the title if you find some parts in these 4 parts not explained well.

If you have any questions or just want to contact me you can find me on Linkedin and Twitter, or you can just post it below. Good luck!💡

--

--