nalexn / clean-architecture-swiftui

SwiftUI sample app using Clean Architecture. Examples of working with CoreData persistence, networking, dependency injection, unit testing, and more.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Question: AppState Scalability and Encapsulation

fernandocardenasm opened this issue · comments

It´s difficult for me to see how the AppState is scalable, if you have many screens, and each screen has specific and shared states, it would require that I create nested structs in the AppState to make it more modular, but it will also make it bigger. How maintable and scalable do you think the AppState is?

The previous leads to my next point. In a View you have the store as a property, and if you need a specific nested state you may end up with e.g. store.wallet.payment.cashback.cards. Is there a better way?

Last but not least, each View knows too much about all the states, and I would like that it only knows about the specific states it needs. How would you adress this?

I will not argue on the point that keeping all state in one place is not the silver bullet, thus it has to have its downsides, like the ones you mentioned. However, this concept isn't new and has been used in various schemes like REDUX and has proven to be maintainable and scalable enough, with the requirement of proper naming and scoping of the variables under sub-containers.

I agree that long paths to the state can be cumbersome, so you can always shrink it with a computer property defined in the scope of the screen, like here.

There several options for how this can be achieved, depending on the use case. We can use WritableKeyPath, computer properties with getter and setter, a wrapper structure that internally retains access to the AppState but outside provides API for accessing only variables for this particular screen, a protocol that outlines limited state accessibility scope with AppState conforming to this protocol, maybe some other.

A radical another way to address the scoping problem is to introduce several DIContainers with independent AppStates and a set of Services. They will use different @Environment injection points, where the screens will have to explicitly declare that they need access to one scope or another.