In 2022, the iOS team at Airbnb decided SwiftUI was sufficiently mature to be adopted for their official app. This required a careful transition, explains Airbnb staff engineer Bryn Bodayle.
The key advantages Airbnb engineers saw in SwiftUI were its flexibility and composability, its declarative nature, conciseness, and idiomaticy, which they hoped could improve developer experience while not losing on the front of user experience.
To make the transition as seamless as possible, they devised a three-phased plan. In a first phase, they would focus on building a collection of reusable components based on their existing design system. In a second phase, they would build entire screens combining basic components. In the third and final phase, screens would be composed together into full features.
Before starting the first two phases, Airbnb engineers conducted a small pilot among engineers who volunteered to try out SwiftUI to gather feedback and improve their infrastructure early on.
As mentioned, the first step was rebuilding the existing design system using SwiftUI based on a series of style protocols that could be instantiated and passed into views using view modifiers. This provided the foundations to allow developers to easily customize UI components with a few lines of code.
The second key step was building an infrastructure to enable bidirectional bridging between UIKit-based Epoxy views and SwiftUI views. The details of how this bridge was built can be found in the original article. Suffice it to say here that this bridge was based on UIHostingViewController to embed a SwiftUI hierarchy into a view controller and UIViewRepresentable to integrate a UIKit view into a SwiftUI hierarchy.
Another fundamental decision Airbnb engineers took was adapting Epoxy's unidirectional data flow to SwiftUI, adopting ObservableOject
as the cornerstore of their state classes to trigger SwiftUI re-rendering for each state change.
We found that engineers preferred to continue to build screens in SwiftUI using this approach, since it enables the business and state mutation logic to be kept separate from the presentation logic.
Testability was also high on Airbnb's list of priorities. Their new SwiftUI implementation needed to match well with their snapshot testing approach. To make this possible, they assigned a name to each view variant they defined, to be used with their snapshot testing service and conformed all view variants to Xcode's PreviewProvider protocol to enable using Xcode Previews. Additionally, they integrated ViewInspector to support behavioural-style tests. ViewInspector allows for traversing a view hierarchy at runtime and providing direct access to the underlying View
structs, thus making their internal state inspectable and enabling simulating user interaction programmatically.
With all that in place, explains Bodayle, Airbnb engineers were able to reduce to approximately a sixth the number of lines of code in comparison with the UIKit implementation, without experiencing any significant performance loss related to SwiftUI reactive nature, except for a small overhead when instantiating UIHostingController
.
There is much more to Airbnb adoption of SwiftUI than can be summarized here, so do not miss the original article for the full details and some useful code snippets.