Our SwiftUI story starts with a Native iOS app. After several iterations and releases, in order to follow the latest technology changes, we decided to adopt SwiftUI. Our goal with adopting this new technology was to future-proof our application because we were anticipating an email from Apple with something along the lines of “we’re deprecating UIKit”.
Engineering Excellence and SwiftUI
One of the mobile team’s pillars of engineering excellence is productivity. We ask ourselves questions such as: Am I writing extendable, flexible code, or am I just doing a one-time job to make code work?
We want our code to be agile and flexible so we can quickly and seamlessly adapt to the latest technologies. In turn, our agility makes for better products and better performance. We want to focus on spending enough time upfront on building the system in the most efficient and useful way.
We planned to benefit from SwiftUI in the following ways:
- Less code for UI. If you’re familiar with UIKit, then you know that your UI will have several files for each view controller. Especially XIB files and source code. It’s common to see a storyboard file with many view controllers and one source file per view controller. With SwiftUI, there is a single Swift file for each view.
- Preview while making UI. SwiftUI Previews allow us to increase our development speed. Previously to see your changes, you had to build source code and deploy it on the simulator to check each time. Now we can have a preview of our views live in Xcode.
- Have native code for all Apple platforms, which is especially useful if we decide to support different Apple platforms. No platform-specific code means easy adaptation in the future and less platform-specific maintenance.
Practice and Planning
“A journey of a thousand miles begins with a single step” – Lao Tzu
As with starting other large-scale new initiatives on my team, we divided SwiftUI adoption into small, manageable chunks. We began by researching and prototyping simple UI elements to understand the principles of our new approach. Since we weren’t working from scratch, we prototyped SwiftUI module integrations into our existing project.
Our preferred resources for moving to SwiftUI were Apple’s documentation and raywenderlich.com, which contains high-quality iOS tutorials. We learned the UI elements that SwiftUI offers, chose the components we wanted to use, and built some simple screens.
After some practice prototyping and building screens, we created a roadmap for our integration of SwiftUI. Our initial integration started with creating simple UI components. Then we built view controllers containing only text, images, and buttons. Finally, we committed to implementing all future simple views in SwiftUI.
Issues and Learning
“The real world is where the monsters are.” ― Rick Riordan, The Lightning Thief
Though we read quite a bit of documentation and performed experiments, we didn’t expect a smooth transition to SwiftUI. We had realistic expectations and an alternative strategy. Namely, we would use UIKit where SwiftUI could not meet our requirements or not solve our problems.
After successfully migrating several simple view controllers, we started migrating more complex views. With this, we faced SwiftUI issues for the first time related to the number of UI elements in a view. The errors arose when we implemented a complex view with many horizontal and vertical grids, buttons, labels, and collections. After a bit of research, we found that it’s impossible to add more than ten views in a single view. We learned that we need to group ten or less UI elements together and use them inside the view body.
SwiftUI was first introduced for iOS 13. We saw a new version of it with the release of iOS 14. Our team was aware that some new UI components were available only for SwiftUI 2.0 and decided to use components from version 1.0. Using components from version 1.0 helped us keep our minimum deployable target.
During development, we continuously tested our application on the latest iOS simulator (iOS 14 at the time). However, when we ran and tested the application on iOS 13, we found a broken UI. All UI elements were on the view but had the wrong sizes and alignments. We did some research and found that this is known behavior. Here, we employed our alternative strategy and left UIKit in place for the broken views.
“Conclusions are not always pleasant.” ― James W. Loewen
Our migration experience didn’t align fully with the examples from our research. We concluded that SwiftUI is currently not mature enough for us to migrate fully from UIKit to SwiftUI. We stopped at a partial migration for now.
We found it hard to make complex UIs with this new technology without proofing each module step-by-step and without proofing the system as a whole. Sometimes during the development of even simple UI, we faced hidden surprises and paused development to continue researching.
SwiftUI’s rollout is very similar to the introduction and spread of Swift. Swift was modified quickly at first, then stabilized and was ready for mature projects after several releases. We believe that SwiftUI will face the same evolution and, after a few releases, will be fully ready to replace UIKit.