The Environment is a great concept, but in practice I've been having some trouble working with it.
Let's say we have the following two modules
Foo is the parent of
FooDetail operates on a scoped version of
Foo's store (and we have the appropriate pullback setup in
Foo's reducer to subscribe to
We want to subscribe to Reachability events in both
FooDetail, so this seems like the perfect time to use
PathMonitorClient from your Designing Dependencies: Reachability episode. Now the question is where does this dependency live and how do we get access to it within our
Reducer to handle reachability events?
Problem with Environment:
Although intuitively it might make sense to put this dependency in the environment, it actually ends up not being such a good idea because of how often the Environment's .init gets called (a consequence of initializing the environment within a closure that is never retained). This ends up creating some constraints in my implementation that seem less than ideal and for me work against my intuition on how I would expect the
Environment's lifecycle to work. My implementation has the subscription happening right when the view first appears, but when the
Store gets sent a follow up action, the subscription gets cancelled because the
Environment.init gets called, resulting in a new instance of
PathMonitorClient. Problem is now the subscription is gone and no event is resubscribing to
PathMonitorClient only once (on initialization of
FooDetail respectively). Rely on PathMonitorClient to cancel the subscription whenever
receiveCancel is called on the
PassthroughSubject within the combine publisher, which would happen when the view is deallocated. This would require the
Environment's lifetime to be as long as the
To get the behavior I'd expect it would require that I end up putting the
PathMonitorClient within state rather than having it in the
Environment. Alternatively I could either A) Make PathMonitorClient a singleton or B) Make it a class type and have it's reference held in memory by something that isn't the
Environment. Downsides to A and B are that I'd have to manage the unsubscribe myself vs allowing ARC to handle it for me in a way that I would expect.
Environment designed to be initialized so many times, has there been any thought to maybe change the lifecycle of it? And a follow up: what are the recommended use cases for storing things in the
Environment? Seems to me that right now only singletons and cheap stateless dependencies are what make sense?