Hey,
I currently do have some Issues related to long living effects.
To give you some background:
I created a Dependency to observe a specific value from the UserDefaults.
It returns an AnyPublisher we can subscribe to, to get notified when the value changes.
enum CardMode: String, Codable, CaseIterable {
case expanded
case collapsed
}
struct CardModeProvider {
var cardMode: () -> CardMode
var cardModePublisher: AnyPublisher<CardMode, Never>
var storeCardMode: (CardMode) -> Void
}
extension CardModeProvider {
static let live: CardModeProvider = {
return Self(
cardMode: {
CardMode(rawValue: UserDefaults.sharedGroupDefaults.cardMode) ?? .expanded
},
cardModePublisher: UserDefaults.sharedGroupDefaults
.publisher(for: \.cardMode)
.map { CardMode(rawValue: $0) ?? .expanded }
.eraseToAnyPublisher(),
storeCardMode: {
UserDefaults.sharedGroupDefaults.cardMode = $0.rawValue
}
)
}()
}
private enum CardModeDependencyKey: DependencyKey {
static let liveValue = CardModeProvider.live
}
extension DependencyValues {
var cardModeProvider: CardModeProvider {
get { self[CardModeDependencyKey.self] }
set { self[CardModeDependencyKey.self] = newValue }
}
}
Inside the reducer I observed the value changes using eraseToEffect:
func reduce(into state: inout State, action: Action) -> EffectTask<Action> {
switch action {
case .onAppear:
return cardModeProvider.cardModePublisher.eraseToEffect {
.updateCardMode($0)
}
}
}
it works like a charm but after I took a look into the Docs I discovered that it is recommended to use .run
and for await value in sequence
for that. So I tried to do that.
.run { send in
for await value in cardModeProvider.cardModePublisher.values {
await send(.updateCardMode(value))
}
}
But unfortunately I doesn't work as expected.
It will get triggered once, but each time I change the value in the User-Defaults the action will not get send.
I first assumed that my publisher was cancelled or completed somehow under the hood so I tried to investigate using handleEvents.
static let live: CardModeProvider = {
return Self(
cardMode: {
CardMode(rawValue: UserDefaults.sharedGroupDefaults.cardMode) ?? .expanded
},
cardModePublisher: UserDefaults.sharedGroupDefaults
.publisher(for: \.cardMode)
.handleEvents(receiveCompletion: {
// ...
}, receiveCancel: {
// ...
})
.map { CardMode(rawValue: $0) ?? .expanded }
.eraseToAnyPublisher(),
storeCardMode: {
UserDefaults.sharedGroupDefaults.cardMode = $0.rawValue
}
)
}()
But it turned out that none of those publisher events occur.
Does anyone maybe has an idea what I am doing wrong?