Skip to content

Instantly share code, notes, and snippets.

@woodycatliu
woodycatliu / Publisher+filterExtension.swift
Created April 27, 2023 09:48
Combine.Publisher.Filter extension
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
}
@woodycatliu
woodycatliu / CurrentValueBacked.swift
Last active April 27, 2023 09:49
Encapsulates PassthroughSubject / CurrentValueSubject
/// 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)
}
@woodycatliu
woodycatliu / CombineBinder.swift
Last active May 4, 2023 10:10
Combine Cocoa: CombineBinder
import Combine
extension Publisher where Failure == Never {
public func bind(to binder: CombineBinder<Output>) -> AnyCancellable {
subscribe(binder)
return AnyCancellable(binder)
}
@woodycatliu
woodycatliu / BindingValueSubject.swift
Last active July 2, 2023 11:05
BindingValueSubject provides the ability to callback and update the source's new value.
//
// BindingValueSubject.swift
//
//
// Created by Woody Liu on 2023/7/2.
//
import Combine
@frozen public struct BindingValue<Output>: Publisher {
@woodycatliu
woodycatliu / XCTestCase+Extension.swift
Last active March 2, 2023 17:47
Easy to do Combine test
import Foundation
import Combine
import XCTest
extension XCTestCase {
func awaitPublisher<P: Publisher>(
_ publisher: P,
timeout: TimeInterval,
description: String,
trigger: (() -> Void)? = nil,
@woodycatliu
woodycatliu / CombineToAsync.swift
Created February 28, 2023 14:03
Combine to async
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 {
@woodycatliu
woodycatliu / Publisher+SinkExtension.swift
Created February 20, 2023 09:12
Very few situations require only observation and no need to do anything when the signal is received
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:
@woodycatliu
woodycatliu / CurrentValueSubject+InitFromPublisher.swift
Last active July 2, 2023 11:06
CurrentValueSubject init from AnyPublisher and avoid retain cycle
import Combine
extension CurrentValueSubject where Failure == Never {
convenience init(with publisher: AnyPublisher<Output, Failure>, value: Output) {
self.init(value)
publisher.receive(subscriber: AnySubscriber(self))
}
}
@woodycatliu
woodycatliu / RxSwift_animate_extension.swift
Created November 4, 2022 04:06
The simple extension for UIKit animate in RxSwift
import UIKit
import RxSwift
import RxCocoa
struct WRxAnimation {
let view: UIView
let transform: CGAffineTransform
}
@woodycatliu
woodycatliu / ReadMe.md
Last active March 2, 2023 17:48
Dump Streams with Swift Combine

Dump Streams with Swift Combine

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.

You can use like below.

 publisher