Your iOS codebase should be using (or should be in the process of moving to) SwiftUI. Here’s why.

João Pedro de Amorim
ProFUSION Engineering
5 min readAug 31, 2022
Credits: SwiftUI Cheat Sheet

Here @ ProFUSION, we’ve done a series of projects using Apple’s SwiftUI and we’re really impressed on how fast and efficient it can be for UI development. In order to spread its word even further within the iOS community, in this article I’ll be tackling the most common outdated arguments against SwiftUI and do a pitch in favor of it.

A big disclaimer is that I’m not saying that your whole app should be in SwiftUI. The article’s point is that the View layer of your architecture should be using SwiftUI.

Arguments against SwiftUI

1) SwiftUI is not production ready — it lacks all the features/APIs that UIKit has

I have to agree with the second part of the argument — yes, as a matter of fact, SwiftUI does not have everything that UIKit does, and it might be the case that you app need a specific missing API in SwiftUI. But, the funny part is, it doesn’t need to have all the features from UIKit it order for it to be production ready!

SwiftUI interoperates seamlessly with UIKit. If your SwiftUI codebase is missing a UIKit API call, the solution is simple enough: override to UIKit for that specific segment of the code. A key example is the usage of UIViewController-based APIs, which in SwiftUI can be easily achieved by using a UIHostingControler. Simply said, a UIHostingController is a UIViewController that instead of using a UIView as its view, it'll use a SwiftUI view instead. Voi-là! Now you have access to the whole VC's lifecycle (viewDidLoad, viewWillAppear, etc) while still on SwiftUI. Neat, isn't it?

But sometimes you want to access a UIKit functionality for a specific visual element and their SwiftUI correspondent does not have that functionality yet (or you just want to do the old way, for a number of reasons). For example, let’s suppose you want to listen to scrollViewDidScroll(_ scrollView: UIScrollView) from a ScrollView within SwiftUI - but, as you'd expect, there's no UIScrollViewDelegate in SwiftUI. The solution for this one is to use a widely adopted library in SwiftUI projects, Introspect. For the example given, the related snippet would be:

Another scenario is one in which you want to port a UIKit element in its entirety to SwiftUI. This can be achieved by implementing either the UIViewRepresentable — if you want to expose a UIView type to SwiftUI or UIViewControllerRepresentable - if you want to expose a UIViewController type. This simple snippet from Hacking with Swift shows how simple it can be to expose, for instance, a UITextView:

And use it in SwiftUI as:

I think that the methods above account for all use cases and give full exposure to the UIKit API from within SwiftUI, but if none of that works, hey, just do a UIViewController with a UIView for that very specific case.

2) It’s not feasible to implement common navigation/architectural patterns in it (e.g. Coordinator)

I know, SwiftUI’s native navigation system is a mess (I could do a 10 page rant on why NavigationView is a mess) - a fair share of improvements are on the way with iOS 16 (with the new NavigationStack, for instance), but I doubt it'll be better than the Coordinator pattern.

Nonetheless, as mentioned earlier, the UIHostingController gives us an immense flexibility to work with SwiftUI, so one can replace the UIViewControllers by UIHostingControllers in your Coordinator implementation and nothing will change - after all, a UIHostingController is a (it subclasses) UIViewController, so, in the end, nothing has changed (the inner UINavigationControllers will be able to push your controllers as usual - you still have access to all of the API so, really, nothing needs to be done).

That extends to other UIViewController-reliant architectures: The change to UIHostingControllers introduces no side-effects or major refactors.

3) I can’t dispose of my existing UIKit views / I can’t migrate all of my existing UIKit views to SwiftUI now

Yes, and you definitely don’t need to. As mentioned, the star of our show here, UIHostingController is able to coexist peacefully with your existing UIViewControllers and their respective UIViews.

For a first effort in adopting SwiftUI, what I suggest to be done is to start, for new features, using UIHostingControllers with SwiftUI views instead of UIViewControllers and UIViews, and, incrementally, you can start migrating your old views to SwiftUI. If it's too much of an effort for your team, just start enforcing SwiftUI for new modules/features and maintain your UIKit legacy codebase, there's really no problem in doing that as well.

4) Because of my userbase, I need to support a vast variety of iOS versions

That might be the case, but this argument falls even shorter for each major iOS release. As of July 2022, from GlobalStats statcounter, the only iOS version with a considerable userbase that does not support SwiftUI is iOS 12.5, at 3.02% of the market share. But this a general view and each app’s userbase is a case on its own, but one thing is for sure: the tendency is for the number of devices that do not have SwiftUI support (introduced in iOS 13) to shrink more and more for each major iOS release.

SwiftUI is easier to maintain, less error-prone and faster to develop in

“Write less, do more” — JQuery's is one of the most recognizable slogans in computing and I think it describes SwiftUI perfectly. If you do embrace SwiftUI’s declarative programming, that’s exactly what you’ll get. One very concrete proof of this statement is the comparison done by @rmeji1 in this great article comparing two equivalent snippets of code, one in UIKit and the other in SwiftUI. The UIKit example is about 50 (discarding the header) lines long, where the SwiftUI one barely reaches 10.

Less code in your codebase means less code to maintain. Less code means that are fewer places to commit mistakes. Less code to write to achieve the same result means that it can be done faster and more efficiently.

Biggest reason on why SwiftUI is not adopted in some codebases

Software engineering, contrary to what we all would like, is not an exact science. The architectural and management decisions do need to account for the human factor in our area. Humans are hardwired to resist change and I can see the developers’ resistance to a new framework playing the biggest role in adopting it or not. But, there’s a latin saying that I like a lot: “Fortune favors the bold” — those who are willing to get out of their comfort zone in technology are the ones who drive change and conquer spots that beforehand were deemed impossible.

Conclusion

With everything in place, I reiterate the title’s statement: your iOS codebase should be using (or should be in the process of moving to) SwiftUI. It’s a pretty solid UI framework that admits UIKit fallback options whenever necessary. Have you moved your codebase to SwiftUI? Are you enjoying the developer experience? Let us know!

--

--