Overriding dependencies outside the scope of the ReducerProtocol (e.g. UIButton extension) #12
-
Great job with decoupling Dependencies from TCA! Looking really good :D I do have a question though. Let's say I have a function within a UIButton extension that uses Combine to update the title font whenever @dependency fontMangager.appFontPublisher sends a value down stream: extension UIButton {
func adaptiveFont() -> AnyCancellable {
@Dependency(\.fontManager.appFontPublisher) var publisher: AnyPublisher<MyFont, Never>
return publisher.sink {
// Logic that updates button font
}
}
} Let's also say that these buttons are generated deep within a UIKit app that is all powered by TCA. I would assume that overriding the dependencies here would be reflected in the final class AppDelegate: UIResponder, UIApplicationDelegate {
let store = Store(
initialState: AppMainReducer.State(),
reducer: AppMainReducer()
.dependency(\.fontManager.appFontPublisher, {
print("Oh hi there!")
return Just(.Ubuntu).eraseToAnyPublisher()
})
)
Specifically, I expect to see the "Oh hi there!" message appear in the console because I was overriding that dependency within a very high-level reducer. However, I only see that the live value is being used. Am I just really abusing @dependency here? While I can certainly override the dependencies with "withDependencies", to me it makes more sense to override all dependencies in the same place instead of searching for the UIButton extension, finding the |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 3 replies
-
Hi @acosmicflamingo, what you are trying to accomplish is not immediately possibly unfortunately. And the reason it is not possible is because dependencies are built on the back of I highly recommend you read the following articles from the documentation to get a deep understanding of why: So, it's not a limitation of the library, but rather a core tenet of how the library is designed. When you access The only for your |
Beta Was this translation helpful? Give feedback.
Hi @acosmicflamingo, what you are trying to accomplish is not immediately possibly unfortunately. And the reason it is not possible is because dependencies are built on the back of
@TaskLocal
which has very strict rules for how you are allowed to change a value.I highly recommend you read the following articles from the documentation to get a deep understanding of why:
So, it's not a limitation of the library, but rather a core tenet of how the library is designed.
When you access
@Dependency
from theUIButton
, you are doing so in a scope that is completely untethered to the scope where the original dependencies were set, and…