Created
September 18, 2025 17:07
-
-
Save crisanvlad/9770fafea4d6dc1eb651792b6d9c4064 to your computer and use it in GitHub Desktop.
CombineLatest failures
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // | |
| // TestViewModel.swift | |
| // TestCombine | |
| // | |
| // Created by Vlad Crisan on 18.09.2025. | |
| // | |
| import Combine | |
| import Foundation | |
| // MARK: - MyError | |
| enum MyError: Error { | |
| case whatever | |
| case other(Error) | |
| } | |
| // MARK: - TestViewModel | |
| final class TestViewModel: ObservableObject { | |
| private var count = 0 | |
| private var subscription: AnyCancellable? | |
| func start() { | |
| let publisherA = makePublisherA() | |
| .handleEvents { _ in | |
| print("A received subscription") | |
| } receiveOutput: { output in | |
| print("A received output: \(output)") | |
| } receiveCompletion: { completion in | |
| print("A received completion: \(completion)") | |
| } receiveCancel: { | |
| print("A received cancel") | |
| } receiveRequest: { _ in | |
| print("A received request") | |
| } | |
| let publisherB = makePublisherB() | |
| .handleEvents { _ in | |
| print("B received subscription") | |
| } receiveOutput: { output in | |
| print("B received output: \(output)") | |
| } receiveCompletion: { completion in | |
| print("B received completion: \(completion)") | |
| } receiveCancel: { | |
| print("B received cancel") | |
| } receiveRequest: { _ in | |
| print("B received request") | |
| } | |
| subscription = Publishers.CombineLatest(publisherA, publisherB) | |
| .sink(receiveCompletion: { completion in | |
| switch completion { | |
| case .finished: | |
| print("Finished completion") | |
| case .failure(let failure): | |
| print("Failure :\(failure)") | |
| } | |
| }, receiveValue: { string, integer in | |
| print("Result \(string), \(integer)") | |
| }) | |
| } | |
| func cancel() { | |
| subscription?.cancel() | |
| start() | |
| } | |
| func increment() { | |
| count += 1 | |
| } | |
| func makePublisherA() -> AnyPublisher<String, MyError> { | |
| if count.isMultiple(of: 2) { | |
| Deferred { | |
| Future { promise in | |
| Task { | |
| do { | |
| let _ = try await Task.sleep(nanoseconds: 2_000_000_000) | |
| promise(.success("Success")) | |
| } catch { | |
| promise(.failure(.other(error))) | |
| } | |
| } | |
| } | |
| .eraseToAnyPublisher() | |
| } | |
| .eraseToAnyPublisher() | |
| } else { | |
| makeFailedPublisher1() | |
| // makeFailedPublisher2() | |
| } | |
| } | |
| private func makeFailedPublisher1() -> AnyPublisher<String, MyError> { | |
| Fail(outputType: String.self, failure: MyError.whatever).eraseToAnyPublisher() | |
| } | |
| private func makeFailedPublisher2() -> AnyPublisher<String, MyError> { | |
| Deferred { | |
| Future { promise in | |
| Task { | |
| do { | |
| let _ = try await Task.sleep(nanoseconds: 2_000_000_000) | |
| promise(.failure(.whatever)) | |
| } catch { | |
| promise(.failure(.other(error))) | |
| } | |
| } | |
| } | |
| .eraseToAnyPublisher() | |
| } | |
| .eraseToAnyPublisher() | |
| } | |
| func makePublisherB() -> AnyPublisher<Int, MyError> { | |
| Deferred { | |
| Future { promise in | |
| Task { | |
| do { | |
| let _ = try await Task.sleep(nanoseconds: 4_000_000_000) | |
| promise(.success(999)) | |
| } catch { | |
| promise(.failure(.other(error))) | |
| } | |
| } | |
| } | |
| .eraseToAnyPublisher() | |
| } | |
| .eraseToAnyPublisher() | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment