🎉 Black Friday Sale! Save 30% when you subscribe today.

Composable SwiftUI Bindings: Case Paths

Episode #108 • Jul 13, 2020 • Subscriber-Only

Now that we know that SwiftUI state management seems biased towards structs, let’s fix it. We’ll show how to write custom transformations on bindings so that we can use enums to model our domains precisely without muddying our views, and it turns out that case paths are the perfect tool for this job.

Previous episode
Composable SwiftUI Bindings: Case Paths
Next episode
Locked

Unlock This Episode

Our Free plan includes 1 subscriber-only episode of your choice, plus weekly updates from our newsletter.

Sign in with GitHub

Introduction

However, there is clearly something not quite right about what we have done because we made quite a few strange decisions along the way. We created properties on the Status enum to project out certain information from it, but in each case that information only made sense for one of the cases. This forced us to make some choices, and it wasn’t clear that we were making the right choice. And if we ever added a third case to this enum or choices will only increase.

So what we are seeing here is that although we better modeled our core domain to properly use an enum that precisely describes the two states our item can be in, we have also accidentally destroyed all of that preciseness by trying to project out state-specific information from the general enum for our views.

And this is happening for one really important reason: quite simply, Swift favors structs over enums.

This is something we have talked about a ton on Point-Free. Swift gives first class support of many concepts and techniques for structs for which there is no corresponding story for enums. We have explained over and over again that structs and enums are really just two sides of the same coin, and any concept we introduce for one we should try searching for the corresponding concept for enums.

In this case what we are seeing is that SwiftUI simply does not give us the tools for dealing with state that is modeled as an enum. All of the tools it gives us are heavily embedded in the world of structs and product types, which leads us to trying to shoehorn tools made for structs into the world of enums.

And so without those tools we keep instinctively turning to methods of classic encapsulation to preserve invariants of our model rather than fully leveraging the benefits of structs and enums to make invalid states of unrepresentable. The idea of encapsulation is drilled into us at a very early stage as programmers as the proper way to manage complexity, but here we are seeing that even if we try to put a nice public interface over the core model we can still have complexity leak out and infect our view.

Binding transformations


References

  • CasePaths
    Brandon Williams & Stephen Celis

    CasePaths is one of our open source projects for bringing the power and ergonomics of key paths to enums.

  • Collection: Enums and Structs
    Brandon Williams & Stephen Celis

    To learn more about how enums and structs are related to each other, and to understand why we were led to define the concept of “case paths”, check out this collection of episodes:

    Note

    Enums are one of Swift’s most notable, powerful features, and as Swift developers we love them and are lucky to have them! By contrasting them with their more familiar counterpart, structs, we can learn interesting things about them, unlocking ergonomics and functionality that the Swift language could learn from.

  • The Many Faces of Map
    Brandon Williams & Stephen Celis • Apr 23, 2018

    To get a better understanding of the map function and how it relates to dynamic member lookup on the Binding type, catch this early episode.

    Note

    Why does the map function appear in every programming language supporting “functional” concepts? And why does Swift have two map functions? We will answer these questions and show that map has many universal properties, and is in some sense unique.

Downloads

Get started with our free plan

Our free plan includes 1 subscriber-only episode of your choice, access to 64 free episodes with transcripts and code samples, and weekly updates from our newsletter.

View plans and pricing