Shared State: File Storage, Part 1

Episode #275 • Apr 15, 2024 • Subscriber-Only

While user defaults is convenient for persisting simple bits of state, more complex data types should be saved to the file system. This can be tricky to get right, and so we take the time to properly handle all of the edge cases.

File Storage, Part 1
Introduction
00:00
Persistence to file storage
01:42
Debouncing persistence
11:25
Saving on `willResignActive`
15:20
Observing external writes to file system
19:27
Fixing feedback loop
26:50
Next time: Testable file storage
29:58

Unlock This Episode

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

Introduction

Stephen: We have accomplished quite a bit in this series so far. We now have 2 primary methods of sharing state in a Composable Architecture application:

  • We can use a simple, unadorned @Shared property wrapper to represent a piece of state that is passed in from the parent feature, and shares its state with the parent.
  • Or we can provide a persistence strategy to the @Shared property wrapper that describes how we want the state to be persisted to an outside system. This makes it possible to globally share the state with any part of the application without needing to explicitly pass it around, and even persist the data to some external storage. Currently we have two persistence strategies:

    • We have an in-memory persistence strategy that just doesn’t persist data at all. This means you will lose the data when the app re-launches, but that can be fine for many use cases.

    • And we have a user defaults persistence strategy that saves simple data types to user defaults. We even went the extra mile to observe changes to user defaults so that if someone makes a change outside of the @Shared property wrapper we can be sure to update our state.

Brandon: This is all great, but user defaults persistence is a bit limited. It only works for the most basic of data types, such as booleans, integers and strings, and therefore is appropriate for little scraps of data and user preferences.

There are many times that we need to persist far more significant chunks of data, and the easiest place to do that is directly on the device’s file system. And the easiest way to serialize the data to disk is via Swift’s Codable protocol and JSON serialization.

Let’s see what it takes to introduce a 3rd conformance to the PersistenceKey protocol and make file storage a reality in Composable Architecture features.

This episode is for subscribers only.

Subscribe to Point-Free

Access this episode, plus all past and future episodes when you become a subscriber.

See plans and pricing

Already a subscriber? Log in

Downloads