Skip to content

Commit 1476acd

Browse files
authored
Merge pull request #435 from ReactiveCocoa/as-map-keypath
Overload map() to support key paths
2 parents ce93e83 + 3ef3d5e commit 1476acd

File tree

6 files changed

+70
-0
lines changed

6 files changed

+70
-0
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# master
22
*Please add new entries at the top.*
33

4+
1. In Swift 3.2 or later, you can use `map()` with the new Smart Key Paths. (#435, kudos to @sharplet)
5+
46
1. When composing `Signal` and `SignalProducer` of inhabitable types, e.g. `Never` or `NoError`, 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)
57

68
1. N-ary `SignalProducer` operators are now generic and accept any type that can be expressed as `SignalProducer`. (#410, kudos to @andersio)

Sources/Property.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,19 @@ extension PropertyProtocol {
102102
return lift { $0.map(transform) }
103103
}
104104

105+
#if swift(>=3.2)
106+
/// Maps the current value and all subsequent values to a new property
107+
/// by applying a key path.
108+
///
109+
/// - parameters:
110+
/// - keyPath: A key path relative to the property's `Value` type.
111+
///
112+
/// - returns: A property that holds a mapped value from `self`.
113+
public func map<U>(_ keyPath: KeyPath<Value, U>) -> Property<U> {
114+
return lift { $0.map(keyPath) }
115+
}
116+
#endif
117+
105118
/// Combines the current value and the subsequent values of two `Property`s in
106119
/// the manner described by `Signal.combineLatest(with:)`.
107120
///

Sources/Signal.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,18 @@ extension Signal {
646646
}
647647
}
648648

649+
#if swift(>=3.2)
650+
/// Map each value in the signal to a new value by applying a key path.
651+
///
652+
/// - parameters:
653+
/// - keyPath: A key path relative to the signal's `Value` type.
654+
///
655+
/// - returns: A signal that will send new values.
656+
public func map<U>(_ keyPath: KeyPath<Value, U>) -> Signal<U, Error> {
657+
return map { $0[keyPath: keyPath] }
658+
}
659+
#endif
660+
649661
/// Map errors in the signal to a new error.
650662
///
651663
/// - parameters:

Sources/SignalProducer.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,18 @@ extension SignalProducer {
621621
return lift { $0.map(transform) }
622622
}
623623

624+
#if swift(>=3.2)
625+
/// Map each value in the producer to a new value by applying a key path.
626+
///
627+
/// - parameters:
628+
/// - keyPath: A key path relative to the producer's `Value` type.
629+
///
630+
/// - returns: A producer that will send new values.
631+
public func map<U>(_ keyPath: KeyPath<Value, U>) -> SignalProducer<U, Error> {
632+
return lift { $0.map(keyPath) }
633+
}
634+
#endif
635+
624636
/// Map errors in the producer to a new error.
625637
///
626638
/// - parameters:

Tests/ReactiveSwiftTests/PropertySpec.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -732,6 +732,17 @@ class PropertySpec: QuickSpec {
732732
property.value = 2
733733
expect(mappedProperty.value) == 3
734734
}
735+
736+
#if swift(>=3.2)
737+
it("should work with key paths") {
738+
let property = MutableProperty("foo")
739+
let mappedProperty = property.map(\.count)
740+
expect(mappedProperty.value) == 3
741+
742+
property.value = "foobar"
743+
expect(mappedProperty.value) == 6
744+
}
745+
#endif
735746
}
736747

737748
describe("combineLatest") {

Tests/ReactiveSwiftTests/SignalSpec.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,26 @@ class SignalSpec: QuickSpec {
525525
observer.send(value: 1)
526526
expect(lastValue) == "2"
527527
}
528+
529+
#if swift(>=3.2)
530+
it("should support key paths") {
531+
let (signal, observer) = Signal<String, NoError>.pipe()
532+
let mappedSignal = signal.map(\String.count)
533+
534+
var lastValue: Int?
535+
mappedSignal.observeValues {
536+
lastValue = $0
537+
}
538+
539+
expect(lastValue).to(beNil())
540+
541+
observer.send(value: "foo")
542+
expect(lastValue) == 3
543+
544+
observer.send(value: "foobar")
545+
expect(lastValue) == 6
546+
}
547+
#endif
528548
}
529549

530550

0 commit comments

Comments
 (0)