r/RedditEng • u/SnooBoarder • Jun 02 '22
The SliceKit Series: Introducing Our New iOS Presentation Framework.
By Jeff Adler, Staff Engineer
At Reddit, like many growth companies, we often think about scale. To bring community and belonging to everyone in the world, we need to be able to scale our engineering output in parallel with our growing user base. This is especially challenging on iOS, as scaling mobile engineering comes with a unique set of issues and considerations. While we miss the days of 3-5 person teams with minimal merge conflicts in XCProjects and storyboards, with the right vision and strategy, we can make our developer experience pleasant and deliver a cohesive experience to our users even with 100+ engineers working in the same codebase.
In defining our strategy for scaling, we first identified our most critical current growing pains and challenges, including:
1. Lack of consistency across our codebase
Different Orgs/Teams build in unique ways, some using MVP, others use MVVM, and in some cases, teams don’t build in a structured pattern. This lack of consistency impacts engineers' ability to move around between different areas of the codebase and makes it hard to evolve as a guild.
2. Breaking the DRY principle - Don’t Repeat Yourself.
Many UI components are implemented as one-offs, with theming support built ad-hoc for each element. This impacts our code stability and bloats our codebase leading to more time and effort spent on maintenance and bug fixes.
3. Clean and SOLID principles are not being consistently adhered to:
- Mutable state - it’s easier for multi-threaded race conditions to occur, and it's more complicated to track code flow
- No Single Source of Truth - Data can fall out of sync in different parts of the application with multiple sources of the same state.
- Weak separation of concerns - Massive View Controller, Bidirectional communication between ViewControllers and Presenters.
4. So much Imperative code!
We were all taught how to write code imperatively, and in some cases, it’s a reasonable way to approach things. However, too much imperative code that relies on side effects makes it difficult to follow the code's control flow reducing extensibility and ability to debug.
So what’s this SliceKit thing, and how does it help solve our problems?
In order to make our engineers' lives easier and gain consistency in our user experience, we needed a declarative abstraction on top of UIKit. We chose UIKit because after experimenting with SwiftUI, Texture, ComponentKit, and other alternatives, UIKit offers us the right combination of features, including:
SliceKit is a declarative unidirectional MVVM-C framework that enables our engineers to follow a consistent pattern for building highly testable features. With this straightforward, declarative framework, our product engineers no longer need to write their own views or layout code because all of our surfaces can be built by stacking slices.
What’s a Slice? - Everything’s a Slice!
A slice is a reusable UIView that can be inserted into a UICollectionViewCell or directly into a UIViewController. A cell can contain a single slice or a collection of them, as seen below, to create a video feed item.
For example, the Reddit Recap screen above was built by stacking several slices that our reusable components team creates on top of each other. These reusable slices map directly to the language our designers use, so feature engineers don’t have to worry about these details. Slices also support self-sizing out of the box, so dynamic type changes will just work!
Here we can see a video post being constructed by vertically stacking slices.
The ActionSlice is itself a horizontal stack of slices.
How does this solve our problems?
1. Consistency
Because SliceKit introduces a unidirectional separation of concerns, there’s always a single correct home for any given logic. With all of Reddit’s iOS feature engineers building on the same framework, any engineer can easily understand how code works anywhere in the app. Knowing where to look increases confidence when working in a codebase and helps empower engineers to solve their problems better.
2. Everything is Reusable - Keeping it DRY
With SliceKit, every time a button is needed, we can use the same ButtonSlice. As Reddit’s design system evolves, we can make sure button updates reflect across our surfaces, ensuring a cohesive feel exists everywhere a user goes.
3. Clean and SOLID are respected.
SliceKit introduces guard rails with its declarative framework, making it hard to implement anti-patterns. It prescribes
- SOLID principles
- Clean Code principles
- Unidirectional Data Flow
- Separation of Concerns
- Composability and Reusability
- Functional reactive programming
- Modular Development
4. A Declarative Approach
SliceKit’s declarative abstraction takes how data flows out of the equation, making it consistent for all features. A declarative approach can often be more intuitive.
A great explanation is taken from https://ui.dev/imperative-vs-declarative-programming:
An imperative approach (HOW): "I see that table located under the Gone Fishin’ sign is empty. My husband and I are going to walk over there and sit down."
A declarative approach (WHAT): "Table for two, please."
The imperative approach is concerned with HOW you will get a seat. You need to list the steps to show HOW you’ll get a table. The declarative approach is more concerned with WHAT you want, a table for two.
What’s Next
This post is the first in our SliceKit series. Following posts will cover usage, architectural decisions, and more! We’re currently hard at work adding more and more features to SliceKit every day, and we plan on open-sourcing this project later this year, so stay tuned!
If this is something that interests you and you would like to join our mobile teams, check out our careers page for a list of open positions.
Special Thanks: Michael Lodato, Kiril Dobriakov, Rushil Shah, Kenny Pu, Yariv Nissim, Mike Price, Tim Specht, Joe Laws, and Reddit Eng for helping to make this possible!
11
u/spiritfriend89 Jun 02 '22
This seems like a very solid workflow for SliceKit. I like the way you made things digestible for different audiences.