Merge branch 'develop' into uisearchbar-additions
This commit is contained in:
commit
097467e07c
|
|
@ -455,3 +455,11 @@ extension NSTextField {
|
|||
|
||||
}
|
||||
```
|
||||
|
||||
```swift
|
||||
extension UITabBarItem {
|
||||
|
||||
public var rx_badgeValue: AnyObserver<String?> {}
|
||||
|
||||
}
|
||||
```
|
||||
|
|
|
|||
|
|
@ -46,7 +46,9 @@ let b /*: Observable<Int>*/ = Variable(2) // b = 2
|
|||
// if a + b >= 0 {
|
||||
// c = "\(a + b) is positive"
|
||||
// }
|
||||
let c = Observable.combineLatest(a, b) { $0 + $1 } // combines latest values of variables `a` and `b` using `+`
|
||||
|
||||
// combines latest values of variables `a` and `b` using `+`
|
||||
let c = Observable.combineLatest(a.asObservable(), b.asObservable()) { $0 + $1 }
|
||||
.filter { $0 >= 0 } // if `a + b >= 0` is true, `a + b` is passed to map operator
|
||||
.map { "\($0) is positive" } // maps `a + b` to "\(a + b) is positive"
|
||||
|
||||
|
|
|
|||
|
|
@ -481,7 +481,7 @@ Disposed
|
|||
Ended ----
|
||||
```
|
||||
|
||||
**Every subscriber upon subscription usually generates it's own separate sequence of elements. Operators are stateless by default. There is vastly more stateless operators then stateful ones.**
|
||||
**Every subscriber upon subscription usually generates it's own separate sequence of elements. Operators are stateless by default. There are vastly more stateless operators than stateful ones.**
|
||||
|
||||
## Sharing subscription and `shareReplay` operator
|
||||
|
||||
|
|
@ -771,7 +771,7 @@ Usually after you have fixed the error, you can remove the type annotations to c
|
|||
|
||||
## Debugging
|
||||
|
||||
Using debugger alone is useful, but you can also use `debug`. `debug` operator will print out all events to standard output and you can add also label those events.
|
||||
Using debugger alone is useful, but usually using `debug` operator will be more efficient. `debug` operator will print out all events to standard output and you can add also label those events.
|
||||
|
||||
`debug` acts like a probe. Here is an example of using it:
|
||||
|
||||
|
|
@ -809,17 +809,34 @@ This is simply 4
|
|||
Disposed
|
||||
```
|
||||
|
||||
You can also use `subscribe` instead of `subscribeNext`
|
||||
You can also easily create your version of the `debug` operator.
|
||||
|
||||
```swift
|
||||
NSURLSession.sharedSession().rx_JSON(request)
|
||||
.map { json in
|
||||
return parse()
|
||||
}
|
||||
.subscribe { n in // this subscribes on all events including error and completed
|
||||
print(n)
|
||||
}
|
||||
```
|
||||
extension ObservableType {
|
||||
public func myDebug(identifier: String) -> Observable<Self.E> {
|
||||
return Observable.create { observer in
|
||||
print("subscribed \(identifier)")
|
||||
let subscription = self.subscribe { e in
|
||||
print("event \(identifier) \(e)")
|
||||
switch e {
|
||||
case .Next(let value):
|
||||
observer.on(.Next(value))
|
||||
|
||||
case .Error(let error):
|
||||
observer.on(.Error(error))
|
||||
|
||||
case .Completed:
|
||||
observer.on(.Completed)
|
||||
}
|
||||
}
|
||||
return AnonymousDisposable {
|
||||
print("disposing \(identifier)")
|
||||
subscription.dispose()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Debugging memory leaks
|
||||
|
||||
|
|
@ -964,7 +981,7 @@ self.rx_observe(CGRect.self, "view.frame", retainSelf: false)
|
|||
|
||||
### `rx_observeWeakly`
|
||||
|
||||
`rx_observeWeakly` has somewhat slower then `rx_observe` because it has to handle object deallocation in case of weak references.
|
||||
`rx_observeWeakly` has somewhat slower than `rx_observe` because it has to handle object deallocation in case of weak references.
|
||||
|
||||
It can be used in all cases where `rx_observe` can be used and additionally
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
Tips
|
||||
====
|
||||
|
||||
* Always strive to model your systems or their parts as pure functions. Those pure functions can be tested easily and can be used to modify operator behaviors.
|
||||
* When you are using Rx, first try to compose built-in operators.
|
||||
* If using some combination of operators often, create your convenience operators.
|
||||
|
||||
e.g.
|
||||
```swift
|
||||
extension ObservableType where E: MaybeCool {
|
||||
|
||||
@warn_unused_result(message="http://git.io/rxs.uo")
|
||||
public func coolElements()
|
||||
-> Observable<E> {
|
||||
return filter { e -> Bool in
|
||||
return e.isCool
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
* Rx operators are as general as possible, but there will always be edge cases that will be hard to model. In those cases you can just create your own operator and possibly use one of the built-in operators as a reference.
|
||||
|
||||
* Always use operators to compose subscriptions.
|
||||
|
||||
**Avoid nesting subscribe calls at all cost. This is a bad smell.**
|
||||
|
||||
```swift
|
||||
textField.rx_text.subscribeNext { text in
|
||||
performURLRequest(text).subscribeNext { result in
|
||||
...
|
||||
}
|
||||
.addDisposableTo(disposeBag)
|
||||
}
|
||||
.addDisposableTo(disposeBag)
|
||||
```
|
||||
|
||||
**Preferred way of chaining disposables by using operators.**
|
||||
|
||||
```swift
|
||||
textField.rx_text
|
||||
.flatMapLatest { text in
|
||||
// Assuming this doesn't fail and returns result on main scheduler,
|
||||
// otherwise `catchError` and `observeOn(MainScheduler.instance)` can be used to
|
||||
// correct this.
|
||||
return performURLRequest(text)
|
||||
}
|
||||
...
|
||||
.addDisposableTo(disposeBag) // only one top most disposable
|
||||
```
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
Unit Tests
|
||||
==========
|
||||
|
||||
## Testing custom operators
|
||||
|
||||
Library uses `RxTests` for all of RxSwift operator tests so you can take a look at AllTests-* target inside the project `Rx.xcworkspace`.
|
||||
|
||||
This is an example of a typical `RxSwift` operator unit test:
|
||||
|
||||
```swift
|
||||
func testMap_Range() {
|
||||
// Initializes test scheduler.
|
||||
// Test scheduler implements virtual time that is
|
||||
// detached from local machine clock.
|
||||
// That enables running the simulation as fast as possible
|
||||
// and proving that all events have been handled.
|
||||
let scheduler = TestScheduler(initialClock: 0)
|
||||
|
||||
// Creates a mock hot observable sequence.
|
||||
// The sequence will emit events at following
|
||||
// times no matter is there some observer subscribed.
|
||||
// (that's what hot means).
|
||||
// This observable sequence will also record all subscriptions
|
||||
// made during it's lifetime (`subscriptions` property).
|
||||
let xs = scheduler.createHotObservable([
|
||||
next(150, 1), // first argument is virtual time, second argument is element value
|
||||
next(210, 0),
|
||||
next(220, 1),
|
||||
next(230, 2),
|
||||
next(240, 4),
|
||||
completed(300) // virtual time when completed is sent
|
||||
])
|
||||
|
||||
// `start` method will by default:
|
||||
// * run the simulation and record all events
|
||||
// using observer referenced by `res`.
|
||||
// * subscribe at virtual time 200
|
||||
// * dispose subscription at virtual time 1000
|
||||
let res = scheduler.start { xs.map { $0 * 2 } }
|
||||
|
||||
let correctMessages = [
|
||||
next(210, 0 * 2),
|
||||
next(220, 1 * 2),
|
||||
next(230, 2 * 2),
|
||||
next(240, 4 * 2),
|
||||
completed(300)
|
||||
]
|
||||
|
||||
let correctSubscriptions = [
|
||||
Subscription(200, 300)
|
||||
]
|
||||
|
||||
XCTAssertEqual(res.events, correctMessages)
|
||||
XCTAssertEqual(xs.subscriptions, correctSubscriptions)
|
||||
}
|
||||
```
|
||||
|
||||
## Testing operator compositions (view models, components)
|
||||
|
||||
Examples how to test operator compositions are contained inside `Rx.xcworkspace` > `RxExample-iOSTests` target.
|
||||
|
||||
It easy to define `RxTests` extensions so you can write your tests in a readable way. Provided examples inside `RxExample-iOSTests` are just a tip how you can write those extensions, but there is a lot of possibilities how to write those tests.
|
||||
|
||||
```swift
|
||||
// expected events and test data
|
||||
let (
|
||||
usernameEvents,
|
||||
passwordEvents,
|
||||
repeatedPasswordEvents,
|
||||
loginTapEvents,
|
||||
|
||||
expectedValidatedUsernameEvents,
|
||||
expectedSignupEnabledEvents
|
||||
) = (
|
||||
scheduler.parseEventsAndTimes("e---u1----u2-----u3-----------------", values: stringValues).first!,
|
||||
scheduler.parseEventsAndTimes("e----------------------p1-----------", values: stringValues).first!,
|
||||
scheduler.parseEventsAndTimes("e---------------------------p2---p1-", values: stringValues).first!,
|
||||
scheduler.parseEventsAndTimes("------------------------------------", values: events).first!,
|
||||
|
||||
scheduler.parseEventsAndTimes("e---v--f--v--f---v--o----------------", values: validations).first!,
|
||||
scheduler.parseEventsAndTimes("f--------------------------------t---", values: booleans).first!
|
||||
)
|
||||
```
|
||||
|
||||
## Integration tests
|
||||
|
||||
It is also possible to write integration tests by using `RxBlocking` operators.
|
||||
|
||||
Importing operators from `RxBlocking` library will enable blocking the current thread and wait for sequence results.
|
||||
|
||||
```swift
|
||||
let result = try fetchResource(location)
|
||||
.toBlocking()
|
||||
.toArray()
|
||||
|
||||
XCTAssertEqual(result, expectedResult)
|
||||
```
|
||||
|
|
@ -24,8 +24,11 @@ KVO observing, async operations and streams are all unified under [abstraction o
|
|||
###### ... understand
|
||||
|
||||
* [why use rx?](Documentation/Why.md)
|
||||
* how does RxSwift work? [Getting Started Guide](Documentation/GettingStarted.md)
|
||||
* what is `Driver`, `ControlProperty`, and `Variable` ... and why do they exist? [Units](Documentation/Units.md)
|
||||
* [the basics, getting started with RxSwift](Documentation/GettingStarted.md)
|
||||
* [units](Documentation/Units.md) - what is `Driver`, `ControlProperty`, and `Variable` ... and why do they exist?
|
||||
* [testing](Documentation/UnitTests.md)
|
||||
* [tips and common errors](Documentation/Tips.md)
|
||||
* [debugging](Documentation/GettingStarted.md#debugging)
|
||||
* [the math behind Rx](Documentation/MathBehindRx.md)
|
||||
* [what are hot and cold observable sequences?](Documentation/HotAndColdObservables.md)
|
||||
* [what does the the public API look like?](Documentation/API.md)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,12 @@
|
|||
/*:
|
||||
> # IMPORTANT: To use `Rx.playground`, please:
|
||||
|
||||
1. Open `Rx.xcworkspace`
|
||||
2. Build `RxSwift-OSX` scheme
|
||||
3. And then open `Rx` playground in `Rx.xcworkspace` tree view.
|
||||
4. Choose `View > Show Debug Area`
|
||||
*/
|
||||
|
||||
//: [<< Previous](@previous) - [Index](Index)
|
||||
|
||||
import RxSwift
|
||||
|
|
|
|||
|
|
@ -1,3 +1,12 @@
|
|||
/*:
|
||||
> # IMPORTANT: To use `Rx.playground`, please:
|
||||
|
||||
1. Open `Rx.xcworkspace`
|
||||
2. Build `RxSwift-OSX` scheme
|
||||
3. And then open `Rx` playground in `Rx.xcworkspace` tree view.
|
||||
4. Choose `View > Show Debug Area`
|
||||
*/
|
||||
|
||||
//: [<< Previous](@previous) - [Index](Index)
|
||||
|
||||
import Cocoa
|
||||
|
|
|
|||
|
|
@ -1,3 +1,12 @@
|
|||
/*:
|
||||
> # IMPORTANT: To use `Rx.playground`, please:
|
||||
|
||||
1. Open `Rx.xcworkspace`
|
||||
2. Build `RxSwift-OSX` scheme
|
||||
3. And then open `Rx` playground in `Rx.xcworkspace` tree view.
|
||||
4. Choose `View > Show Debug Area`
|
||||
*/
|
||||
|
||||
//: [<< Previous](@previous) - [Index](Index)
|
||||
|
||||
import RxSwift
|
||||
|
|
|
|||
|
|
@ -1,3 +1,12 @@
|
|||
/*:
|
||||
> # IMPORTANT: To use `Rx.playground`, please:
|
||||
|
||||
1. Open `Rx.xcworkspace`
|
||||
2. Build `RxSwift-OSX` scheme
|
||||
3. And then open `Rx` playground in `Rx.xcworkspace` tree view.
|
||||
4. Choose `View > Show Debug Area`
|
||||
*/
|
||||
|
||||
//: [<< Previous](@previous) - [Index](Index)
|
||||
|
||||
import RxSwift
|
||||
|
|
|
|||
|
|
@ -1,3 +1,12 @@
|
|||
/*:
|
||||
> # IMPORTANT: To use `Rx.playground`, please:
|
||||
|
||||
1. Open `Rx.xcworkspace`
|
||||
2. Build `RxSwift-OSX` scheme
|
||||
3. And then open `Rx` playground in `Rx.xcworkspace` tree view.
|
||||
4. Choose `View > Show Debug Area`
|
||||
*/
|
||||
|
||||
//: [<< Previous](@previous) - [Index](Index)
|
||||
|
||||
import RxSwift
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
/*:
|
||||
> # IMPORTANT: To use `RxSamples`, please:
|
||||
> # IMPORTANT: To use `Rx.playground`, please:
|
||||
|
||||
1. Open `Rx.xcworkspace`
|
||||
2. Build `RxSwift-OSX` scheme
|
||||
|
|
|
|||
|
|
@ -1,3 +1,12 @@
|
|||
/*:
|
||||
> # IMPORTANT: To use `Rx.playground`, please:
|
||||
|
||||
1. Open `Rx.xcworkspace`
|
||||
2. Build `RxSwift-OSX` scheme
|
||||
3. And then open `Rx` playground in `Rx.xcworkspace` tree view.
|
||||
4. Choose `View > Show Debug Area`
|
||||
*/
|
||||
|
||||
//: [<< Index](@previous)
|
||||
|
||||
import RxSwift
|
||||
|
|
|
|||
|
|
@ -1,3 +1,12 @@
|
|||
/*:
|
||||
> # IMPORTANT: To use `Rx.playground`, please:
|
||||
|
||||
1. Open `Rx.xcworkspace`
|
||||
2. Build `RxSwift-OSX` scheme
|
||||
3. And then open `Rx` playground in `Rx.xcworkspace` tree view.
|
||||
4. Choose `View > Show Debug Area`
|
||||
*/
|
||||
|
||||
//: [<< Previous](@previous) - [Index](Index)
|
||||
|
||||
import RxSwift
|
||||
|
|
|
|||
|
|
@ -1,3 +1,12 @@
|
|||
/*:
|
||||
> # IMPORTANT: To use `Rx.playground`, please:
|
||||
|
||||
1. Open `Rx.xcworkspace`
|
||||
2. Build `RxSwift-OSX` scheme
|
||||
3. And then open `Rx` playground in `Rx.xcworkspace` tree view.
|
||||
4. Choose `View > Show Debug Area`
|
||||
*/
|
||||
|
||||
//: [<< Previous](@previous) - [Index](Index)
|
||||
|
||||
import RxSwift
|
||||
|
|
|
|||
|
|
@ -1,3 +1,12 @@
|
|||
/*:
|
||||
> # IMPORTANT: To use `Rx.playground`, please:
|
||||
|
||||
1. Open `Rx.xcworkspace`
|
||||
2. Build `RxSwift-OSX` scheme
|
||||
3. And then open `Rx` playground in `Rx.xcworkspace` tree view.
|
||||
4. Choose `View > Show Debug Area`
|
||||
*/
|
||||
|
||||
//: [<< Previous](@previous) - [Index](Index)
|
||||
|
||||
import RxSwift
|
||||
|
|
|
|||
|
|
@ -1,3 +1,12 @@
|
|||
/*:
|
||||
> # IMPORTANT: To use `Rx.playground`, please:
|
||||
|
||||
1. Open `Rx.xcworkspace`
|
||||
2. Build `RxSwift-OSX` scheme
|
||||
3. And then open `Rx` playground in `Rx.xcworkspace` tree view.
|
||||
4. Choose `View > Show Debug Area`
|
||||
*/
|
||||
|
||||
//: [<< Previous](@previous) - [Index](Index)
|
||||
|
||||
import RxSwift
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<playground version='6.0' target-platform='osx' display-mode='rendered'>
|
||||
<playground version='6.0' target-platform='osx' display-mode='raw'>
|
||||
<pages>
|
||||
<page name='Index'/>
|
||||
<page name='Introduction'/>
|
||||
|
|
|
|||
|
|
@ -11,6 +11,11 @@
|
|||
79E9DE8A1C3417FD009970AF /* DispatchQueueSchedulerQOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79E9DE881C3417FD009970AF /* DispatchQueueSchedulerQOS.swift */; };
|
||||
79E9DE8B1C3417FD009970AF /* DispatchQueueSchedulerQOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79E9DE881C3417FD009970AF /* DispatchQueueSchedulerQOS.swift */; };
|
||||
79E9DE8C1C3417FD009970AF /* DispatchQueueSchedulerQOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79E9DE881C3417FD009970AF /* DispatchQueueSchedulerQOS.swift */; };
|
||||
7EDBAEB41C89B1A6006CBE67 /* UITabBarItem+RxTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7EDBAEAB1C89B1A5006CBE67 /* UITabBarItem+RxTests.swift */; };
|
||||
7EDBAEBC1C89B9B7006CBE67 /* UITabBarItem+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7EDBAEB71C89B9B7006CBE67 /* UITabBarItem+Rx.swift */; };
|
||||
7EDBAEBE1C89B9B7006CBE67 /* UITabBarItem+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7EDBAEB71C89B9B7006CBE67 /* UITabBarItem+Rx.swift */; };
|
||||
7EDBAEBF1C89B9B7006CBE67 /* UITabBarItem+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7EDBAEB71C89B9B7006CBE67 /* UITabBarItem+Rx.swift */; };
|
||||
7EDBAEC31C89BCB9006CBE67 /* UITabBarItem+RxTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7EDBAEAB1C89B1A5006CBE67 /* UITabBarItem+RxTests.swift */; };
|
||||
7F600F3F1C5D0C6C00535B1D /* UIRefreshControl+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F600F3D1C5D0C0100535B1D /* UIRefreshControl+Rx.swift */; };
|
||||
7F600F401C5D0C6D00535B1D /* UIRefreshControl+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F600F3D1C5D0C0100535B1D /* UIRefreshControl+Rx.swift */; };
|
||||
7F600F411C5D0C6E00535B1D /* UIRefreshControl+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F600F3D1C5D0C0100535B1D /* UIRefreshControl+Rx.swift */; };
|
||||
|
|
@ -35,6 +40,8 @@
|
|||
9BA1CBFD1C0F84A10044B50A /* UIActivityIndicatorView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BA1CBD11C0F7C0A0044B50A /* UIActivityIndicatorView+Rx.swift */; };
|
||||
9BA1CBFE1C0F84C40044B50A /* UIActivityIndicatorView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BA1CBD11C0F7C0A0044B50A /* UIActivityIndicatorView+Rx.swift */; };
|
||||
9D71C4D21BF08191006E8F59 /* UIButton+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = C88254061B8A752B00B02D69 /* UIButton+Rx.swift */; };
|
||||
AAE623761C82475700FC7801 /* UIProgressView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAE623751C82475700FC7801 /* UIProgressView+Rx.swift */; };
|
||||
AAE623771C82475700FC7801 /* UIProgressView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAE623751C82475700FC7801 /* UIProgressView+Rx.swift */; };
|
||||
B1B7C3BD1BDD39DB0076934E /* TakeLast.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1B7C3BC1BDD39DB0076934E /* TakeLast.swift */; };
|
||||
B1B7C3BE1BDD39DB0076934E /* TakeLast.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1B7C3BC1BDD39DB0076934E /* TakeLast.swift */; };
|
||||
B1B7C3BF1BDD39DB0076934E /* TakeLast.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1B7C3BC1BDD39DB0076934E /* TakeLast.swift */; };
|
||||
|
|
@ -635,6 +642,10 @@
|
|||
C8B145011BD2D80100267DCE /* ImmediateScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8B144FF1BD2D80100267DCE /* ImmediateScheduler.swift */; };
|
||||
C8B145021BD2D80100267DCE /* ImmediateScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8B144FF1BD2D80100267DCE /* ImmediateScheduler.swift */; };
|
||||
C8B145031BD2D80100267DCE /* ImmediateScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8B144FF1BD2D80100267DCE /* ImmediateScheduler.swift */; };
|
||||
C8B290891C94D64600E923D0 /* RxTest+Controls.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8B290841C94D55600E923D0 /* RxTest+Controls.swift */; };
|
||||
C8B2908A1C94D64700E923D0 /* RxTest+Controls.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8B290841C94D55600E923D0 /* RxTest+Controls.swift */; };
|
||||
C8B2908B1C94D64700E923D0 /* RxTest+Controls.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8B290841C94D55600E923D0 /* RxTest+Controls.swift */; };
|
||||
C8B2908D1C94D6C500E923D0 /* UISearchBar+RxTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8B2908C1C94D6C500E923D0 /* UISearchBar+RxTests.swift */; };
|
||||
C8BCD3C71C1468D4005F1280 /* ShareReplay1WhileConnected.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8BCD3C61C1468D4005F1280 /* ShareReplay1WhileConnected.swift */; };
|
||||
C8BCD3C81C1468D4005F1280 /* ShareReplay1WhileConnected.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8BCD3C61C1468D4005F1280 /* ShareReplay1WhileConnected.swift */; };
|
||||
C8BCD3C91C1468D4005F1280 /* ShareReplay1WhileConnected.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8BCD3C61C1468D4005F1280 /* ShareReplay1WhileConnected.swift */; };
|
||||
|
|
@ -1316,6 +1327,8 @@
|
|||
|
||||
/* Begin PBXFileReference section */
|
||||
79E9DE881C3417FD009970AF /* DispatchQueueSchedulerQOS.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DispatchQueueSchedulerQOS.swift; sourceTree = "<group>"; };
|
||||
7EDBAEAB1C89B1A5006CBE67 /* UITabBarItem+RxTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UITabBarItem+RxTests.swift"; sourceTree = "<group>"; };
|
||||
7EDBAEB71C89B9B7006CBE67 /* UITabBarItem+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UITabBarItem+Rx.swift"; sourceTree = "<group>"; };
|
||||
7F600F3D1C5D0C0100535B1D /* UIRefreshControl+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIRefreshControl+Rx.swift"; sourceTree = "<group>"; };
|
||||
7F600F421C5D0D2D00535B1D /* UIRefreshControl+RxTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIRefreshControl+RxTests.swift"; sourceTree = "<group>"; };
|
||||
842A5A281C357F7D003568D5 /* NSTextStorage+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSTextStorage+Rx.swift"; sourceTree = "<group>"; };
|
||||
|
|
@ -1325,6 +1338,7 @@
|
|||
84C225A21C33F00B008724EC /* RxTextStorageDelegateProxy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxTextStorageDelegateProxy.swift; sourceTree = "<group>"; };
|
||||
9BA1CBD11C0F7C0A0044B50A /* UIActivityIndicatorView+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIActivityIndicatorView+Rx.swift"; sourceTree = "<group>"; };
|
||||
A111CE961B91C97C00D0DCEE /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
AAE623751C82475700FC7801 /* UIProgressView+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIProgressView+Rx.swift"; sourceTree = "<group>"; };
|
||||
B1B7C3BC1BDD39DB0076934E /* TakeLast.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TakeLast.swift; sourceTree = "<group>"; };
|
||||
B1D8998E1BF653410027B05C /* Timeout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Timeout.swift; sourceTree = "<group>"; };
|
||||
C807F3611C2ACED300017910 /* TestSchedulerVirtualTimeConverter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestSchedulerVirtualTimeConverter.swift; sourceTree = "<group>"; };
|
||||
|
|
@ -1603,6 +1617,8 @@
|
|||
C8A56AD71AD7424700B4673B /* RxSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RxSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
C8B144FA1BD2D44500267DCE /* ConcurrentMainScheduler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConcurrentMainScheduler.swift; sourceTree = "<group>"; };
|
||||
C8B144FF1BD2D80100267DCE /* ImmediateScheduler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImmediateScheduler.swift; sourceTree = "<group>"; };
|
||||
C8B290841C94D55600E923D0 /* RxTest+Controls.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "RxTest+Controls.swift"; sourceTree = "<group>"; };
|
||||
C8B2908C1C94D6C500E923D0 /* UISearchBar+RxTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UISearchBar+RxTests.swift"; sourceTree = "<group>"; };
|
||||
C8BCD3C61C1468D4005F1280 /* ShareReplay1WhileConnected.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShareReplay1WhileConnected.swift; sourceTree = "<group>"; };
|
||||
C8BCD3EC1C14B5FB005F1280 /* UIView+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+Rx.swift"; sourceTree = "<group>"; };
|
||||
C8BCD3F11C14B62B005F1280 /* NSView+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSView+Rx.swift"; sourceTree = "<group>"; };
|
||||
|
|
@ -2175,6 +2191,7 @@
|
|||
C8D132511C42DA7F00B59FFF /* TestImplementations */,
|
||||
C83508D91C38706D0027C24C /* CLLocationManager+RxTests.swift */,
|
||||
8476A01F1C3D5D580040BA22 /* UIImagePickerController+RxTests.swift */,
|
||||
C8B290841C94D55600E923D0 /* RxTest+Controls.swift */,
|
||||
C83508DA1C38706D0027C24C /* Control+RxTests+Cocoa.swift */,
|
||||
C83508DB1C38706D0027C24C /* Control+RxTests+UIKit.swift */,
|
||||
C83508DC1C38706D0027C24C /* Control+RxTests.swift */,
|
||||
|
|
@ -2200,6 +2217,8 @@
|
|||
C83508F01C38706D0027C24C /* SentMessageTest.swift */,
|
||||
C83508F11C38706D0027C24C /* UIView+RxTests.swift */,
|
||||
7F600F421C5D0D2D00535B1D /* UIRefreshControl+RxTests.swift */,
|
||||
7EDBAEAB1C89B1A5006CBE67 /* UITabBarItem+RxTests.swift */,
|
||||
C8B2908C1C94D6C500E923D0 /* UISearchBar+RxTests.swift */,
|
||||
);
|
||||
path = RxCocoaTests;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -2322,6 +2341,7 @@
|
|||
C882540A1B8A752B00B02D69 /* UIGestureRecognizer+Rx.swift */,
|
||||
C882540B1B8A752B00B02D69 /* UIImageView+Rx.swift */,
|
||||
C882540C1B8A752B00B02D69 /* UILabel+Rx.swift */,
|
||||
AAE623751C82475700FC7801 /* UIProgressView+Rx.swift */,
|
||||
7F600F3D1C5D0C0100535B1D /* UIRefreshControl+Rx.swift */,
|
||||
C882540D1B8A752B00B02D69 /* UIScrollView+Rx.swift */,
|
||||
C882540E1B8A752B00B02D69 /* UISearchBar+Rx.swift */,
|
||||
|
|
@ -2336,6 +2356,7 @@
|
|||
9BA1CBD11C0F7C0A0044B50A /* UIActivityIndicatorView+Rx.swift */,
|
||||
8479BC4A1C3ACED100FB8B54 /* UIImagePickerController+Rx.swift */,
|
||||
C8BCD3EC1C14B5FB005F1280 /* UIView+Rx.swift */,
|
||||
7EDBAEB71C89B9B7006CBE67 /* UITabBarItem+Rx.swift */,
|
||||
);
|
||||
path = iOS;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -3244,6 +3265,7 @@
|
|||
C882542E1B8A752B00B02D69 /* UILabel+Rx.swift in Sources */,
|
||||
C88254211B8A752B00B02D69 /* RxSearchBarDelegateProxy.swift in Sources */,
|
||||
C80DDEA71BCE69BA006A1832 /* ObservableConvertibleType+Driver.swift in Sources */,
|
||||
7EDBAEBC1C89B9B7006CBE67 /* UITabBarItem+Rx.swift in Sources */,
|
||||
C839365F1C70E02200A9A09E /* UIApplication+Rx.swift in Sources */,
|
||||
C80DDE9F1BCE69BA006A1832 /* Driver+Subscription.swift in Sources */,
|
||||
C811C89D1C24D80100A2DDD4 /* DeallocObservable.swift in Sources */,
|
||||
|
|
@ -3251,6 +3273,7 @@
|
|||
C80D338F1B91EF9E0014629D /* Observable+Bind.swift in Sources */,
|
||||
C88254311B8A752B00B02D69 /* UISegmentedControl+Rx.swift in Sources */,
|
||||
C8093EED1B8A732E0088E94D /* KVOObservable.swift in Sources */,
|
||||
AAE623761C82475700FC7801 /* UIProgressView+Rx.swift in Sources */,
|
||||
C8DB968D1BF7595D0084BD53 /* KVORepresentable+Swift.swift in Sources */,
|
||||
C80DDEB11BCE8CA3006A1832 /* Driver+Operators+arity.swift in Sources */,
|
||||
C88254281B8A752B00B02D69 /* UIButton+Rx.swift in Sources */,
|
||||
|
|
@ -3372,6 +3395,7 @@
|
|||
C835094B1C38706E0027C24C /* AnonymousObservable+Test.swift in Sources */,
|
||||
C835092E1C38706E0027C24C /* ControlEventTests.swift in Sources */,
|
||||
C83509531C38706E0027C24C /* Observable+AggregateTest.swift in Sources */,
|
||||
C8B290891C94D64600E923D0 /* RxTest+Controls.swift in Sources */,
|
||||
C83509291C38706E0027C24C /* PerformanceTools.swift in Sources */,
|
||||
C835096A1C38706E0027C24C /* TestErrors.swift in Sources */,
|
||||
C83509561C38706E0027C24C /* Observable+ConcurrencyTest.swift in Sources */,
|
||||
|
|
@ -3385,6 +3409,7 @@
|
|||
C835095F1C38706E0027C24C /* Observable+SubscriptionTest.swift in Sources */,
|
||||
C83509451C38706E0027C24C /* Observable.Extensions.swift in Sources */,
|
||||
C835093B1C38706E0027C24C /* RXObjCRuntime+Testing.m in Sources */,
|
||||
C8B2908D1C94D6C500E923D0 /* UISearchBar+RxTests.swift in Sources */,
|
||||
C83509641C38706E0027C24C /* VariableTest.swift in Sources */,
|
||||
C83509461C38706E0027C24C /* PrimitiveHotObservable.swift in Sources */,
|
||||
C835097E1C38726E0027C24C /* RxMutableBox.swift in Sources */,
|
||||
|
|
@ -3396,6 +3421,7 @@
|
|||
C83509331C38706E0027C24C /* Driver+Extensions.swift in Sources */,
|
||||
C835094F1C38706E0027C24C /* CurrentThreadSchedulerTest.swift in Sources */,
|
||||
C835093E1C38706E0027C24C /* UIView+RxTests.swift in Sources */,
|
||||
7EDBAEB41C89B1A6006CBE67 /* UITabBarItem+RxTests.swift in Sources */,
|
||||
C83509411C38706E0027C24C /* BackgroundThreadPrimitiveHotObservable.swift in Sources */,
|
||||
C83509581C38706E0027C24C /* Observable+MultipleTest+CombineLatest.swift in Sources */,
|
||||
C83509651C38706E0027C24C /* VirtualSchedulerTest.swift in Sources */,
|
||||
|
|
@ -3444,6 +3470,7 @@
|
|||
C83509EE1C3875580027C24C /* Observable.Extensions.swift in Sources */,
|
||||
C83509BD1C38750D0027C24C /* ControlPropertyTests.swift in Sources */,
|
||||
C83509E11C3875500027C24C /* TestVirtualScheduler.swift in Sources */,
|
||||
C8B2908A1C94D64700E923D0 /* RxTest+Controls.swift in Sources */,
|
||||
C8350A181C38756A0027C24C /* VariableTest.swift in Sources */,
|
||||
C83509EF1C3875580027C24C /* PrimitiveHotObservable.swift in Sources */,
|
||||
C83509FB1C38755D0027C24C /* Observable+BindingTest.swift in Sources */,
|
||||
|
|
@ -3481,6 +3508,7 @@
|
|||
C8350A121C38756A0027C24C /* Observable+StandardSequenceOperatorsTest.swift in Sources */,
|
||||
C83509C31C3875220027C24C /* KVOObservableTests.swift in Sources */,
|
||||
C83509F91C38755D0027C24C /* MainSchedulerTests.swift in Sources */,
|
||||
7EDBAEC31C89BCB9006CBE67 /* UITabBarItem+RxTests.swift in Sources */,
|
||||
C83509AB1C3874D20027C24C /* XCTest+AllTests.swift in Sources */,
|
||||
C83509C11C3875220027C24C /* Driver+Extensions.swift in Sources */,
|
||||
C83509DD1C38754C0027C24C /* EquatableArray.swift in Sources */,
|
||||
|
|
@ -3534,6 +3562,7 @@
|
|||
C8350A081C38755E0027C24C /* Observable+AggregateTest.swift in Sources */,
|
||||
C83509E81C3875580027C24C /* PrimitiveMockObserver.swift in Sources */,
|
||||
C83509BE1C3875100027C24C /* DelegateProxyTest+Cocoa.swift in Sources */,
|
||||
C8B2908B1C94D64700E923D0 /* RxTest+Controls.swift in Sources */,
|
||||
C8350A1B1C38756B0027C24C /* Observable+SingleTest.swift in Sources */,
|
||||
C8350A231C38756B0027C24C /* VirtualSchedulerTest.swift in Sources */,
|
||||
C83509E51C3875580027C24C /* MySubject.swift in Sources */,
|
||||
|
|
@ -4173,6 +4202,7 @@
|
|||
C8F0C03A1BBBFBB9001B112F /* ControlTarget.swift in Sources */,
|
||||
C8F0C03B1BBBFBB9001B112F /* UISearchBar+Rx.swift in Sources */,
|
||||
C8F0C03C1BBBFBB9001B112F /* ItemEvents.swift in Sources */,
|
||||
7EDBAEBF1C89B9B7006CBE67 /* UITabBarItem+Rx.swift in Sources */,
|
||||
C8DB968B1BF756F40084BD53 /* KVORepresentable+CoreGraphics.swift in Sources */,
|
||||
C8FD21B11C67E14C00863EC3 /* UIBindingObserver.swift in Sources */,
|
||||
C8F0C03D1BBBFBB9001B112F /* RxTableViewDataSourceType.swift in Sources */,
|
||||
|
|
@ -4248,6 +4278,7 @@
|
|||
D203C50D1BB9C53E00D02D00 /* UISegmentedControl+Rx.swift in Sources */,
|
||||
C8C4B4C41C17727000828BD5 /* MessageSentObserver.swift in Sources */,
|
||||
D2138C861BB9BEBE00339B5C /* Observable+Bind.swift in Sources */,
|
||||
AAE623771C82475700FC7801 /* UIProgressView+Rx.swift in Sources */,
|
||||
D203C50A1BB9C53E00D02D00 /* UILabel+Rx.swift in Sources */,
|
||||
D203C4F51BB9C52900D02D00 /* ItemEvents.swift in Sources */,
|
||||
C8BCD3F61C14B6D1005F1280 /* NSLayoutConstraint+Rx.swift in Sources */,
|
||||
|
|
@ -4265,6 +4296,7 @@
|
|||
9D71C4D21BF08191006E8F59 /* UIButton+Rx.swift in Sources */,
|
||||
D203C4FD1BB9C53700D02D00 /* RxSearchBarDelegateProxy.swift in Sources */,
|
||||
D2138C8A1BB9BEBE00339B5C /* Logging.swift in Sources */,
|
||||
7EDBAEBE1C89B9B7006CBE67 /* UITabBarItem+Rx.swift in Sources */,
|
||||
C8DB968A1BF756F40084BD53 /* KVORepresentable+CoreGraphics.swift in Sources */,
|
||||
C8FD21B01C67E14C00863EC3 /* UIBindingObserver.swift in Sources */,
|
||||
D203C50F1BB9C53E00D02D00 /* UIStepper+Rx.swift in Sources */,
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ extension NSNotificationCenter {
|
|||
- returns: Observable sequence of posted notifications.
|
||||
*/
|
||||
@warn_unused_result(message="http://git.io/rxs.uo")
|
||||
public func rx_notification(name: String, object: AnyObject? = nil) -> Observable<NSNotification> {
|
||||
public func rx_notification(name: String?, object: AnyObject? = nil) -> Observable<NSNotification> {
|
||||
return Observable.create { [weak object] observer in
|
||||
let nsObserver = self.addObserverForName(name, object: object, queue: nil) { notification in
|
||||
observer.on(.Next(notification))
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ extension NSURLSession {
|
|||
public func rx_data(request: NSURLRequest) -> Observable<NSData> {
|
||||
return rx_response(request).map { (data, response) -> NSData in
|
||||
if 200 ..< 300 ~= response.statusCode {
|
||||
return data ?? NSData()
|
||||
return data
|
||||
}
|
||||
else {
|
||||
throw RxCocoaURLError.HTTPRequestFailed(response: response, data: data)
|
||||
|
|
@ -209,7 +209,7 @@ extension NSURLSession {
|
|||
public func rx_JSON(request: NSURLRequest) -> Observable<AnyObject> {
|
||||
return rx_data(request).map { (data) -> AnyObject in
|
||||
do {
|
||||
return try NSJSONSerialization.JSONObjectWithData(data ?? NSData(), options: [])
|
||||
return try NSJSONSerialization.JSONObjectWithData(data, options: [])
|
||||
} catch let error {
|
||||
throw RxCocoaURLError.DeserializationError(error: error)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@ static NSMutableDictionary *forwardableSelectorsPerClass = nil;
|
|||
for (unsigned int i = 0; i < numberOfBaseProtocols; ++i) {
|
||||
[selectors unionSet:[self collectSelectorsForProtocol:pSubprotocols[i]]];
|
||||
}
|
||||
|
||||
free(pSubprotocols);
|
||||
|
||||
return selectors;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,9 +112,7 @@ extension UICollectionView {
|
|||
For more information take a look at `DelegateProxyType` protocol documentation.
|
||||
*/
|
||||
public var rx_dataSource: DelegateProxy {
|
||||
get {
|
||||
return proxyForObject(RxCollectionViewDataSourceProxy.self, self)
|
||||
}
|
||||
return proxyForObject(RxCollectionViewDataSourceProxy.self, self)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
//
|
||||
// UIProgressView+Rx.swift
|
||||
// Rx
|
||||
//
|
||||
// Created by Samuel Bae on 2/27/16.
|
||||
// Copyright © 2016 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
|
||||
import Foundation
|
||||
#if !RX_NO_MODULE
|
||||
import RxSwift
|
||||
#endif
|
||||
import UIKit
|
||||
|
||||
extension UIProgressView {
|
||||
|
||||
/**
|
||||
Bindable sink for `progress` property
|
||||
*/
|
||||
public var rx_progress: AnyObserver<Float> {
|
||||
return UIBindingObserver(UIElement: self) { progressView, progress in
|
||||
progressView.progress = progress
|
||||
}.asObserver()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
//
|
||||
// UITabBarItem+Rx.swift
|
||||
// Rx
|
||||
//
|
||||
// Created by Mateusz Derks on 04/03/16.
|
||||
// Copyright © 2016 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
#if !RX_NO_MODULE
|
||||
import RxSwift
|
||||
#endif
|
||||
|
||||
extension UITabBarItem {
|
||||
|
||||
/**
|
||||
Bindable sink for `badgeValue` property.
|
||||
*/
|
||||
public var rx_badgeValue: AnyObserver<String?> {
|
||||
return UIBindingObserver(UIElement: self) { tabBarItem, badgeValue in
|
||||
tabBarItem.badgeValue = badgeValue
|
||||
}.asObserver()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -35,7 +35,14 @@ extension UITextView {
|
|||
let text = self?.text ?? ""
|
||||
|
||||
let textChanged = self?.textStorage
|
||||
// This project uses text storage notifications because
|
||||
// that's the only way to catch autocorrect changes
|
||||
// in all cases. Other suggestions are welcome.
|
||||
.rx_didProcessEditingRangeChangeInLength
|
||||
// This observe on is here because text storage
|
||||
// will emit event while process is not completely done,
|
||||
// so rebinding a value will cause an exception to be thrown.
|
||||
.observeOn(MainScheduler.asyncInstance)
|
||||
.map { _ in
|
||||
return self?.textStorage.string ?? ""
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,9 +18,7 @@ struct ItemPath : CustomDebugStringConvertible {
|
|||
let itemIndex: Int
|
||||
|
||||
var debugDescription : String {
|
||||
get {
|
||||
return "(\(sectionIndex), \(itemIndex))"
|
||||
}
|
||||
return "(\(sectionIndex), \(itemIndex))"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -51,20 +49,18 @@ public struct Changeset<S: SectionModelType> : CustomDebugStringConvertible {
|
|||
}
|
||||
|
||||
public var debugDescription : String {
|
||||
get {
|
||||
let serializedSections = "[\n" + finalSections.map { "\($0)" }.joinWithSeparator(",\n") + "\n]\n"
|
||||
return " >> Final sections"
|
||||
let serializedSections = "[\n" + finalSections.map { "\($0)" }.joinWithSeparator(",\n") + "\n]\n"
|
||||
return " >> Final sections"
|
||||
+ " \n\(serializedSections)"
|
||||
+ (insertedSections.count > 0 || deletedSections.count > 0 || movedSections.count > 0 || updatedSections.count > 0 ? "\nSections:" : "")
|
||||
+ (insertedSections.count > 0 ? "\ninsertedSections:\n\t\(insertedSections)" : "")
|
||||
+ (deletedSections.count > 0 ? "\ndeletedSections:\n\t\(deletedSections)" : "")
|
||||
+ (movedSections.count > 0 ? "\nmovedSections:\n\t\(movedSections)" : "")
|
||||
+ (updatedSections.count > 0 ? "\nupdatesSections:\n\t\(updatedSections)" : "")
|
||||
+ (insertedItems.count > 0 || deletedItems.count > 0 || movedItems.count > 0 || updatedItems.count > 0 ? "\nItems:" : "")
|
||||
+ (insertedItems.count > 0 || deletedItems.count > 0 || movedItems.count > 0 || updatedItems.count > 0 ? "\nItems:" : "")
|
||||
+ (insertedItems.count > 0 ? "\ninsertedItems:\n\t\(insertedItems)" : "")
|
||||
+ (deletedItems.count > 0 ? "\ndeletedItems:\n\t\(deletedItems)" : "")
|
||||
+ (movedItems.count > 0 ? "\nmovedItems:\n\t\(movedItems)" : "")
|
||||
+ (updatedItems.count > 0 ? "\nupdatedItems:\n\t\(updatedItems)" : "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,19 +33,17 @@ enum EditEvent : CustomDebugStringConvertible {
|
|||
|
||||
extension EditEvent {
|
||||
var debugDescription: String {
|
||||
get {
|
||||
switch self {
|
||||
case .Inserted:
|
||||
return "Inserted"
|
||||
case .Deleted:
|
||||
return "Deleted"
|
||||
case .Moved:
|
||||
return "Moved"
|
||||
case .MovedAutomatically:
|
||||
return "MovedAutomatically"
|
||||
case .Untouched:
|
||||
return "Untouched"
|
||||
}
|
||||
switch self {
|
||||
case .Inserted:
|
||||
return "Inserted"
|
||||
case .Deleted:
|
||||
return "Deleted"
|
||||
case .Moved:
|
||||
return "Moved"
|
||||
case .MovedAutomatically:
|
||||
return "MovedAutomatically"
|
||||
case .Untouched:
|
||||
return "Untouched"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -57,9 +55,7 @@ struct SectionAdditionalInfo : CustomDebugStringConvertible {
|
|||
|
||||
extension SectionAdditionalInfo {
|
||||
var debugDescription: String {
|
||||
get {
|
||||
return "\(event), \(indexAfterDelete)"
|
||||
}
|
||||
return "\(event), \(indexAfterDelete)"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -70,9 +66,7 @@ struct ItemAdditionalInfo : CustomDebugStringConvertible {
|
|||
|
||||
extension ItemAdditionalInfo {
|
||||
var debugDescription: String {
|
||||
get {
|
||||
return "\(event) \(indexAfterDelete)"
|
||||
}
|
||||
return "\(event) \(indexAfterDelete)"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,9 +25,7 @@ public struct SectionModel<Section, ItemType> : SectionModelType, CustomStringCo
|
|||
}
|
||||
|
||||
public var description: String {
|
||||
get {
|
||||
return "\(self.model) > \(items)"
|
||||
}
|
||||
return "\(self.model) > \(items)"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -48,15 +46,11 @@ public struct HashableSectionModel<Section: Hashable, ItemType: Hashable> : Hash
|
|||
}
|
||||
|
||||
public var description: String {
|
||||
get {
|
||||
return "HashableSectionModel(model: \"\(self.model)\", items: \(items))"
|
||||
}
|
||||
return "HashableSectionModel(model: \"\(self.model)\", items: \(items))"
|
||||
}
|
||||
|
||||
public var hashValue: Int {
|
||||
get {
|
||||
return self.model.hashValue
|
||||
}
|
||||
return self.model.hashValue
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,7 +70,11 @@ class APIWrappersViewController: ViewController {
|
|||
|
||||
// MARK: UISegmentedControl
|
||||
|
||||
segmentedControl.rx_value
|
||||
// also test two way binding
|
||||
let segmentedValue = Variable(0)
|
||||
segmentedControl.rx_value <-> segmentedValue
|
||||
|
||||
segmentedValue.asObservable()
|
||||
.subscribeNext { [weak self] x in
|
||||
self?.debug("UISegmentedControl value \(x)")
|
||||
}
|
||||
|
|
@ -79,7 +83,11 @@ class APIWrappersViewController: ViewController {
|
|||
|
||||
// MARK: UISwitch
|
||||
|
||||
switcher.rx_value
|
||||
// also test two way binding
|
||||
let switchValue = Variable(false)
|
||||
switcher.rx_value <-> switchValue
|
||||
|
||||
switchValue.asObservable()
|
||||
.subscribeNext { [weak self] x in
|
||||
self?.debug("UISwitch value \(x)")
|
||||
}
|
||||
|
|
@ -103,7 +111,11 @@ class APIWrappersViewController: ViewController {
|
|||
|
||||
// MARK: UISlider
|
||||
|
||||
slider.rx_value
|
||||
// also test two way binding
|
||||
let sliderValue = Variable<Float>(0.0)
|
||||
slider.rx_value <-> sliderValue
|
||||
|
||||
sliderValue.asObservable()
|
||||
.subscribeNext { [weak self] x in
|
||||
self?.debug("UISlider value \(x)")
|
||||
}
|
||||
|
|
@ -112,7 +124,12 @@ class APIWrappersViewController: ViewController {
|
|||
|
||||
// MARK: UIDatePicker
|
||||
|
||||
datePicker.rx_date
|
||||
// also test two way binding
|
||||
let dateValue = Variable(NSDate())
|
||||
datePicker.rx_date <-> dateValue
|
||||
|
||||
|
||||
dateValue.asObservable()
|
||||
.subscribeNext { [weak self] x in
|
||||
self?.debug("UIDatePicker date \(x)")
|
||||
}
|
||||
|
|
@ -121,7 +138,11 @@ class APIWrappersViewController: ViewController {
|
|||
|
||||
// MARK: UITextField
|
||||
|
||||
textField.rx_text
|
||||
// also test two way binding
|
||||
let textValue = Variable("")
|
||||
textField.rx_text <-> textValue
|
||||
|
||||
textValue.asObservable()
|
||||
.subscribeNext { [weak self] x in
|
||||
self?.debug("UITextField text \(x)")
|
||||
}
|
||||
|
|
@ -139,7 +160,11 @@ class APIWrappersViewController: ViewController {
|
|||
|
||||
// MARK: UITextView
|
||||
|
||||
textView.rx_text
|
||||
// also test two way binding
|
||||
let textViewValue = Variable("")
|
||||
textView.rx_text <-> textViewValue
|
||||
|
||||
textViewValue.asObservable()
|
||||
.subscribeNext { [weak self] x in
|
||||
self?.debug("UITextView event \(x)")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,14 +23,14 @@ private extension UILabel {
|
|||
|
||||
private extension UIView {
|
||||
var rx_driveAuthorization: AnyObserver<Bool> {
|
||||
return UIBindingObserver(UIElement: self) { label, authorized in
|
||||
return UIBindingObserver(UIElement: self) { view, authorized in
|
||||
if authorized {
|
||||
label.hidden = true
|
||||
label.superview?.sendSubviewToBack(label)
|
||||
view.hidden = true
|
||||
view.superview?.sendSubviewToBack(view)
|
||||
}
|
||||
else {
|
||||
label.hidden = false
|
||||
label.superview?.bringSubviewToFront(label)
|
||||
view.hidden = false
|
||||
view.superview?.bringSubviewToFront(view)
|
||||
}
|
||||
}.asObserver()
|
||||
}
|
||||
|
|
@ -48,7 +48,6 @@ class GeolocationViewController: ViewController {
|
|||
|
||||
let geolocationService = GeolocationService.instance
|
||||
|
||||
|
||||
geolocationService.autorized
|
||||
.drive(noGeolocationView.rx_driveAuthorization)
|
||||
.addDisposableTo(disposeBag)
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ class ImagePickerController: ViewController {
|
|||
.take(1)
|
||||
}
|
||||
.map { info in
|
||||
return info[UIImagePickerControllerOriginalImage] as? UIImage
|
||||
return info[UIImagePickerControllerEditedImage] as? UIImage
|
||||
}
|
||||
.bindTo(imageView.rx_image)
|
||||
.addDisposableTo(disposeBag)
|
||||
|
|
|
|||
|
|
@ -23,9 +23,7 @@ struct User: Equatable, CustomDebugStringConvertible {
|
|||
|
||||
extension User {
|
||||
var debugDescription: String {
|
||||
get {
|
||||
return firstName + " " + lastName
|
||||
}
|
||||
return firstName + " " + lastName
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,9 +20,7 @@ class ReachabilityService {
|
|||
|
||||
private let _reachabilityChangedSubject = PublishSubject<ReachabilityStatus>()
|
||||
private var reachabilityChanged: Observable<ReachabilityStatus> {
|
||||
get {
|
||||
return _reachabilityChangedSubject.asObservable()
|
||||
}
|
||||
return _reachabilityChangedSubject.asObservable()
|
||||
}
|
||||
|
||||
// singleton
|
||||
|
|
|
|||
|
|
@ -35,13 +35,11 @@ public struct BagKey : Hashable {
|
|||
let key: Int
|
||||
|
||||
public var hashValue: Int {
|
||||
get {
|
||||
if let uniqueIdentity = uniqueIdentity {
|
||||
return hash(key) ^ (unsafeAddressOf(uniqueIdentity).hashValue)
|
||||
}
|
||||
else {
|
||||
return hash(key)
|
||||
}
|
||||
if let uniqueIdentity = uniqueIdentity {
|
||||
return hash(key) ^ (unsafeAddressOf(uniqueIdentity).hashValue)
|
||||
}
|
||||
else {
|
||||
return hash(key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -212,9 +210,7 @@ extension Bag {
|
|||
A textual representation of `self`, suitable for debugging.
|
||||
*/
|
||||
public var debugDescription : String {
|
||||
get {
|
||||
return "\(self.count) elements in Bag"
|
||||
}
|
||||
return "\(self.count) elements in Bag"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,28 +49,22 @@ public struct Queue<T>: SequenceType {
|
|||
}
|
||||
|
||||
private var dequeueIndex: Int {
|
||||
get {
|
||||
let index = _pushNextIndex - count
|
||||
return index < 0 ? index + _storage.count : index
|
||||
}
|
||||
let index = _pushNextIndex - count
|
||||
return index < 0 ? index + _storage.count : index
|
||||
}
|
||||
|
||||
/**
|
||||
- returns: Is queue empty.
|
||||
*/
|
||||
public var isEmpty: Bool {
|
||||
get {
|
||||
return count == 0
|
||||
}
|
||||
return count == 0
|
||||
}
|
||||
|
||||
/**
|
||||
- returns: Number of elements inside queue.
|
||||
*/
|
||||
public var count: Int {
|
||||
get {
|
||||
return _count
|
||||
}
|
||||
return _count
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -23,9 +23,7 @@ public final class AnonymousDisposable : DisposeBase, Cancelable {
|
|||
- returns: Was resource disposed.
|
||||
*/
|
||||
public var disposed: Bool {
|
||||
get {
|
||||
return _disposed == 1
|
||||
}
|
||||
return _disposed == 1
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -23,9 +23,7 @@ public final class BinaryDisposable : DisposeBase, Cancelable {
|
|||
- returns: Was resource disposed.
|
||||
*/
|
||||
public var disposed: Bool {
|
||||
get {
|
||||
return _disposed > 0
|
||||
}
|
||||
return _disposed > 0
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -33,9 +33,7 @@ public class BooleanDisposable : Disposable, Cancelable {
|
|||
- returns: Was resource disposed.
|
||||
*/
|
||||
public var disposed: Bool {
|
||||
get {
|
||||
return _disposed
|
||||
}
|
||||
return _disposed
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -20,10 +20,8 @@ public class CompositeDisposable : DisposeBase, Disposable, Cancelable {
|
|||
private var _disposables: Bag<Disposable>? = Bag()
|
||||
|
||||
public var disposed: Bool {
|
||||
get {
|
||||
_lock.lock(); defer { _lock.unlock() }
|
||||
return _disposables == nil
|
||||
}
|
||||
_lock.lock(); defer { _lock.unlock() }
|
||||
return _disposables == nil
|
||||
}
|
||||
|
||||
public override init() {
|
||||
|
|
@ -82,10 +80,8 @@ public class CompositeDisposable : DisposeBase, Disposable, Cancelable {
|
|||
- returns: Gets the number of disposables contained in the `CompositeDisposable`.
|
||||
*/
|
||||
public var count: Int {
|
||||
get {
|
||||
_lock.lock(); defer { _lock.unlock() }
|
||||
return _disposables?.count ?? 0
|
||||
}
|
||||
_lock.lock(); defer { _lock.unlock() }
|
||||
return _disposables?.count ?? 0
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -21,10 +21,8 @@ public class RefCountDisposable : DisposeBase, Cancelable {
|
|||
- returns: Was resource disposed.
|
||||
*/
|
||||
public var disposed: Bool {
|
||||
get {
|
||||
_lock.lock(); defer { _lock.unlock() }
|
||||
return _disposable == nil
|
||||
}
|
||||
_lock.lock(); defer { _lock.unlock() }
|
||||
return _disposable == nil
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -28,9 +28,7 @@ public class ScheduledDisposable : Cancelable {
|
|||
- returns: Was resource disposed.
|
||||
*/
|
||||
public var disposed: Bool {
|
||||
get {
|
||||
return _disposed == 1
|
||||
}
|
||||
return _disposed == 1
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -22,9 +22,7 @@ public class SerialDisposable : DisposeBase, Cancelable {
|
|||
- returns: Was resource disposed.
|
||||
*/
|
||||
public var disposed: Bool {
|
||||
get {
|
||||
return _disposed
|
||||
}
|
||||
return _disposed
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -25,9 +25,7 @@ public class SingleAssignmentDisposable : DisposeBase, Disposable, Cancelable {
|
|||
- returns: A value that indicates whether the object is disposed.
|
||||
*/
|
||||
public var disposed: Bool {
|
||||
get {
|
||||
return _disposed
|
||||
}
|
||||
return _disposed
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -34,11 +34,11 @@ public enum RxError
|
|||
*/
|
||||
case ArgumentOutOfRange
|
||||
/**
|
||||
Sequence doesn't contain any element.
|
||||
Sequence doesn't contain any elements.
|
||||
*/
|
||||
case NoElements
|
||||
/**
|
||||
Sequence contains more then one element.
|
||||
Sequence contains more than one element.
|
||||
*/
|
||||
case MoreThanOneElement
|
||||
/**
|
||||
|
|
@ -62,11 +62,11 @@ public extension RxError {
|
|||
case .ArgumentOutOfRange:
|
||||
return "Argument out of range."
|
||||
case .NoElements:
|
||||
return "Sequence doesn't contain any element."
|
||||
return "Sequence doesn't contain any elements."
|
||||
case .MoreThanOneElement:
|
||||
return "Sequence contains more then one element."
|
||||
return "Sequence contains more than one element."
|
||||
case .Timeout:
|
||||
return "Sequence timeout"
|
||||
return "Sequence timeout."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -37,15 +37,13 @@ extension Event {
|
|||
- returns: Description of event
|
||||
*/
|
||||
public var debugDescription: String {
|
||||
get {
|
||||
switch self {
|
||||
case .Next(let value):
|
||||
return "Next(\(value))"
|
||||
case .Error(let error):
|
||||
return "Error(\(error))"
|
||||
case .Completed:
|
||||
return "Completed"
|
||||
}
|
||||
switch self {
|
||||
case .Next(let value):
|
||||
return "Next(\(value))"
|
||||
case .Error(let error):
|
||||
return "Error(\(error))"
|
||||
case .Completed:
|
||||
return "Completed"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -55,35 +53,29 @@ extension Event {
|
|||
- returns: Is `Completed` or `Error` event
|
||||
*/
|
||||
public var isStopEvent: Bool {
|
||||
get {
|
||||
switch self {
|
||||
case .Next: return false
|
||||
case .Error, .Completed: return true
|
||||
}
|
||||
switch self {
|
||||
case .Next: return false
|
||||
case .Error, .Completed: return true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
- returns: If `Next` event, returns element value.
|
||||
*/
|
||||
public var element: Element? {
|
||||
get {
|
||||
if case .Next(let value) = self {
|
||||
return value
|
||||
}
|
||||
return nil
|
||||
if case .Next(let value) = self {
|
||||
return value
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
- returns: If `Error` event, returns error.
|
||||
*/
|
||||
public var error: ErrorType? {
|
||||
get {
|
||||
if case .Error(let error) = self {
|
||||
return error
|
||||
}
|
||||
return nil
|
||||
if case .Error(let error) = self {
|
||||
return error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
|
@ -31,7 +31,7 @@ extension ObservableType {
|
|||
- parameter onError: Action to invoke upon errored termination of the observable sequence.
|
||||
- parameter onCompleted: Action to invoke upon graceful termination of the observable sequence.
|
||||
- parameter onDisposed: Action to invoke upon any type of termination of sequence (if the sequence has
|
||||
gracefully completed, errored, or if the generation is cancelled by disposing subscription)
|
||||
gracefully completed, errored, or if the generation is cancelled by disposing subscription).
|
||||
- returns: Subscription object used to unsubscribe from the observable sequence.
|
||||
*/
|
||||
@warn_unused_result(message="http://git.io/rxs.ud")
|
||||
|
|
@ -119,7 +119,7 @@ extension ObservableType {
|
|||
|
||||
public extension ObservableType {
|
||||
/**
|
||||
All internal subscribe calls go through this method
|
||||
All internal subscribe calls go through this method.
|
||||
*/
|
||||
@warn_unused_result(message="http://git.io/rxs.ud")
|
||||
func subscribeSafe<O: ObserverType where O.E == E>(observer: O) -> Disposable {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ public protocol ObservableType : ObservableConvertibleType {
|
|||
**Next\* (Error | Completed)?**
|
||||
|
||||
* sequences can produce zero or more elements so zero or more `Next` events can be sent to `observer`
|
||||
* once an `Error` or `Completed` event is sent, the sequence terminates and can't produce any other element
|
||||
* once an `Error` or `Completed` event is sent, the sequence terminates and can't produce any other elements
|
||||
|
||||
It is possible that events are sent from different threads, but no two events can be sent concurrently to
|
||||
`observer`.
|
||||
|
|
|
|||
|
|
@ -36,8 +36,8 @@ class SingleAsyncSink<ElementType, O: ObserverType where O.E == ElementType> : S
|
|||
}
|
||||
|
||||
if _seenValue == false {
|
||||
forwardOn(.Next(value))
|
||||
_seenValue = true
|
||||
forwardOn(.Next(value))
|
||||
} else {
|
||||
forwardOn(.Error(RxError.MoreThanOneElement))
|
||||
dispose()
|
||||
|
|
|
|||
|
|
@ -76,9 +76,7 @@ class WithLatestFromSecond<FirstType, SecondType, ResultType, O: ObserverType wh
|
|||
private let _disposable: Disposable
|
||||
|
||||
var _lock: NSRecursiveLock {
|
||||
get {
|
||||
return _parent._lock
|
||||
}
|
||||
return _parent._lock
|
||||
}
|
||||
|
||||
init(parent: Parent, disposable: Disposable) {
|
||||
|
|
|
|||
|
|
@ -32,8 +32,6 @@ extension RxMutableBox {
|
|||
- returns: Box description.
|
||||
*/
|
||||
var debugDescription: String {
|
||||
get {
|
||||
return "MutatingBox(\(self.value))"
|
||||
}
|
||||
return "MutatingBox(\(self.value))"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,9 +20,7 @@ public class ConcurrentDispatchQueueScheduler: SchedulerType {
|
|||
private let _queue : dispatch_queue_t
|
||||
|
||||
public var now : NSDate {
|
||||
get {
|
||||
return NSDate()
|
||||
}
|
||||
return NSDate()
|
||||
}
|
||||
|
||||
// leeway for scheduling timers
|
||||
|
|
|
|||
|
|
@ -25,9 +25,7 @@ public final class ConcurrentMainScheduler : SchedulerType {
|
|||
- returns: Current time.
|
||||
*/
|
||||
public var now : NSDate {
|
||||
get {
|
||||
return _mainScheduler.now
|
||||
}
|
||||
return _mainScheduler.now
|
||||
}
|
||||
|
||||
private init(mainScheduler: MainScheduler) {
|
||||
|
|
|
|||
|
|
@ -19,9 +19,7 @@ struct ScheduledItem<T>
|
|||
private let _disposable = SingleAssignmentDisposable()
|
||||
|
||||
var disposed: Bool {
|
||||
get {
|
||||
return _disposable.disposed
|
||||
}
|
||||
return _disposable.disposed
|
||||
}
|
||||
|
||||
init(action: Action, state: T) {
|
||||
|
|
|
|||
|
|
@ -34,6 +34,12 @@ public final class MainScheduler : SerialDispatchQueueScheduler {
|
|||
*/
|
||||
public static let instance = MainScheduler()
|
||||
|
||||
/**
|
||||
Singleton instance of `MainScheduler` that always schedules work asynchronously
|
||||
and doesn't perform optimizations for calls scheduled from main thread.
|
||||
*/
|
||||
public static let asyncInstance = SerialDispatchQueueScheduler(serialQueue: dispatch_get_main_queue())
|
||||
|
||||
/**
|
||||
In case this method is called on a background thread it will throw an exception.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -35,9 +35,7 @@ public class SerialDispatchQueueScheduler: SchedulerType {
|
|||
- returns: Current time.
|
||||
*/
|
||||
public var now : NSDate {
|
||||
get {
|
||||
return NSDate()
|
||||
}
|
||||
return NSDate()
|
||||
}
|
||||
|
||||
// leeway for scheduling timers
|
||||
|
|
|
|||
|
|
@ -251,9 +251,7 @@ extension VirtualTimeScheduler {
|
|||
A textual representation of `self`, suitable for debugging.
|
||||
*/
|
||||
public var debugDescription: String {
|
||||
get {
|
||||
return self._schedulerQueue.debugDescription
|
||||
}
|
||||
return self._schedulerQueue.debugDescription
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -266,9 +264,7 @@ class VirtualSchedulerItem<Time>
|
|||
let id: Int
|
||||
|
||||
var disposed: Bool {
|
||||
get {
|
||||
return disposable.disposed
|
||||
}
|
||||
return disposable.disposed
|
||||
}
|
||||
|
||||
var disposable = SingleAssignmentDisposable()
|
||||
|
|
|
|||
|
|
@ -35,9 +35,7 @@ final public class PublishSubject<Element>
|
|||
Indicates whether the subject has been disposed.
|
||||
*/
|
||||
public var disposed: Bool {
|
||||
get {
|
||||
return _disposed
|
||||
}
|
||||
return _disposed
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -37,9 +37,7 @@ extension Recorded {
|
|||
A textual representation of `self`, suitable for debugging.
|
||||
*/
|
||||
public var debugDescription: String {
|
||||
get {
|
||||
return "\(value) @ \(time)"
|
||||
}
|
||||
return "\(value) @ \(time)"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -50,9 +50,7 @@ public struct Subscription
|
|||
The hash value.
|
||||
*/
|
||||
public var hashValue : Int {
|
||||
get {
|
||||
return subscribe.hashValue ^ unsubscribe.hashValue
|
||||
}
|
||||
return subscribe.hashValue ^ unsubscribe.hashValue
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -61,10 +59,8 @@ extension Subscription {
|
|||
A textual representation of `self`, suitable for debugging.
|
||||
*/
|
||||
public var debugDescription : String {
|
||||
get {
|
||||
let infiniteText = "Infinity"
|
||||
return "(\(subscribe) : \(unsubscribe != Int.max ? String(unsubscribe) : infiniteText))"
|
||||
}
|
||||
let infiniteText = "Infinity"
|
||||
return "(\(subscribe) : \(unsubscribe != Int.max ? String(unsubscribe) : infiniteText))"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -468,11 +468,13 @@ _ObservableStandardSequenceOperatorsTest.allTests = [
|
|||
("testSingle_One", { _ObservableStandardSequenceOperatorsTest.setUp(); _ObservableStandardSequenceOperatorsTest.testSingle_One(); _ObservableStandardSequenceOperatorsTest.tearDown(); }),
|
||||
("testSingle_Many", { _ObservableStandardSequenceOperatorsTest.setUp(); _ObservableStandardSequenceOperatorsTest.testSingle_Many(); _ObservableStandardSequenceOperatorsTest.tearDown(); }),
|
||||
//("testSingle_Error", { _ObservableStandardSequenceOperatorsTest.setUp(); _ObservableStandardSequenceOperatorsTest.testSingle_Error(); _ObservableStandardSequenceOperatorsTest.tearDown(); }),
|
||||
("testSingle_DecrementCountsFirst", { _ObservableStandardSequenceOperatorsTest.setUp(); _ObservableStandardSequenceOperatorsTest.testSingle_DecrementCountsFirst(); _ObservableStandardSequenceOperatorsTest.tearDown(); }),
|
||||
("testSinglePredicate_Empty", { _ObservableStandardSequenceOperatorsTest.setUp(); _ObservableStandardSequenceOperatorsTest.testSinglePredicate_Empty(); _ObservableStandardSequenceOperatorsTest.tearDown(); }),
|
||||
("testSinglePredicate_One", { _ObservableStandardSequenceOperatorsTest.setUp(); _ObservableStandardSequenceOperatorsTest.testSinglePredicate_One(); _ObservableStandardSequenceOperatorsTest.tearDown(); }),
|
||||
("testSinglePredicate_Many", { _ObservableStandardSequenceOperatorsTest.setUp(); _ObservableStandardSequenceOperatorsTest.testSinglePredicate_Many(); _ObservableStandardSequenceOperatorsTest.tearDown(); }),
|
||||
//("testSinglePredicate_Error", { _ObservableStandardSequenceOperatorsTest.setUp(); _ObservableStandardSequenceOperatorsTest.testSinglePredicate_Error(); _ObservableStandardSequenceOperatorsTest.tearDown(); }),
|
||||
//("testSinglePredicate_Throws", { _ObservableStandardSequenceOperatorsTest.setUp(); _ObservableStandardSequenceOperatorsTest.testSinglePredicate_Throws(); _ObservableStandardSequenceOperatorsTest.tearDown(); }),
|
||||
("testSinglePredicate_DecrementCountsFirst", { _ObservableStandardSequenceOperatorsTest.setUp(); _ObservableStandardSequenceOperatorsTest.testSinglePredicate_DecrementCountsFirst(); _ObservableStandardSequenceOperatorsTest.tearDown(); }),
|
||||
]
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -287,6 +287,23 @@ extension ControlTests {
|
|||
}
|
||||
}
|
||||
|
||||
// UIProgressView
|
||||
extension ControlTests {
|
||||
func testProgressView_HasWeakReference() {
|
||||
ensureControlObserverHasWeakReference(UIProgressView(), { (progressView: UIProgressView) -> AnyObserver<Float> in progressView.rx_progress }, { Variable<Float>(0.0).asObservable() })
|
||||
}
|
||||
|
||||
func testProgressView_NextElementsSetsValue() {
|
||||
let subject = UIProgressView()
|
||||
let progressSequence = Variable<Float>(0.0)
|
||||
let disposable = progressSequence.asObservable().bindTo(subject.rx_progress)
|
||||
defer { disposable.dispose() }
|
||||
|
||||
progressSequence.value = 1.0
|
||||
XCTAssert(subject.progress == progressSequence.value, "Expected progress to have been set")
|
||||
}
|
||||
}
|
||||
|
||||
// UITableView
|
||||
extension ControlTests {
|
||||
func testTableView_DelegateEventCompletesOnDealloc() {
|
||||
|
|
@ -614,15 +631,6 @@ extension ControlTests {
|
|||
}
|
||||
}
|
||||
|
||||
// UISearchBar
|
||||
extension ControlTests {
|
||||
func testSearchBar_DelegateEventCompletesOnDealloc() {
|
||||
let createView: () -> UISearchBar = { UISearchBar(frame: CGRectMake(0, 0, 1, 1)) }
|
||||
ensurePropertyDeallocated(createView, "a") { (view: UISearchBar) in view.rx_text }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// UIButton
|
||||
extension ControlTests {
|
||||
func testButton_tapDeallocates() {
|
||||
|
|
|
|||
|
|
@ -13,89 +13,4 @@ import XCTest
|
|||
|
||||
class ControlTests : RxTest {
|
||||
|
||||
func ensurePropertyDeallocated<C, T: Equatable where C: NSObject>(createControl: () -> C, _ initialValue: T, _ propertySelector: C -> ControlProperty<T>) {
|
||||
let variable = Variable(initialValue)
|
||||
|
||||
|
||||
var completed = false
|
||||
var deallocated = false
|
||||
var lastReturnedPropertyValue: T!
|
||||
|
||||
autoreleasepool {
|
||||
var control: C! = createControl()
|
||||
|
||||
let property = propertySelector(control)
|
||||
|
||||
let disposable = variable.asObservable().bindTo(property)
|
||||
|
||||
_ = property.subscribe(onNext: { n in
|
||||
lastReturnedPropertyValue = n
|
||||
}, onCompleted: {
|
||||
completed = true
|
||||
disposable.dispose()
|
||||
})
|
||||
|
||||
|
||||
_ = control.rx_deallocated.subscribeNext { _ in
|
||||
deallocated = true
|
||||
}
|
||||
|
||||
control = nil
|
||||
}
|
||||
|
||||
XCTAssertTrue(deallocated)
|
||||
XCTAssertTrue(completed)
|
||||
XCTAssertEqual(initialValue, lastReturnedPropertyValue)
|
||||
}
|
||||
|
||||
func ensureEventDeallocated<C, T where C: NSObject>(createControl: () -> C, _ eventSelector: C -> ControlEvent<T>) {
|
||||
return ensureEventDeallocated({ () -> (C, Disposable) in (createControl(), NopDisposable.instance) }, eventSelector)
|
||||
}
|
||||
|
||||
func ensureEventDeallocated<C, T where C: NSObject>(createControl: () -> (C, Disposable), _ eventSelector: C -> ControlEvent<T>) {
|
||||
var completed = false
|
||||
var deallocated = false
|
||||
let outerDisposable = SingleAssignmentDisposable()
|
||||
|
||||
autoreleasepool {
|
||||
let (control, disposable) = createControl()
|
||||
let eventObservable = eventSelector(control)
|
||||
|
||||
_ = eventObservable.subscribe(onNext: { n in
|
||||
|
||||
}, onCompleted: {
|
||||
completed = true
|
||||
})
|
||||
|
||||
_ = control.rx_deallocated.subscribeNext { _ in
|
||||
deallocated = true
|
||||
}
|
||||
|
||||
outerDisposable.disposable = disposable
|
||||
}
|
||||
|
||||
outerDisposable.dispose()
|
||||
XCTAssertTrue(deallocated)
|
||||
XCTAssertTrue(completed)
|
||||
}
|
||||
|
||||
func ensureControlObserverHasWeakReference<C, T where C: NSObject>(@autoclosure createControl: () -> (C), _ observerSelector: C -> AnyObserver<T>, _ observableSelector: () -> (Observable<T>)) {
|
||||
var deallocated = false
|
||||
|
||||
let disposeBag = DisposeBag()
|
||||
|
||||
autoreleasepool {
|
||||
let control = createControl()
|
||||
let propertyObserver = observerSelector(control)
|
||||
let observable = observableSelector()
|
||||
|
||||
observable.bindTo(propertyObserver).addDisposableTo(disposeBag)
|
||||
|
||||
_ = control.rx_deallocated.subscribeNext { _ in
|
||||
deallocated = true
|
||||
}
|
||||
}
|
||||
|
||||
XCTAssertTrue(deallocated)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -280,9 +280,7 @@ class ThreeDSectionedViewDelegateProxy : DelegateProxy
|
|||
|
||||
extension ThreeDSectionedView {
|
||||
var rx_proxy: DelegateProxy {
|
||||
get {
|
||||
return proxyForObject(ThreeDSectionedViewDelegateProxy.self, self)
|
||||
}
|
||||
return proxyForObject(ThreeDSectionedViewDelegateProxy.self, self)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,111 @@
|
|||
//
|
||||
// RxTest+Controls.swift
|
||||
// Rx
|
||||
//
|
||||
// Created by Krunoslav Zaher on 3/12/16.
|
||||
// Copyright © 2016 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import RxCocoa
|
||||
import RxSwift
|
||||
import XCTest
|
||||
|
||||
extension RxTest {
|
||||
func ensurePropertyDeallocated<C, T: Equatable where C: NSObject>(createControl: () -> C, _ initialValue: T, _ propertySelector: C -> ControlProperty<T>) {
|
||||
let variable = Variable(initialValue)
|
||||
|
||||
|
||||
var completed = false
|
||||
var deallocated = false
|
||||
var lastReturnedPropertyValue: T!
|
||||
|
||||
autoreleasepool {
|
||||
var control: C! = createControl()
|
||||
|
||||
let property = propertySelector(control)
|
||||
|
||||
let disposable = variable.asObservable().bindTo(property)
|
||||
|
||||
_ = property.subscribe(onNext: { n in
|
||||
lastReturnedPropertyValue = n
|
||||
}, onCompleted: {
|
||||
completed = true
|
||||
disposable.dispose()
|
||||
})
|
||||
|
||||
|
||||
_ = control.rx_deallocated.subscribeNext { _ in
|
||||
deallocated = true
|
||||
}
|
||||
|
||||
control = nil
|
||||
}
|
||||
|
||||
|
||||
// this code is here to flush any events that were scheduled to
|
||||
// run on main loop
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
let runLoop = CFRunLoopGetCurrent()
|
||||
CFRunLoopStop(runLoop)
|
||||
}
|
||||
let runLoop = CFRunLoopGetCurrent()
|
||||
CFRunLoopWakeUp(runLoop)
|
||||
CFRunLoopRun()
|
||||
|
||||
XCTAssertTrue(deallocated)
|
||||
XCTAssertTrue(completed)
|
||||
XCTAssertEqual(initialValue, lastReturnedPropertyValue)
|
||||
}
|
||||
|
||||
func ensureEventDeallocated<C, T where C: NSObject>(createControl: () -> C, _ eventSelector: C -> ControlEvent<T>) {
|
||||
return ensureEventDeallocated({ () -> (C, Disposable) in (createControl(), NopDisposable.instance) }, eventSelector)
|
||||
}
|
||||
|
||||
func ensureEventDeallocated<C, T where C: NSObject>(createControl: () -> (C, Disposable), _ eventSelector: C -> ControlEvent<T>) {
|
||||
var completed = false
|
||||
var deallocated = false
|
||||
let outerDisposable = SingleAssignmentDisposable()
|
||||
|
||||
autoreleasepool {
|
||||
let (control, disposable) = createControl()
|
||||
let eventObservable = eventSelector(control)
|
||||
|
||||
_ = eventObservable.subscribe(onNext: { n in
|
||||
|
||||
}, onCompleted: {
|
||||
completed = true
|
||||
})
|
||||
|
||||
_ = control.rx_deallocated.subscribeNext { _ in
|
||||
deallocated = true
|
||||
}
|
||||
|
||||
outerDisposable.disposable = disposable
|
||||
}
|
||||
|
||||
outerDisposable.dispose()
|
||||
XCTAssertTrue(deallocated)
|
||||
XCTAssertTrue(completed)
|
||||
}
|
||||
|
||||
func ensureControlObserverHasWeakReference<C, T where C: NSObject>(@autoclosure createControl: () -> (C), _ observerSelector: C -> AnyObserver<T>, _ observableSelector: () -> (Observable<T>)) {
|
||||
var deallocated = false
|
||||
|
||||
let disposeBag = DisposeBag()
|
||||
|
||||
autoreleasepool {
|
||||
let control = createControl()
|
||||
let propertyObserver = observerSelector(control)
|
||||
let observable = observableSelector()
|
||||
|
||||
observable.bindTo(propertyObserver).addDisposableTo(disposeBag)
|
||||
|
||||
_ = control.rx_deallocated.subscribeNext { _ in
|
||||
deallocated = true
|
||||
}
|
||||
}
|
||||
|
||||
XCTAssertTrue(deallocated)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
//
|
||||
// UISearchBar+RxTests.swift
|
||||
// Rx
|
||||
//
|
||||
// Created by Krunoslav Zaher on 3/12/16.
|
||||
// Copyright © 2016 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
import RxSwift
|
||||
import RxCocoa
|
||||
import UIKit
|
||||
import XCTest
|
||||
|
||||
class UISearchBarTests : RxTest {
|
||||
func testText_completesOnDealloc() {
|
||||
let createView: () -> UISearchBar = { UISearchBar(frame: CGRectMake(0, 0, 1, 1)) }
|
||||
ensurePropertyDeallocated(createView, "a") { (view: UISearchBar) in view.rx_text }
|
||||
}
|
||||
|
||||
func testText_changeEventWorks() {
|
||||
let searchBar = UISearchBar(frame: CGRectMake(0, 0, 1, 1))
|
||||
|
||||
var latestText: String! = nil
|
||||
|
||||
// search bar should dispose this itself
|
||||
_ = searchBar.rx_text.subscribeNext { text in
|
||||
latestText = text
|
||||
}
|
||||
|
||||
XCTAssertEqual(latestText, "")
|
||||
|
||||
searchBar.text = "newValue"
|
||||
searchBar.delegate!.searchBar!(searchBar, textDidChange: "newValue")
|
||||
|
||||
XCTAssertEqual(latestText, "newValue")
|
||||
}
|
||||
|
||||
func textText_binding() {
|
||||
let searchBar = UISearchBar(frame: CGRectMake(0, 0, 1, 1))
|
||||
|
||||
XCTAssertNotEqual(searchBar.text, "value")
|
||||
_ = Observable.just("value").bindTo(searchBar.rx_text)
|
||||
XCTAssertEqual(searchBar.text, "value")
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
//
|
||||
// UITabBarItem+RxTests.swift
|
||||
// Rx
|
||||
//
|
||||
// Created by Mateusz Derks on 04/03/16.
|
||||
// Copyright © 2016 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
import RxSwift
|
||||
import RxCocoa
|
||||
import UIKit
|
||||
import XCTest
|
||||
|
||||
class UITabBarItemTests : RxTest {
|
||||
}
|
||||
|
||||
extension UITabBarItemTests {
|
||||
func testBadgetValue_Text() {
|
||||
let subject = UITabBarItem(tabBarSystemItem: .More, tag: 0)
|
||||
Observable.just("5").subscribe(subject.rx_badgeValue).dispose()
|
||||
|
||||
XCTAssertTrue(subject.badgeValue == "5")
|
||||
}
|
||||
|
||||
func testBadgetValue_Empty() {
|
||||
let subject = UITabBarItem(tabBarSystemItem: .More, tag: 0)
|
||||
Observable.just(nil).subscribe(subject.rx_badgeValue).dispose()
|
||||
|
||||
XCTAssertTrue(subject.badgeValue == nil)
|
||||
}
|
||||
}
|
||||
|
|
@ -19,15 +19,11 @@ class MySubject<Element where Element : Hashable> : SubjectType, ObserverType {
|
|||
var _disposed: Bool = false
|
||||
|
||||
var subscribeCount: Int {
|
||||
get {
|
||||
return _subscribeCount
|
||||
}
|
||||
return _subscribeCount
|
||||
}
|
||||
|
||||
var diposed: Bool {
|
||||
get {
|
||||
return _disposed
|
||||
}
|
||||
return _disposed
|
||||
}
|
||||
|
||||
func disposeOn(value: Element, disposable: Disposable) {
|
||||
|
|
|
|||
|
|
@ -5067,6 +5067,14 @@ extension ObservableStandardSequenceOperatorsTest {
|
|||
Subscription(200, 210)
|
||||
])
|
||||
}
|
||||
|
||||
func testSingle_DecrementCountsFirst() {
|
||||
let k = BehaviorSubject(value: false)
|
||||
|
||||
_ = k.single { _ in true }.subscribeNext { n in
|
||||
k.on(.Next(!n))
|
||||
}
|
||||
}
|
||||
|
||||
func testSinglePredicate_Empty() {
|
||||
let scheduler = TestScheduler(initialClock: 0)
|
||||
|
|
@ -5199,5 +5207,14 @@ extension ObservableStandardSequenceOperatorsTest {
|
|||
Subscription(200, 230)
|
||||
])
|
||||
}
|
||||
|
||||
func testSinglePredicate_DecrementCountsFirst() {
|
||||
let k = BehaviorSubject(value: false)
|
||||
|
||||
_ = k.single { _ in true }.subscribeNext { n in
|
||||
k.on(.Next(!n))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,9 +36,7 @@ class RxTest
|
|||
private var startResourceCount: Int32 = 0
|
||||
|
||||
var accumulateStatistics: Bool {
|
||||
get {
|
||||
return true
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
#if TRACE_RESOURCES
|
||||
|
|
|
|||
Loading…
Reference in New Issue