Please add new entries at the top.
- Fixed integer overflow for
DispatchTimeIntervalin FoundationExtensions.swift (#506)
-
Signalnow usesLifetimefor resource management. (#404, kudos to @andersio)The
Signalinitialzer now accepts a generator closure that is passed with the inputObserverand theLifetimeas its arguments. The original variant accepting a single-argument generator closure is now obselete. This is a source breaking change.// New: Add `Disposable`s to the `Lifetime`. let candies = Signal<U, E> { (observer: Signal<U, E>.Observer, lifetime: Lifetime) in lifetime += trickOrTreat.observe(observer) } // Obsolete: Returning a `Disposable`. let candies = Signal { (observer: Signal<U, E>.Observer) -> Disposable? in return trickOrTreat.observe(observer) }
-
SignalProducer.startWithSignalnow returns the value of the setup closure. (#533, kudos to @Burgestrand)
- Disabled code coverage data to allow app submissions with Xcode 9.0 (see Carthage/Carthage#2056, kudos to @NachoSoto)
-
Signal.Observer.actionhas been deprecated. UseSignal.Observer.sendinstead. (#515) -
Workaround an unexpected EGAGIN error being returned by pthread in 32-bit ARM debug builds. (#508)
-
The
SignalProducerinternals have undergone a significant refactoring, which bootstraps the effort to reduce the overhead of constant producers and producer compositions. (#487, kudos to @andersio)
-
Addressed the exceptionally high build time. (#495)
-
New method
retry(upTo:interval:on:). This delays retrying on failure byintervaluntil hitting theupTolimitation.
-
Lifetime.+=which ties aDisposableto aLifetime, is now part of the public API and is no longer deprecated. -
Feedbacks from
isEnabledto the state of the sameActionno longer deadlocks if it does not constitute an infinite feedback loop. (#481, kudos to @andersio)Note that
isExecutingalready supportsActionstate feedback, and legitimate feedback loops would still deadlock.
- Fixed a deadlock upon disposal when combining operators, i.e.
zipandcombineLatest, are used. (#471, kudos to @stevebrambilla for catching the bug)
-
If the input observer of a
Signaldeinitializes while theSignalhas not yet terminated, aninterruptedevent would now be automatically sent. (#463, kudos to @andersio) -
ValidationResultandValidatorOutputhave been renamed toValidatingProperty.ResultandValidatingProperty.Decision, respectively. (#443) -
Mitigated a race condition related to ARC in the
Signalinternal. (#456, kudos to @andersio) -
Added new convenience initialisers to
Actionthat make creating actions with state input properties easier. When creating anActionthat is conditionally enabled based on an optional property, use the renamedAction.init(unwrapping:execute:)initialisers. (#455, kudos to @sharplet)
-
combinePreviousforSignalandSignalProducerno longer requires an initial value. The first tuple would be emitted as soon as the second value is received by the operator if no initial value is given. (#445, kudos to @andersio) -
Fixed an impedance mismatch in the
Signalinternals that caused heap corruptions. (#449, kudos to @gparker42) -
In Swift 3.2 or later, you may create
BindingTargetfor a key path of a specific object. (#440, kudos to @andersio)
-
In Swift 3.2 or later, you can use
map()with the new Smart Key Paths. (#435, kudos to @sharplet) -
When composing
SignalandSignalProducerof inhabitable types, e.g.NeverorNoError, ReactiveSwift now warns about operators that are illogical to use, and traps at runtime when such operators attempt to instantiate an instance. (#429, kudos to @andersio) -
N-ary
SignalProduceroperators are now generic and accept any type that can be expressed asSignalProducer. (#410, kudos to @andersio) Types may conform toSignalProducerConvertibleto be an eligible operand. -
The performance of
SignalProducerhas been improved significantly. (#140, kudos to @andersio)All lifted
SignalProduceroperators no longer yield an extraSignal. As a result, the calling overhead of event delivery is generally reduced proportionally to the level of chaining of lifted operators. -
interruptednow respectsobserve(on:). (#140)When a produced
Signalis interrupted, ifobserve(on:)is the last applied operator,interruptedwould now be delivered on theSchedulerpassed toobserve(on:)just like other events. -
Feedbacks from
isExecutingto the state of the sameAction, including allenabledIfconvenience initializers, no longer deadlocks. (#400, kudos to @andersio) -
MutablePropertynow enforces exclusivity of access. (#419, kudos to @andersio)In other words, nested modification in
MutableProperty.modifyis now prohibited. Generally speaking, it should have extremely limited impact as in most cases theMutablePropertywould have been deadlocked already. -
promoteErrorcan now infer the new error type from the context. (#413, kudos to @andersio)
This is the first alpha release of ReactiveSwift 2.0. It requires Swift 3.1 (Xcode 8.3).
The Signal lifetime semantics is modified to improve interoperability with memory debugging tools. ReactiveSwift 2.0 adopted a new Signal internal which does not exploit deliberate retain cycles that consequentially confuse memory debugging tools.
A Signal is now automatically and silently disposed of, when:
- the
Signalis not retained and has no active observer; or - (New) both the
Signaland its input observer are not retained.
It is expected that memory debugging tools would no longer report irrelevant negative leaks that were once caused by the ReactiveSwift internals.
SignalProducer now uses Lifetime for resource management. You may observe the Lifetime for the disposal of the produced Signal.
let producer = SignalProducer<Int, NoError> { observer, lifetime in
if let disposable = numbers.observe(observer) {
lifetime.observeEnded(disposable.dispose)
}
}Two Disposable-accepting methods Lifetime.Type.+= and Lifetime.add are provided to aid migration, and are subject to removal in a future release.
-
All
SignalandSignalProduceroperators now belongs to the respective concrete types. (#304)Custom operators should extend the concrete types directly.
SignalProtocolandSignalProducerProtocolshould be used only for constraining associated types. -
combineLatestandzipare optimised to have a constant overhead regardless of arity, mitigating the possibility of stack overflow. (#345) -
flatMap(_:transform:)is renamed toflatMap(_:_:). (#339) -
promoteErrors(_:)is renamed topromoteError(_:). (#408) -
Eventis renamed toSignal.Event. (#376) -
Observeris renamed toSignal.Observer. (#376)
Action(input:_:),Action(_:),Action(enabledIf:_:)andAction(state:enabledIf:_:)are renamed toAction(state:execute:),Action(execute:),Action(enabledIf:execute:)andAction(state:enabledIf:execute:)respectively. (#325)
- The memory overhead of property composition has been considerably reduced. (#340)
-
The
BindingSourcenow requires only a producer representation ofself. (#359) -
The
<~operator overloads are now provided byBindingTargetProvider. (#359)
-
SimpleDisposableandActionDisposablehas been folded intoAnyDisposable. (#412) -
CompositeDisposable.DisposableHandleis replaced byDisposable?. (#363) -
The
+=operator overloads forCompositeDisposableare now hosted inside the concrete types. (#412)
-
Improved the performance of
Bag. (#354) -
RemovalTokenis renamed toBag.Token. (#354)
Schedulergains a class bound. (#333)
Lifetime.endednow uses the inhabitableNeveras its value type. (#392)
SignalandAtomicnow useos_unfair_lockwhen it is available. (#342)
-
FlattenStrategy.raceis introduced. (#233, kudos to @inamiy)raceflattens whichever inner signal that first sends an event, and ignores the rest. -
FlattenStrategy.concurrentis introduced. (#298, kudos to @andersio)concurrentstarts and flattens inner signals according to the specified concurrency limit. If an inner signal is received after the limit is reached, it would be queued and drained later as the in-flight inner signals terminate. -
New operators:
reduce(into:)andscan(into:). (#365, kudos to @ikesyo)These variants pass to the closure an
inoutreference to the accumulator, which helps the performance when a large value type is used, e.g. collection. -
Property(initial:then:)gains overloads that accept a producer or signal of the wrapped value type when the value type is anOptional. (#396)
-
The requirement
BindingSource.observe(_:during:)and the implementations have been removed. -
All Swift 2 (ReactiveCocoa 4) obsolete symbols have been removed.
-
All deprecated methods and protocols in ReactiveSwift 1.1.x are no longer available.
Thank you to all of @ReactiveCocoa/reactiveswift and all our contributors, but especially to @andersio, @calebd, @eimantas, @ikesyo, @inamiy, @Marcocanc, @mdiep, @NachoSoto, @sharplet and @tjnet. ReactiveSwift is only possible due to the many hours of work that these individuals have volunteered. ❤️
observe(_:during:)is now deprecated. It would be removed in ReactiveSwift 2.0. Usetake(during:)and the relevant observation API ofSignal,SignalProducerandPropertyinstead. (#374)
- Fixed a rare occurrence of
interruptedevents being emitted by aProperty. (#362)
- The properties
Signal.negated,SignalProducer.negatedandProperty.negatedare deprecated. Use its operator formnegate()instead.
- New boolean operators:
and,orandnegated; available onSignal<Bool, E>,SignalProducer<Bool, E>andProperty<Bool, E>types. (#160, kudos to @cristianames92) - New operator
filterMap. (#232, kudos to @RuiAAPeres) - New operator
lazyMap(on:_:). It coalescesvalueevents when they are emitted at a rate faster than the rate the given scheduler can handle. The transform is applied on only the coalesced and the uncontended values. (#240, kudos to @liscio) - New protocol
BindingTargetProvider, which replacesBindingTargetProtocol. (#254, kudos to @andersio)
- New initializer
SignalProducer(_:), which takes a@escaping () -> Valueclosure. It is similar toSignalProducer(value:), but it lazily evaluates the value every time the producer is started. (#240, kudos to @liscio)
- New method
Lifetime.observeEnded(self:). This is now the recommended way to explicitly observe the end of aLifetime. UseLifetime.endedonly if composition is needed. (#229, kudos to @andersio) - New factory method
Lifetime.make(), which returns a tuple ofLifetimeandLifetime.Token. (#236, kudos to @sharplet)
ValidatingProperty: A mutable property that validates mutations before committing them. (#182, kudos to @andersio).- A new interactive UI playground:
ReactiveSwift-UIExamples.playground. It demonstrates howValidatingPropertycan be used in an interactive form UI. (#182)
- Flattening a signal of
Sequenceno longer requires an explicitFlattenStrategy. (#199, kudos to @dmcrodrigues) BindingSourceProtocolhas been renamed toBindingSource. (#254)SchedulerProtocolandDateSchedulerProtocolhas been renamed toSchedulerandDateScheduler, respectively. (#257)take(during:)now handles endedLifetimeproperly. (#229)
AtomicProtocolhas been deprecated. (#279)ActionProtocolhas been deprecated. (#284)ObserverProtocolhas been deprecated. (#262)BindingTargetProtocolhas been deprecated. (#254)
- Fixed a couple of infinite feedback loops in
Action. (#221) - Fixed a race condition of
Signalwhich might result in a deadlock when a signal is sent a terminal event as a result of an observer of it being released. (#267)
Kudos to @mdiep, @sharplet and @andersio who helped review the pull requests.
This is the first major release of ReactiveSwift, a multi-platform, pure-Swift functional reactive programming library spun off from ReactiveCocoa. As Swift continues to expand beyond Apple’s platforms, we hope that ReactiveSwift will see broader adoption. To learn more, please refer to ReactiveCocoa’s CHANGELOG.
Major changes since ReactiveCocoa 4 include:
-
Updated for Swift 3
APIs have been updated and renamed to adhere to the Swift 3 API Design Guidelines.
-
Signal Lifetime Semantics
Signals now live and continue to emit events only while either (a) they have observers or (b) they are retained. This clears up a number of unexpected cases and makes Signals much less dangerous. -
Reactive Proxies
Types can now declare conformance to
ReactiveExtensionsProviderto expose areactiveproperty that’s generic overself. This property hosts reactive extensions to the type, such as the ones provided onNotificationCenterandURLSession. -
Property Composition
Propertys can now be composed. They expose many of the familiar operators fromSignalandSignalProducer, includingmap,flatMap,combineLatest, etc. -
Binding Primitives
BindingTargetProtocolandBindingSourceProtocolhave been introduced to allow binding of observable instances to targets.BindingTargetis a new concrete type that can be used to wrap a settable but non-observable property. -
Lifetime
Lifetimeis introduced to represent the lifetime of any arbitrary reference type. This can be used with the newtake(during:)operator, but also forms part of the new binding APIs. -
Race-free Action
A new
ActioninitializerAction(state:enabledIf:_:)has been introduced. It allows the latest value of any arbitrary property to be supplied to the execution closure in addition to the input fromapply(_:), while having the availability being derived from the property.This eliminates a data race in ReactiveCocoa 4.x, when both the
enabledIfpredicate and the execution closure depend on an overlapping set of properties.
Extensive use of Swift’s @available declaration has been used to ease migration from ReactiveCocoa 4. Xcode should have fix-its for almost all changes from older APIs.
Thank you to all of @ReactiveCocoa/ReactiveSwift and all our contributors, but especially to @andersio, @liscio, @mdiep, @nachosoto, and @sharplet. ReactiveSwift is only possible due to the many hours of work that these individuals have volunteered. ❤️