Swift Combine publisher won't trigger in flatMap after finished event

I'm trying to create a refresh event using CurrentValueSubject while making a network call. So whenever network request fails I can press the button to make the request again, but can't make it work as failure event will terminate publisher and it won't work again.

import Combine
import SwiftUI

struct ContentView: View {

    @ObservedObject var viewModel: TestViewModel = TestViewModel()

    var body: some View {
        Button("Test", action: viewModel.test)
        Button("Refresh", action: viewModel.refresh)
    }
}

class TestViewModel: ObservableObject {

    var bag = Set<AnyCancellable>()
    private let changeSubject = CurrentValueSubject<Void, Never>(())

    func test() {
        changeSubject
            .flatMap { self.networkPublisher }
            .sink(
                receiveCompletion: {
                    switch $0 {
                        case .failure:
                            print("Failure")
                        case .finished:
                            print("Finished")
                    }
                },
                receiveValue: {
                    print("Value: \($0)")
                }
            )
            .store(in: &bag)
    }

    func refresh() {
        changeSubject.send(())
    }

    var networkPublisher: AnyPublisher<String, Error> {
        var url = URLRequest(url: URLComponents(string: "www.google.com")!.url!)
        url.httpMethod = "GET"
        return URLSession.shared
            .dataTaskPublisher(for: url)
            .tryMap { _ -> String in "Result" }
            .receive(on: DispatchQueue.main)
            .eraseToAnyPublisher()
    }
}

To fix this I could use .tryCatch { _ -> Just<String> in Just("Error") } to catch the error and that would prevent the publisher from terminating. But why it wouldn't create a new publisher inside flatMap each time?

Terms of Service

Privacy Policy

Cookie Policy