TCA for non-UI components?

I'm trying to use TCA for components that are not UI components. Ideally I would like to just create a Store and observe changes to the state, similar to what the ViewStore does in a SwiftUI context. Since the published state property on Store is internal it cannot be inspected or subscribed to, and the Store itself does not implement the ObservableObject protocol. Am I missing something? Would it make sense to make state public (read-only)? And possibly make Store implement ObservableObject?

Hey Bjorn, you're not missing anything, and it's something that was discussed quite a bit leading up to open sourcing.

The ViewStore is necessary for any type of observation of the state. It's not just for SwiftUI, it is also used in UIKit (see an example here). It can be used in any situation that state needs to be accessed, not just views. Further, if you don't need the store for later scope'ing then you don't even need to hold onto it. You can just hold onto let viewStore = ViewStore(Store(...)) and it will act exactly as you want.

(Aside: The docs are a little misleading right now since they say it's meant for SwiftUI views, but I think that's leftover from when the API was in flux before open sourcing. I will fix it right away.)

The reason we are not exposing the state or send on Store is to make it so that there is only one way to do things in TCA. The Store is for running the business logic of your app, and holds everything to power the app, whereas ViewStore is
for observing state changes and sending user actions.

Does that clear things up?

1 Like

Hi Brandon, that makes sense, and it does indeed do what I need. I got confused by the ViewStore name, the docs, and the location of the source file. Thanks!

If ViewStore is intended for generic use the dependency on SwiftUI should be removed. Will SwiftUI still be autolinked if the binding functions are moved to an extension in a separate file (and never used) and import SwiftUI removed from the ViewStore source file?

I just updated the docs: https://github.com/pointfreeco/swift-composable-architecture/blob/master/Sources/ComposableArchitecture/SwiftUI/ViewStore.swift#L4-L6

And yeah, the file is not in the right spot. We should move it. Thanks for the feedback!

1 Like