Hello, enjoying TCA architecture so far.
I have a question related with achieving similar goal with CombineLatest in TCA. Let's say when the splash screen appears, the screen must be shown to the user for at least 3 seconds, and while the splash screen is shown, the app throws an effect that contains an api call to get user information. So there can be 2 cases:
- When the getUser response comes within 3 seconds, we wait until the minimum 3 seconds to pass and move on.
- When the getUser response comes after 3 seconds, we move on as soon as we receives the response.
I know that this can be done by changing a state variable(e.g. threeSecondsPassed, gotUserResponse boolean) when 3 seconds has passed and the response is received respectively and whenever we receive a response we can check if both state variable are set to true and move on. However, I want to implement a cleaner solution like using combineLatest so that we can call an action to move on whenever we receive respective values from timer publisher, and getUser response publisher. I also know that the easiest way is to put a delay 3 seconds on receiving the response, but in this way we have to wait more than 3 seconds. Below is the pseudo code I initially thought, after checking Timer example in the case study:
//inside reducer
case .onAppear: //called when splash view is shown
let combinedPublisher = Publishers.CombineLatest(
Effect.timer(id: TimerId(), every: 3, tolerance: .zero, on: environment.mainQueue).eraseToAnyPublisher(),
environment
.userClient
.getUser()
.subscribe(on: environment.backgroundQueue)
.receive(on: environment.mainQueue)
.catchToEffect()
.eraseToAnyPublisher())
return combined
.map { (time, response) -> Result<User, Error> in
return response
}
.eraseToEffect()
.map(AppAction.userResponse) //userResponse is the action used to move on from splash view
However, this code doesn't work as we can't get the response from the combinedPublisher. What would be an ideal implementation to tackle this in TCA?