CoreData, TCA and higher order reducers

Our app uses CoreData as its data store. I'm trying to keep the app state completely ignorant of its backing store, so mutating actions below the top level don't know about the DB.

I have a higher order reducer that looks at mutations that need to be persisted. My concern is that this approach creates fairly deeply nested case statements, and these add up, even when the same child view types are reused.

For example, to 'monitor' a file downloaded from one of our views:

case let .homeView(.episodeRow(
  .episodeCards(id: episodeId, action: 
  .downloadComponent(.downloadClient(.success(.response(fileURL))))))):
    print("Episode \(episodeId) file downloaded \(fileURL)")

I am curious about opinions on this approach. Alternatively, I can just one-shot load / save the full app state from the DB (this gets more complicated when we introduce iCloud syncing, but I understand that's a different set of complexities).

Thanks.

Modifying the database is a side effect so my first thought would be to model mutations to the database as side effects triggered in the reducer that normally handles the action. This keeps your CoreData decoupled from your views but still allows the view to be in control of the interaction. If a record failed to insert for instance it's easy for the side effect to return an error to the reducer which can update the view accordingly.

5 Likes

Thanks, I kept trying to do it all at the top level, but that just added complexity. All my database calls are already side effects, so doing them locally where the action takes place certainly makes it very straight forward. That's the nudge I needed. :stuck_out_tongue_winking_eye: