There’s a large complex problem that we all grapple with when making applications, but it’s not often addressed head on and given a systematic study. Our applications are built as large blobs of state, which represents the actual data of the application, and behavior to evolve that state over time. Now this big blob of data and behavior is extremely difficult to understand all at once. It’s of course all there, even if some parts are hidden away in little implicit chunks of state and behavior, but ideally we could cook up tools and techniques that allow us to understand only a small part of the application at once.
Doing this comes with huge benefits. Things like improved compile times, allowing yourself to build and run subsets of your application in isolation, strengthening the boundaries between components to make them more versatile, and more. We’ve definitely harped on these concepts over and over on Point-Free, but there’s still more to say.
We want to explore the heart of this problem from first principles. We’ll start with a vanilla SwiftUI application that has two separate screens, each with their own behavior and functionality, but they also need to share a little bit of functionality. Further, the parent screen that encapsulates the two children also wants to be able to observe the changes in each of the children.
This is a surprisingly subtle interaction to get right, especially in vanilla SwiftUI. The crux of the problem is that we want to be able to bundle up most or all of our application’s behavior into a single object, and then derive new objects from it that contain only a subset of the behavior. So, we could take the root application domain and derive smaller and smaller domains. For example, we take the app-level object and derive an object for just the home screen, and then further derive from that an object for the profile screen, and then further derive from that an object for the settings screen, all the while these derived objects will stay in sync with each other so that the changes in one are instantly reflected in the others.
Now, if you are a user of our Composable Architecture library this all probably sounds very similar to the concept of Store
s and .scope
s, and you’re right, but we want to use vanilla SwiftUI as a jumping off point to dig even deeper into those concepts.