When I develop the project in Swift, The Swift.print is the most commonly used.
But some times I wish more readable dectect value like use dump, even if I programming in Combine.
So I create the combine extension for dump.
publisher
| extension Publisher { | |
| public func filterTo(_ isIncluded: @escaping (Self.Output) -> Bool) -> AnyPublisher<Output, Failure> { | |
| self.filter(isIncluded).eraseToAnyPublisher() | |
| } | |
| public func filterTo(equalTo value: Output) -> AnyPublisher<Output, Failure> where Output: AnyObject&Equatable { | |
| return self.filterTo { [weak value] output in | |
| value == output | |
| } |
| /// Property Wrapper that wraps an `AnyPublisher`, which is backed by a `CurrentValueSubject`. This is to make it possible to easily expose just a publisher to consumers of a type, | |
| /// without also exposing the `CurrentValueSubject` to consumers, effectively allowing for public reads and private writes of a publisher. | |
| @propertyWrapper | |
| struct CurrentValueBacked<Output> { | |
| private var subject: CurrentValueSubject<Output, Never> | |
| init(_ output: Output) { | |
| subject = CurrentValueSubject<Output, Never>(output) | |
| } |
| import Combine | |
| extension Publisher where Failure == Never { | |
| public func bind(to binder: CombineBinder<Output>) -> AnyCancellable { | |
| subscribe(binder) | |
| return AnyCancellable(binder) | |
| } | |
| // | |
| // BindingValueSubject.swift | |
| // | |
| // | |
| // Created by Woody Liu on 2023/7/2. | |
| // | |
| import Combine | |
| @frozen public struct BindingValue<Output>: Publisher { |
| import Foundation | |
| import Combine | |
| import XCTest | |
| extension XCTestCase { | |
| func awaitPublisher<P: Publisher>( | |
| _ publisher: P, | |
| timeout: TimeInterval, | |
| description: String, | |
| trigger: (() -> Void)? = nil, |
| extension Publisher { | |
| func awaitOutput() async throws -> Output { | |
| return try await withCheckedThrowingContinuation { continuation in | |
| let lock = NSRecursiveLock() | |
| var nillableContinuation: CheckedContinuation<Self.Output, Error>? = continuation | |
| var cancelable: AnyCancellable? | |
| cancelable = first().sink(receiveCompletion: { | |
| lock.lock(); defer { lock.unlock() } | |
| switch $0 { |
| import Combine | |
| extension Publisher { | |
| public func sink(completion completionHandle: (() -> Void)? = nil, receiveError: ((Self.Failure) -> Void)? = nil, receiveValue: ((Self.Output) -> Void)? = nil) -> AnyCancellable { | |
| return self.sink(receiveCompletion: { completion in | |
| switch completion { | |
| case .failure(let error): | |
| receiveError?(error) | |
| case .finished: |
| import Combine | |
| extension CurrentValueSubject where Failure == Never { | |
| convenience init(with publisher: AnyPublisher<Output, Failure>, value: Output) { | |
| self.init(value) | |
| publisher.receive(subscriber: AnySubscriber(self)) | |
| } | |
| } |
| import UIKit | |
| import RxSwift | |
| import RxCocoa | |
| struct WRxAnimation { | |
| let view: UIView | |
| let transform: CGAffineTransform | |
| } |