Skip to content

Commit 0dec921

Browse files
committed
Merge remote-tracking branch 'origin/master' into anders/locks
2 parents dd907a2 + 120149c commit 0dec921

File tree

7 files changed

+69
-13
lines changed

7 files changed

+69
-13
lines changed

.swift-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
4.1
1+
4.1.2

.travis.yml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
language: objective-c
2-
osx_image: xcode9.3
2+
osx_image: xcode9.4
33
before_install: true
44
install: true
55
branches:
@@ -15,7 +15,7 @@ cache:
1515

1616
jobs:
1717
include:
18-
- osx_image: xcode9.3
18+
- osx_image: xcode9.4
1919
script:
2020
- XCODE_SCHEME=ReactiveSwift-macOS
2121
XCODE_SDK=macosx
@@ -38,11 +38,14 @@ jobs:
3838
XCODE_DESTINATION="platform=watchOS Simulator,name=Apple Watch Series 3 - 38mm"
3939
script/build
4040
- script:
41+
# To work around the lint error: "ERROR | swift: Specification `ReactiveSwift` specifies an inconsistent `swift_version` (`4.1`) compared to the one present in your `.swift-version` file (`4.1.2`). Please remove the `.swift-version` file which is now deprecated and only use the `swift_version` attribute within your podspec."
42+
# `.swift-version` is for swiftenv, not for CocoaPods, so we can't remove the file as suggested.
43+
- rm .swift-version
4144
- pod repo update --silent
4245
- pod lib lint ReactiveSwift.podspec
4346
env:
4447
- JOB=PODSPEC
45-
- osx_image: xcode9.3
48+
- osx_image: xcode9.4
4649
script:
4750
- swift --version
4851
- swift build

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,19 @@
44

55
# 4.0.0-rc.2
66

7+
*Please add new entries at the top.*
8+
9+
1. [CocoaPods] CocoaPods 1.4.0 is the minimum required version. (#651, kudos to @ikesyo)
10+
1. `<~` bindings now works with optional left-hand-side operands. (#642, kudos to @andersio and @Ankit-Aggarwal)
11+
12+
```swift
13+
let nilTarget: BindingTarget<Int>? = nil
14+
15+
// This is now a valid binding. Previously required manual
16+
// unwrapping in ReactiveSwift 3.x.
17+
nilTarget <~ notifications.map { $0.count }
18+
```
19+
720
1. Support Swift 4.2 (Xcode 10) (#644, kudos to @ikesyo)
821

922
# 4.0.0-rc.1

ReactiveSwift.podspec

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,7 @@ Pod::Spec.new do |s|
2020
s.dependency 'Result', '~> 4.0'
2121

2222
s.pod_target_xcconfig = {"OTHER_SWIFT_FLAGS[config=Release]" => "$(inherited) -suppress-warnings" }
23+
24+
s.cocoapods_version = ">= 1.4.0"
25+
s.swift_version = "4.1"
2326
end

Sources/UnidirectionalBinding.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,3 +149,16 @@ public struct BindingTarget<Value>: BindingTargetProvider {
149149
self.init(on: scheduler, lifetime: lifetime) { [weak object] in object?[keyPath: keyPath] = $0 }
150150
}
151151
}
152+
153+
extension Optional: BindingTargetProvider where Wrapped: BindingTargetProvider {
154+
public typealias Value = Wrapped.Value
155+
156+
public var bindingTarget: BindingTarget<Wrapped.Value> {
157+
switch self {
158+
case let .some(provider):
159+
return provider.bindingTarget
160+
case .none:
161+
return BindingTarget(lifetime: .empty, action: { _ in })
162+
}
163+
}
164+
}

Tests/ReactiveSwiftTests/UnidirectionalBindingSpec.swift

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ class UnidirectionalBindingSpec: QuickSpec {
2121
}
2222

2323
describe("closure binding target") {
24-
var target: BindingTarget<Int>!
25-
var optionalTarget: BindingTarget<Int?>!
24+
var target: BindingTarget<Int>?
25+
var optionalTarget: BindingTarget<Int?>?
2626
var value: Int?
2727

2828
beforeEach {
@@ -33,40 +33,57 @@ class UnidirectionalBindingSpec: QuickSpec {
3333

3434
describe("non-optional target") {
3535
it("should pass through the lifetime") {
36-
expect(target.lifetime).to(beIdenticalTo(lifetime))
36+
expect(target!.lifetime).to(beIdenticalTo(lifetime))
3737
}
3838

3939
it("should trigger the supplied setter") {
4040
expect(value).to(beNil())
4141

42-
target.action(1)
42+
target!.action(1)
4343
expect(value) == 1
4444
}
4545

4646
it("should accept bindings from properties") {
4747
expect(value).to(beNil())
4848

4949
let property = MutableProperty(1)
50-
target <~ property
50+
target! <~ property
5151
expect(value) == 1
5252

5353
property.value = 2
5454
expect(value) == 2
5555
}
5656
}
5757

58-
describe("optional target") {
58+
describe("target of optional value") {
5959
it("should pass through the lifetime") {
60-
expect(optionalTarget.lifetime).to(beIdenticalTo(lifetime))
60+
expect(optionalTarget!.lifetime).to(beIdenticalTo(lifetime))
6161
}
6262

6363
it("should trigger the supplied setter") {
6464
expect(value).to(beNil())
6565

66-
optionalTarget.action(1)
66+
optionalTarget!.action(1)
6767
expect(value) == 1
6868
}
6969

70+
it("should accept bindings from properties") {
71+
expect(value).to(beNil())
72+
73+
let property = MutableProperty(1)
74+
optionalTarget! <~ property
75+
expect(value) == 1
76+
77+
property.value = 2
78+
expect(value) == 2
79+
}
80+
}
81+
82+
describe("optional LHS binding with non-nil LHS at runtime") {
83+
it("should pass through the lifetime") {
84+
expect(target.bindingTarget.lifetime).to(beIdenticalTo(lifetime))
85+
}
86+
7087
it("should accept bindings from properties") {
7188
expect(value).to(beNil())
7289

@@ -78,6 +95,13 @@ class UnidirectionalBindingSpec: QuickSpec {
7895
expect(value) == 2
7996
}
8097
}
98+
99+
describe("optional LHS binding with nil LHS at runtime") {
100+
it("should pass through the empty lifetime") {
101+
let nilTarget: BindingTarget<Int>? = nil
102+
expect(nilTarget.bindingTarget.lifetime).to(beIdenticalTo(Lifetime.empty))
103+
}
104+
}
81105
}
82106

83107
describe("key path binding target") {

0 commit comments

Comments
 (0)