Refactoring UIKit Storyboards monolith to SwiftUI: Part 1

Ignas Pileckas
4 min readJan 22, 2024

--

Part 1 — Where to start?

It’s late 2023 and I’ve joined AttaPoll as a Solo iOS-dev with one mission — complete AttaPoll iOS app redesign and maintenance.

With this series of blog posts I want to document this journey of the app’s overhaul as I know that a lot of developers worldwide are facing similar problems and I will try to explain my solutions as thoroughly as possible.

AttaPoll connects you with a wide range of companies and organisations that are looking for your views and opinions. Pretty simple, complete tasks (mostly surveys) — earn money. Use this referral link to Sign Up and receive an initial starting bonus!

Current situation

In its history, the app didn’t have a dedicated developer, it was developed by the company’s two founders and later on, if it needed any maintenance some part-time freelance guys would be hired.

During our interviews I got to know that:

  • The app was using only Storyboards (Not a single Xib)
  • AppDelegate had around 1000 lines of code.

And all the other iOS Developer’s nightmare fuel you can imagine. To be honest I did not expect anything else to begin with and all those things looked exciting, at least to me.

Defining crucial pain points

Firstly, before tackling a project like this, you need to evaluate where are the biggest pain points that need refactoring before you start revamping the app with the new design. Imagine you’re building a new house, you won’t be able to add cool features to the house like heated floors, without having a perfectly polished concrete foundation.

Same comes with apps, you need to do some groundwork first before moving on to the cool stuff.

App’s entry point — AppDelegate

Since the app was still supporting iOS 12 (with iOS 17 being just released), there was no SceneDelegate — the app’s entry point was AppDelegate

Remember when I mentioned AppDelegate was around 1000 lines of code? (See Fig. 1)

Fig 1. — AppDelegate class length

Reasoning is it was handling everything and I mean everything. Not only all the startup stuff, but also basically responsible for the whole UI implementation:

Fig. 2 — Navigation Methods in AppDelegate

It was full of methods where it instantiates a new Storyboard and sets one of the ViewControllers of that storyboard to be the UIWindow’s `rootViewController` .

And there were a bunch of places around the App in various Services, DataSources, that call AppDelegate directly to present a storyboard:

Storyboards

And talking about storyboards, every view was in a storyboard:

What this means is that in order to use SwiftUI in the project, we will need to carefully go through these storyboards, create UIViewControllerRepresentables for the ViewControllers inside the storyboards (or for the storyboards themselves). And then use those classes within SwiftUI Views.

Networking

And one more thing that really made my jaw drop was the Networking library it was using. Google APIs Client Library for Objective-C for REST

I haven’t seen this bad boy in ages. Good old Objective-C library with completion blocks. Being used directly in ViewController’s ViewDidLoadlifecycle methods, while in some cases also showing a spinner, completely blocking the UI while the calls are being made. Lovely.

The plan

So, these are the most crucial pain points I could determine upon first inspection of the project:

  • AppDelegate handling UI, direct calls being made to AppDelegate within Services, no coordinator classes.
  • iOS 12 support, No SceneDelegate present.
  • Storyboards, storyboards everywhere.
  • Network calls in ViewDidLoad, ViewDidAppear methods of ViewControllers in Storybards.

Find out in Part Two how are we going to tackle these problems and make some groundwork for the app’s redesign!

https://medium.com/@iPile/refactoring-uikit-storyboards-monolith-to-swiftui-part-2-783acb7c11e8

--

--

Ignas Pileckas

Senior iOS Developer @AttaPoll. Apple WWDC2020 Student Challenge winner.