Skip to content

Instantly share code, notes, and snippets.

@RuiAAPeres
Last active December 12, 2023 09:30
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save RuiAAPeres/db046159f7d9e3cabaeac29a995219aa to your computer and use it in GitHub Desktop.
Save RuiAAPeres/db046159f7d9e3cabaeac29a995219aa to your computer and use it in GitHub Desktop.
Couple of methods to bridge ReactiveSwift with SwiftUI
import Combine
import ReactiveSwift
import SwiftUI
class AnySubscription: Subscription {
private let cancelable: Cancellable
init(cancelable: Cancellable) {
self.cancelable = cancelable
}
init(_ cancel: @escaping () -> Void) {
self.cancelable = AnyCancellable(cancel)
}
func request(_ demand: Subscribers.Demand) {}
func cancel() {
self.cancelable.cancel()
}
}
extension Property: BindingConvertible {
public var binding: Binding<Value> {
Binding<Value>(getValue: { self.value }, setValue: {_ in })
}
}
extension Property: Publisher {
public typealias Output = Value
public typealias Failure = Never
public func receive<S>(subscriber: S) where S : Subscriber, Property.Failure == S.Failure, Property.Output == S.Input {
self.signal.observe { event in
switch event {
case .completed, .interrupted:
subscriber.receive(completion: .finished)
case let .value(value):
_ = subscriber.receive(value)
}
}
}
}
extension Property: BindableObject {
public typealias PublisherType = Property
public var didChange: Property {
self
}
}
extension MutableProperty: BindingConvertible {
public var binding: Binding<Value> {
Binding<Value>(getValue: { self.value }, setValue: { self.value = $0 })
}
}
extension MutableProperty: Publisher {
public typealias Output = Value
public typealias Failure = Never
public func receive<S>(subscriber: S) where S : Subscriber, MutableProperty.Failure == S.Failure, MutableProperty.Output == S.Input {
self.signal.observe { event in
switch event {
case .completed, .interrupted:
subscriber.receive(completion: .finished)
case let .value(value):
_ = subscriber.receive(value)
}
}
}
}
extension MutableProperty: BindableObject {
public typealias PublisherType = MutableProperty
public var didChange: MutableProperty {
self
}
}
extension SignalProducer {
var publisher: some Publisher {
return AnyPublisher<Value, Error> { subscriber in
let serial = SerialDisposable()
subscriber.receive(subscription: AnySubscription(serial.dispose))
serial.inner = self.start { event in
switch event {
case .completed, .interrupted:
subscriber.receive(completion: .finished)
case let .value(value):
_ = subscriber.receive(value)
case let .failed(error):
subscriber.receive(completion: .failure(error))
}
}
}
}
}
extension Signal {
var publisher: some Publisher {
return AnyPublisher<Value, Error> { subscriber in
let serial = SerialDisposable()
subscriber.receive(subscription: AnySubscription(serial.dispose))
serial.inner = self.observe { event in
switch event {
case .completed, .interrupted:
subscriber.receive(completion: .finished)
case let .value(value):
_ = subscriber.receive(value)
case let .failed(error):
subscriber.receive(completion: .failure(error))
}
}
}
}
}
@NicholasTD07
Copy link

Nice work! Thanks for sharing!

@zixzelz
Copy link

zixzelz commented Apr 21, 2021

How did you compile it?

@zoltanbognar
Copy link

This looks great!
unfortunately this code is not compiling with new swiftUI and combine
can you please update it
Thanks a lot

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment