Skip to content

Commit b540e78

Browse files
authored
Merge pull request #114 from iv-mexx/feature/debuggingTechniques
Update DebuggingTechniques for ReactiveSwift 1.0
2 parents dd015c3 + 71fabac commit b540e78

File tree

1 file changed

+23
-51
lines changed

1 file changed

+23
-51
lines changed

Documentation/DebuggingTechniques.md

Lines changed: 23 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -15,66 +15,37 @@ Below is an example of type-error scenario:
1515

1616
```swift
1717
SignalProducer<Int, NoError>(value:42)
18-
.on(next: { answer in
18+
.on(value: { answer in
1919
return _
2020
})
2121
.startWithCompleted {
2222
print("Completed.")
2323
}
2424
```
2525

26-
The code above will not compile with the following error on a `print` call `error: ambiguous reference to member 'print'
27-
print("Completed.")`. To find the actual compile error, the chain needs to be broken apart. Add explicit definitions of closure types on each of the steps:
26+
The code above will not compile with the following error on the `.startWithCompleted` call `error: cannot convert value of type 'Disposable' to closure result type '()'. To find the actual compile error, the chain needs to be broken apart. Add explicit definitions of closure types on each of the steps:
2827

2928
```swift
3029
let initialProducer = SignalProducer<Int, NoError>.init(value:42)
31-
let sideEffectProducer = initialProducer.on(next: { (answer: Int) in
30+
let sideEffectProducer = initialProducer.on(value: { (answer: Int) in
3231
return _
3332
})
3433
let disposable = sideEffectProducer.startWithCompleted {
3534
print("Completed.")
3635
}
3736
```
3837

39-
The code above will not compile too, but with the error `error: cannot convert value of type '(_) -> _' to expected argument type '(Int -> ())?'` on definition of `on` closure. This gives enough of information to locate unexpected `return _` since `on` closure should not have any return value.
40-
41-
#### Binding `DynamicProperty` with `<~` operator
42-
43-
Using the `<~` operator to bind a `Signal` or a `SignalProducer` to a `DynamicProperty` can result in unexpected compiler errors.
44-
45-
Below is an example of this scenario:
46-
47-
```swift
48-
let label = UILabel()
49-
let property = MutableProperty<String>("")
50-
51-
DynamicProperty(object: label, keyPath: "text") <~ property.producer
52-
```
53-
54-
This will often result in a compiler error:
55-
56-
> error: binary operator '<~' cannot be applied to operands of type 'DynamicProperty' and 'SignalProducer<String, NoError>'
57-
DynamicProperty(object: label, keyPath: "text") <~ property.producer
58-
59-
The reason is a limitation in the swift type checker - A `DynamicProperty` always has a type of `AnyObject?`, but the `<~` operator requires the values of both sides to have the same type, so the right side value would have to be `AnyObject?` as well, but usually a more concrete type is used (in this example `String`).
60-
61-
Usually, the fix is as easy as adding a `.map{ $0 }`.
62-
63-
```swift
64-
DynamicProperty(object: label, keyPath: "text") <~ property.producer.map { $0 }
65-
```
66-
67-
This allows the type checker to infer that `String` can be converted to `AnyProperty?` and thus, the binding succeeds.
38+
The code above will not compile too, but with the error `error: cannot convert value of type '(Int) -> _' to expected argument type '((Int) -> Void)?'` on definition of `on` closure. This gives enough of information to locate unexpected `return _` since `on` closure should not have any return value.
6839

6940
#### Debugging event streams
7041

7142
As mentioned in the README, stream debugging can be quite difficut and tedious, so we provide the `logEvents` operator. In its simplest form:
7243

7344
```swift
74-
let searchString = textField.rac_textSignal()
75-
.toSignalProducer()
76-
.map { text in text as! String }
77-
.throttle(0.5, onScheduler: QueueScheduler.mainQueueScheduler)
45+
let property = MutableProperty<String>("")
46+
...
47+
let searchString = property.producer
48+
.throttle(0.5, on: QueueScheduler.main)
7849
.logEvents()
7950
```
8051

@@ -98,31 +69,32 @@ func debugLog(identifier: String, event: String, fileName: String, functionName:
9869
You would then:
9970

10071
```swift
101-
let searchString = textField.rac_textSignal()
102-
.toSignalProducer()
103-
.map { text in text as! String }
104-
.throttle(0.5, onScheduler: QueueScheduler.mainQueueScheduler)
72+
let property = MutableProperty<String>("")
73+
...
74+
let searchString = property.producer
75+
.throttle(0.5, on: QueueScheduler.main)
10576
.logEvents(logger: debugLog)
10677
```
10778

10879
We also provide the `identifier` parameter. This is useful when you are debugging multiple streams and you don't want to get lost:
10980

11081
```swift
111-
let searchString = textField.rac_textSignal()
112-
.toSignalProducer()
113-
.map { text in text as! String }
114-
.throttle(0.5, onScheduler: QueueScheduler.mainQueueScheduler)
82+
let property = MutableProperty<String>("")
83+
...
84+
let searchString = property.producer
85+
.throttle(0.5, on: QueueScheduler.main)
11586
.logEvents(identifier: "✨My awesome stream ✨")
11687
```
11788

118-
There also cases, specially with [hot signals][[Signals]], when there is simply too much output. For those, you can specify which events you are interested in:
89+
There also cases, specially with [hot signals][Signal], when there is simply too much output. For those, you can specify which events you are interested in:
11990

12091
```swift
121-
let searchString = textField.rac_textSignal()
122-
.toSignalProducer()
123-
.map { text in text as! String }
124-
.throttle(0.5, onScheduler: QueueScheduler.mainQueueScheduler)
125-
.logEvents(events:[.Disposed]) // This will happen when the `UITextField` is released
92+
let property = MutableProperty<String>("")
93+
...
94+
let searchString = property.producer
95+
.throttle(0.5, on: QueueScheduler.main)
96+
.logEvents(events: [.disposed]) // This will happen when `property` is released
12697
```
12798

99+
[Signal]: ../Sources/Signal.swift
128100

0 commit comments

Comments
 (0)