Skip to content

Instantly share code, notes, and snippets.

@n8chur
Last active March 2, 2022 06:41
Show Gist options
  • Save n8chur/e1e055b91c626014d917d3d7f7a0ad61 to your computer and use it in GitHub Desktop.
Save n8chur/e1e055b91c626014d917d3d7f7a0ad61 to your computer and use it in GitHub Desktop.
An example implementation of @published from Swift's Combine framework along with an "immutable" variant.
import Combine
/**
An observable, mutable property.
Replays the current value when subscribed.
*/
@propertyWrapper
struct Published<Output>: Publisher {
typealias Failure = Never
private let subject: CurrentValueSubject<Output, Never>
var value: Output {
get { subject.value }
nonmutating set { subject.value = newValue }
}
init(initialValue: Output) {
subject = CurrentValueSubject<Output, Never>(initialValue)
}
func receive<S>(subscriber: S) where S : Subscriber, Failure == S.Failure, Output == S.Input {
subject.receive(subscriber: subscriber)
}
}
/**
An immutable, observable property.
Replays the current value when subscribed.
*/
@propertyWrapper
struct ImmutablePublished<Output>: Publisher {
typealias Failure = Never
private let subject: CurrentValueSubject<Output, Failure>
var value: Output { subject.value }
private let cancellable: Cancellable
init(_ publisher: AnyPublisher<Output, Failure>, initialValue: Output) {
subject = CurrentValueSubject<Output, Failure>(initialValue)
cancellable = publisher.assign(to: \.value, on: subject)
}
func receive<S>(subscriber: S) where S : Subscriber, Failure == S.Failure, Output == S.Input {
subject.receive(subscriber: subscriber)
}
}
@dshikulin-mwb
Copy link

It misses projectedValue and I guess it won't trigger objectWillChange of ObservableObject

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