Execute an action onDisappear #2891
-
Hi there community. I've been reading a lot about cancellation and onDisappear action execution with TCA but I haven't found yet one that explains what to do if I need to close some resource. Lets take the following example from StarMicronicsSDK:
So, whenever the view disappears I need to stop monitoring the device and sending an action when event .onDisappear triggers may lead to a warning/error from TCA that a state was executed when child was nil. The app right now displays a list of printers you can pick from and navigates to a detail view where it starts monitoring as I mentioned earlier. Here comes my question, how can I stop monitoring when user goes back (they pop from the stack) or when the view disappears? Here is some code I can share to give you guys a hint: Reducercase .startMonitoring:
return .concatenate(
.send(.detectPaperWidth),
monitor.startMonitoring(state.printer.id)
)
.cancellable(id: CancelID.cancelScanning, cancelInFlight: true) View.task {
await self.store.send(.startMonitoring).finish()
}
.onDisappear {
self.store.send(.stopMonitoring) // This is NOT the way
} Parent Reducer logic:...
var path = StackState<HardwareDetailFeature.State>()
...
case path(StackAction<HardwareDetailFeature.State, HardwareDetailFeature.Action>)
...
.forEach(\.path, action: \.path) {
HardwareDetailFeature()
} Parent ViewNavigationStack(path: $store.scope(state: \.path, action: \.path)) {
....
NavigationLink(state: HardwareDetailFeature.State(
printer: printer,
printerIsConnected: true
)) {
EmptyView() // Just a hack to avoid the swiftui chevron and use my own
} System:
|
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 4 replies
-
This happens automatically when using |
Beta Was this translation helpful? Give feedback.
Yes, the effect being cancelled is all you need. If your effect is constructed using a Combine publisher then you can use something like
.handleEvents
orAnyCancellable
to detect cancellation and clean up resources. Or if you are use Swift's async tools then you can use something likeonTermination
fromAsyncStream.Continuation
orwithCancellationHandler
.Essentially it's your job to tap into cancellation in the effect and do the clean up. All the library needs to do is cancel the effect.