Bringing the Best of SwiftUI to Our Team's UIKit Code
Article Summary
Victor Pavlychko from Grammarly tackles the challenge every iOS team faces: loving SwiftUI's elegance but being stuck with years of UIKit code. His solution? Reverse engineer SwiftUI's best features into their existing codebase.
Grammarly's iOS team needed to support iOS versions older than 13, couldn't abandon their massive UIKit investment, and wanted SwiftUI's developer experience improvements. They systematically refactored their UIKit code to adopt SwiftUI's declarative patterns and live preview capabilities.
Key Takeaways
- Created LayoutPins enum to replace 90% of messy Auto Layout constraint code
- Built hierarchical view wrappers so code indentation mirrors UI hierarchy like SwiftUI
- Solved SwiftUI preview crashes by converting static frameworks to dynamic libraries
- Extracted view logic into single fill(with:) methods for cleaner data updates
- Fixed duplicate symbol issues by making all dependencies dynamic for live previews
Grammarly successfully brought SwiftUI's declarative syntax and live previews to their UIKit keyboard extension without rewriting existing code.
About This Article
Grammarly's UIKit codebase had messy subviews and mixed Auto Layout constraints with configuration logic. The viewDidLoad() methods were cluttered with layout code, network calls, and system event subscriptions all in one place, making it hard to maintain.
The team built a ContentViewController base class that overrides loadView(). They created a LayoutPins enum to generate constraints and added generic addSubview wrappers with configuration closures. This structure matched the actual UI hierarchy in code.
The LayoutPins enum handled about 90% of the project's layout code. Moving initialization from init methods to setupView() let developers iterate with live preview without rebuilding the entire project.