Moves `subscribeOn` out of `Driver` unit.

This commit is contained in:
Krunoslav Zaher 2015-10-19 19:59:27 +02:00
parent 9a182a8f50
commit fcd63dafb8
7 changed files with 99 additions and 67 deletions

View File

@ -13,10 +13,12 @@ The purpose of units is to use the Swift compiler static type checking to prove
RxCocoa project already contains several units, but the most elaborate one is called `Driver`, so this unit will be used to explain the idea behind units.
`Driver` was named that way because it describes sequences that drive certain parts of the app. Those sequences will usually drive UI bindings, UI event pumps that keep your application responsive but also drive application services, etc.
`Driver` was named that way because it describes sequences that drive certain parts of the app. Those sequences will usually drive UI bindings, UI event pumps that keep your application responsive, but also drive application services, etc.
The purpose of `Driver` unit is to ensure the underlying observable sequence has the following properties.
* can't fail, all failures are being handled properly
* elements are delivered on main thread
* sequence computation resources are shared
TBD...

View File

@ -56,10 +56,10 @@ public struct Driver<Element> : DriverConvertibleType {
init(raw: Observable<E>) {
self._source = raw
}
#if EXPANDABLE_DRIVER
public static func createUnsafe<O: ObservableType>(source: O) -> Driver<O.E> {
return Driver<O.E>(source.asObservable())
return Driver<O.E>(raw: source.asObservable())
}
#endif
@ -82,7 +82,7 @@ public struct Drive {
- returns: An observable sequence with no elements.
*/
public static func empty<E>() -> Driver<E> {
return Driver(raw: RxSwift.empty())
return Driver(raw: RxSwift.empty().subscribeOn(ConcurrentMainScheduler.sharedInstance))
}
/**
@ -91,7 +91,7 @@ public struct Drive {
- returns: An observable sequence whose observers will never get called.
*/
public static func never<E>() -> Driver<E> {
return Driver(raw: RxSwift.never())
return Driver(raw: RxSwift.never().subscribeOn(ConcurrentMainScheduler.sharedInstance))
}
/**
@ -101,7 +101,7 @@ public struct Drive {
- returns: An observable sequence containing the single specified element.
*/
public static func just<E>(element: E) -> Driver<E> {
return Driver(raw: RxSwift.just(element))
return Driver(raw: RxSwift.just(element).subscribeOn(ConcurrentMainScheduler.sharedInstance))
}
#else
@ -112,7 +112,7 @@ public struct Drive {
- returns: An observable sequence with no elements.
*/
public static func empty<E>() -> Driver<E> {
return Driver(raw: _empty())
return Driver(raw: _empty().subscribeOn(ConcurrentMainScheduler.sharedInstance))
}
/**
@ -121,7 +121,7 @@ public struct Drive {
- returns: An observable sequence whose observers will never get called.
*/
public static func never<E>() -> Driver<E> {
return Driver(raw: _never())
return Driver(raw: _never().subscribeOn(ConcurrentMainScheduler.sharedInstance))
}
/**
@ -131,13 +131,13 @@ public struct Drive {
- returns: An observable sequence containing the single specified element.
*/
public static func just<E>(element: E) -> Driver<E> {
return Driver(raw: _just(element))
return Driver(raw: _just(element).subscribeOn(ConcurrentMainScheduler.sharedInstance))
}
#endif
public static func sequenceOf<E>(elements: E ...) -> Driver<E> {
let source = elements.asObservable()
let source = elements.asObservable().subscribeOn(ConcurrentMainScheduler.sharedInstance)
return Driver(raw: source)
}

View File

@ -21,7 +21,6 @@ extension ObservableConvertibleType {
public func asDriver(onErrorJustReturn onErrorJustReturn: E) -> Driver<E> {
let source = self
.asObservable()
.subscribeOn(ConcurrentMainScheduler.sharedInstance)
.observeOn(MainScheduler.sharedInstance)
.catchErrorJustReturn(onErrorJustReturn)
return Driver(source)
@ -36,7 +35,6 @@ extension ObservableConvertibleType {
public func asDriver(onErrorDriveWith onErrorDriveWith: Driver<E>) -> Driver<E> {
let source = self
.asObservable()
.subscribeOn(ConcurrentMainScheduler.sharedInstance)
.observeOn(MainScheduler.sharedInstance)
.catchError { _ in
onErrorDriveWith.asObservable()
@ -53,7 +51,6 @@ extension ObservableConvertibleType {
public func asDriver(onErrorRecover onErrorRecover: (error: ErrorType) -> Driver<E>) -> Driver<E> {
let source = self
.asObservable()
.subscribeOn(ConcurrentMainScheduler.sharedInstance)
.observeOn(MainScheduler.sharedInstance)
.catchError { error in
onErrorRecover(error: error).asObservable()

View File

@ -0,0 +1,18 @@
//
// BackgroundThreadPrimitiveHotObservable.swift
// RxTests
//
// Created by Krunoslav Zaher on 10/19/15.
//
//
import Foundation
import RxSwift
import XCTest
class BackgroundThreadPrimitiveHotObservable<ElementType: Equatable> : PrimitiveHotObservable<ElementType> {
override func subscribe<O : ObserverType where O.E == E>(observer: O) -> Disposable {
XCTAssertTrue(!NSThread.isMainThread())
return super.subscribe(observer)
}
}

View File

@ -20,6 +20,8 @@ class PrimitiveHotObservable<ElementType : Equatable> : ObservableType {
var subscriptions: [Subscription]
var observers: Bag<AnyObserver<E>>
let lock = NSRecursiveLock()
init() {
self.subscriptions = []
@ -31,12 +33,18 @@ class PrimitiveHotObservable<ElementType : Equatable> : ObservableType {
}
func subscribe<O : ObserverType where O.E == E>(observer: O) -> Disposable {
lock.lock()
defer { lock.unlock() }
let key = observers.insert(AnyObserver(observer))
subscriptions.append(SubscribedToHotObservable)
let i = self.subscriptions.count - 1
return AnonymousDisposable {
self.lock.lock()
defer { self.lock.unlock() }
let removed = self.observers.removeKey(key)
assert(removed != nil)

View File

@ -26,7 +26,7 @@ class DriverTest : RxTest {
// * it can't error out - it needs to have catch somewhere
extension DriverTest {
func subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler<R: Equatable>(driver: Driver<R>, subscribedOnBackground: () -> ()) -> [R] {
func subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription<R: Equatable>(driver: Driver<R>, subscribedOnBackground: () -> ()) -> [R] {
var firstElements = [R]()
var secondElements = [R]()
@ -65,7 +65,6 @@ extension DriverTest {
MainScheduler.sharedInstance.schedule(()) { _ in
subscribeFinished.fulfill()
return NopDisposable.instance
}
return NopDisposable.instance
@ -93,10 +92,10 @@ extension DriverTest {
// conversions
extension DriverTest {
func testAsDriver_onErrorJustReturn() {
let hotObservable = MainThreadPrimitiveHotObservable<Int>()
let hotObservable = BackgroundThreadPrimitiveHotObservable<Int>()
let driver = hotObservable.asDriver(onErrorJustReturn: -1)
let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) {
let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) {
XCTAssertTrue(hotObservable.subscriptions == [SubscribedToHotObservable])
hotObservable.on(.Next(1))
@ -110,10 +109,10 @@ extension DriverTest {
}
func testAsDriver_onErrorDriveWith() {
let hotObservable = MainThreadPrimitiveHotObservable<Int>()
let hotObservable = BackgroundThreadPrimitiveHotObservable<Int>()
let driver = hotObservable.asDriver(onErrorDriveWith: Drive.just(-1))
let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) {
let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) {
XCTAssertTrue(hotObservable.subscriptions == [SubscribedToHotObservable])
hotObservable.on(.Next(1))
@ -127,12 +126,12 @@ extension DriverTest {
}
func testAsDriver_onErrorRecover() {
let hotObservable = MainThreadPrimitiveHotObservable<Int>()
let hotObservable = BackgroundThreadPrimitiveHotObservable<Int>()
let driver = hotObservable.asDriver { e in
return Drive.empty()
}
let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) {
let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) {
XCTAssertTrue(hotObservable.subscriptions == [SubscribedToHotObservable])
hotObservable.on(.Next(1))
@ -149,13 +148,13 @@ extension DriverTest {
// map
extension DriverTest {
func testAsDriver_map() {
let hotObservable = MainThreadPrimitiveHotObservable<Int>()
let hotObservable = BackgroundThreadPrimitiveHotObservable<Int>()
let driver = hotObservable.asDriver(onErrorJustReturn: -1).map { (n: Int) -> Int in
XCTAssertTrue(NSThread.isMainThread())
return n + 1
}
let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) {
let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) {
XCTAssertTrue(hotObservable.subscriptions == [SubscribedToHotObservable])
hotObservable.on(.Next(1))
@ -173,13 +172,13 @@ extension DriverTest {
// filter
extension DriverTest {
func testAsDriver_filter() {
let hotObservable = MainThreadPrimitiveHotObservable<Int>()
let hotObservable = BackgroundThreadPrimitiveHotObservable<Int>()
let driver = hotObservable.asDriver(onErrorJustReturn: -1).filter { n in
XCTAssertTrue(NSThread.isMainThread())
return n % 2 == 0
}
let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) {
let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) {
XCTAssertTrue(hotObservable.subscriptions == [SubscribedToHotObservable])
hotObservable.on(.Next(1))
@ -197,13 +196,13 @@ extension DriverTest {
// switch latest
extension DriverTest {
func testAsDriver_switchLatest() {
let hotObservable = MainThreadPrimitiveHotObservable<Driver<Int>>()
let hotObservable = BackgroundThreadPrimitiveHotObservable<Driver<Int>>()
let hotObservable1 = MainThreadPrimitiveHotObservable<Int>()
let hotObservable2 = MainThreadPrimitiveHotObservable<Int>()
let driver = hotObservable.asDriver(onErrorJustReturn: hotObservable1.asDriver(onErrorJustReturn: -1)).switchLatest()
let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) {
let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) {
XCTAssertTrue(hotObservable.subscriptions == [SubscribedToHotObservable])
hotObservable.on(.Next(hotObservable1.asDriver(onErrorJustReturn: -2)))
@ -236,7 +235,7 @@ extension DriverTest {
// doOn
extension DriverTest {
func testAsDriver_doOn() {
let hotObservable = MainThreadPrimitiveHotObservable<Int>()
let hotObservable = BackgroundThreadPrimitiveHotObservable<Int>()
var events = [Event<Int>]()
@ -246,7 +245,7 @@ extension DriverTest {
events.append(e)
}
let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) {
let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) {
XCTAssertTrue(hotObservable.subscriptions == [SubscribedToHotObservable])
hotObservable.on(.Next(1))
@ -265,11 +264,11 @@ extension DriverTest {
// distinct until change
extension DriverTest {
func testAsDriver_distinctUntilChanged1() {
let hotObservable = MainThreadPrimitiveHotObservable<Int>()
let hotObservable = BackgroundThreadPrimitiveHotObservable<Int>()
let driver = hotObservable.asDriver(onErrorJustReturn: -1).distinctUntilChanged()
let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) {
let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) {
XCTAssertTrue(hotObservable.subscriptions == [SubscribedToHotObservable])
hotObservable.on(.Next(1))
@ -284,11 +283,11 @@ extension DriverTest {
}
func testAsDriver_distinctUntilChanged2() {
let hotObservable = MainThreadPrimitiveHotObservable<Int>()
let hotObservable = BackgroundThreadPrimitiveHotObservable<Int>()
let driver = hotObservable.asDriver(onErrorJustReturn: -1).distinctUntilChanged({ $0 })
let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) {
let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) {
XCTAssertTrue(hotObservable.subscriptions == [SubscribedToHotObservable])
hotObservable.on(.Next(1))
@ -303,11 +302,11 @@ extension DriverTest {
}
func testAsDriver_distinctUntilChanged3() {
let hotObservable = MainThreadPrimitiveHotObservable<Int>()
let hotObservable = BackgroundThreadPrimitiveHotObservable<Int>()
let driver = hotObservable.asDriver(onErrorJustReturn: -1).distinctUntilChanged({ $0 == $1 })
let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) {
let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) {
XCTAssertTrue(hotObservable.subscriptions == [SubscribedToHotObservable])
hotObservable.on(.Next(1))
@ -323,11 +322,11 @@ extension DriverTest {
func testAsDriver_distinctUntilChanged4() {
let hotObservable = MainThreadPrimitiveHotObservable<Int>()
let hotObservable = BackgroundThreadPrimitiveHotObservable<Int>()
let driver = hotObservable.asDriver(onErrorJustReturn: -1).distinctUntilChanged({ $0 }) { $0 == $1 }
let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) {
let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) {
XCTAssertTrue(hotObservable.subscriptions == [SubscribedToHotObservable])
hotObservable.on(.Next(1))
@ -346,13 +345,13 @@ extension DriverTest {
// flat map
extension DriverTest {
func testAsDriver_flatMap() {
let hotObservable = MainThreadPrimitiveHotObservable<Int>()
let hotObservable = BackgroundThreadPrimitiveHotObservable<Int>()
let driver = hotObservable.asDriver(onErrorJustReturn: -1).flatMap { (n: Int) -> Driver<Int> in
XCTAssertTrue(NSThread.isMainThread())
return Drive.just(n + 1)
}
let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) {
let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) {
XCTAssertTrue(hotObservable.subscriptions == [SubscribedToHotObservable])
hotObservable.on(.Next(1))
@ -370,13 +369,13 @@ extension DriverTest {
// merge
extension DriverTest {
func testAsDriver_merge() {
let hotObservable = MainThreadPrimitiveHotObservable<Int>()
let hotObservable = BackgroundThreadPrimitiveHotObservable<Int>()
let driver = hotObservable.asDriver(onErrorJustReturn: -1).map { (n: Int) -> Driver<Int> in
XCTAssertTrue(NSThread.isMainThread())
return Drive.just(n + 1)
}.merge()
let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) {
let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) {
XCTAssertTrue(hotObservable.subscriptions == [SubscribedToHotObservable])
hotObservable.on(.Next(1))
@ -390,13 +389,13 @@ extension DriverTest {
}
func testAsDriver_merge2() {
let hotObservable = MainThreadPrimitiveHotObservable<Int>()
let hotObservable = BackgroundThreadPrimitiveHotObservable<Int>()
let driver = hotObservable.asDriver(onErrorJustReturn: -1).map { (n: Int) -> Driver<Int> in
XCTAssertTrue(NSThread.isMainThread())
return Drive.just(n + 1)
}.merge(maxConcurrent: 1)
let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) {
let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) {
XCTAssertTrue(hotObservable.subscriptions == [SubscribedToHotObservable])
hotObservable.on(.Next(1))
@ -413,10 +412,10 @@ extension DriverTest {
// debounce
extension DriverTest {
func testAsDriver_debounce() {
let hotObservable = MainThreadPrimitiveHotObservable<Int>()
let hotObservable = BackgroundThreadPrimitiveHotObservable<Int>()
let driver = hotObservable.asDriver(onErrorJustReturn: -1).debounce(0.0, MainScheduler.sharedInstance)
let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) {
let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) {
XCTAssertTrue(hotObservable.subscriptions == [SubscribedToHotObservable])
hotObservable.on(.Error(testError))
@ -428,10 +427,10 @@ extension DriverTest {
}
func testAsDriver_throttle() {
let hotObservable = MainThreadPrimitiveHotObservable<Int>()
let hotObservable = BackgroundThreadPrimitiveHotObservable<Int>()
let driver = hotObservable.asDriver(onErrorJustReturn: -1).throttle(0.0, MainScheduler.sharedInstance)
let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) {
let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) {
XCTAssertTrue(hotObservable.subscriptions == [SubscribedToHotObservable])
hotObservable.on(.Next(1))
@ -449,13 +448,13 @@ extension DriverTest {
// scan
extension DriverTest {
func testAsDriver_scan() {
let hotObservable = MainThreadPrimitiveHotObservable<Int>()
let hotObservable = BackgroundThreadPrimitiveHotObservable<Int>()
let driver = hotObservable.asDriver(onErrorJustReturn: -1).scan(0) { (a: Int, n: Int) -> Int in
XCTAssertTrue(NSThread.isMainThread())
return a + n
}
let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) {
let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) {
XCTAssertTrue(hotObservable.subscriptions == [SubscribedToHotObservable])
hotObservable.on(.Next(1))
@ -473,12 +472,12 @@ extension DriverTest {
// concat
extension DriverTest {
func testAsDriver_concat() {
let hotObservable1 = MainThreadPrimitiveHotObservable<Int>()
let hotObservable1 = BackgroundThreadPrimitiveHotObservable<Int>()
let hotObservable2 = MainThreadPrimitiveHotObservable<Int>()
let driver = [hotObservable1.asDriver(onErrorJustReturn: -1), hotObservable2.asDriver(onErrorJustReturn: -2)].concat()
let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) {
let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) {
XCTAssertTrue(hotObservable1.subscriptions == [SubscribedToHotObservable])
hotObservable1.on(.Next(1))
@ -502,12 +501,12 @@ extension DriverTest {
// combine latest
extension DriverTest {
func testAsDriver_combineLatest_array() {
let hotObservable1 = MainThreadPrimitiveHotObservable<Int>()
let hotObservable2 = MainThreadPrimitiveHotObservable<Int>()
let hotObservable1 = BackgroundThreadPrimitiveHotObservable<Int>()
let hotObservable2 = BackgroundThreadPrimitiveHotObservable<Int>()
let driver = [hotObservable1.asDriver(onErrorJustReturn: -1), hotObservable2.asDriver(onErrorJustReturn: -2)].combineLatest { a in a.reduce(0, combine: +) }
let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) {
let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) {
XCTAssertTrue(hotObservable1.subscriptions == [SubscribedToHotObservable])
XCTAssertTrue(hotObservable2.subscriptions == [SubscribedToHotObservable])
@ -528,12 +527,12 @@ extension DriverTest {
}
func testAsDriver_combineLatest() {
let hotObservable1 = MainThreadPrimitiveHotObservable<Int>()
let hotObservable2 = MainThreadPrimitiveHotObservable<Int>()
let hotObservable1 = BackgroundThreadPrimitiveHotObservable<Int>()
let hotObservable2 = BackgroundThreadPrimitiveHotObservable<Int>()
let driver = combineLatest(hotObservable1.asDriver(onErrorJustReturn: -1), hotObservable2.asDriver(onErrorJustReturn: -2), resultSelector: +)
let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) {
let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) {
XCTAssertTrue(hotObservable1.subscriptions == [SubscribedToHotObservable])
XCTAssertTrue(hotObservable2.subscriptions == [SubscribedToHotObservable])
@ -557,12 +556,12 @@ extension DriverTest {
// zip
extension DriverTest {
func testAsDriver_zip_array() {
let hotObservable1 = MainThreadPrimitiveHotObservable<Int>()
let hotObservable2 = MainThreadPrimitiveHotObservable<Int>()
let hotObservable1 = BackgroundThreadPrimitiveHotObservable<Int>()
let hotObservable2 = BackgroundThreadPrimitiveHotObservable<Int>()
let driver = [hotObservable1.asDriver(onErrorJustReturn: -1), hotObservable2.asDriver(onErrorJustReturn: -2)].zip { a in a.reduce(0, combine: +) }
let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) {
let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) {
XCTAssertTrue(hotObservable1.subscriptions == [SubscribedToHotObservable])
XCTAssertTrue(hotObservable2.subscriptions == [SubscribedToHotObservable])
@ -583,12 +582,12 @@ extension DriverTest {
}
func testAsDriver_zip() {
let hotObservable1 = MainThreadPrimitiveHotObservable<Int>()
let hotObservable2 = MainThreadPrimitiveHotObservable<Int>()
let hotObservable1 = BackgroundThreadPrimitiveHotObservable<Int>()
let hotObservable2 = BackgroundThreadPrimitiveHotObservable<Int>()
let driver = zip(hotObservable1.asDriver(onErrorJustReturn: -1), hotObservable2.asDriver(onErrorJustReturn: -2), resultSelector: +)
let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) {
let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) {
XCTAssertTrue(hotObservable1.subscriptions == [SubscribedToHotObservable])
XCTAssertTrue(hotObservable2.subscriptions == [SubscribedToHotObservable])

View File

@ -87,6 +87,9 @@
C88BB8AC1B07E64B0064D411 /* AssumptionsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C81108401AF50E2A001C13E4 /* AssumptionsTest.swift */; };
C88BB8AD1B07E64B0064D411 /* TestConnectableObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C81108311AF50E2A001C13E4 /* TestConnectableObservable.swift */; };
C88BB8AE1B07E64B0064D411 /* VariableTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C814CEA21AF5622600E98087 /* VariableTest.swift */; };
C8941BD91BD4F58C00A0E874 /* BackgroundThreadPrimitiveHotObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8941BD81BD4F58C00A0E874 /* BackgroundThreadPrimitiveHotObservable.swift */; };
C8941BDA1BD4F58C00A0E874 /* BackgroundThreadPrimitiveHotObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8941BD81BD4F58C00A0E874 /* BackgroundThreadPrimitiveHotObservable.swift */; };
C8941BDB1BD4F58C00A0E874 /* BackgroundThreadPrimitiveHotObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8941BD81BD4F58C00A0E874 /* BackgroundThreadPrimitiveHotObservable.swift */; };
C897EC3B1B10E000009C2CB0 /* BehaviorSubjectTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C897EC3A1B10E000009C2CB0 /* BehaviorSubjectTest.swift */; };
C897EC3C1B10E000009C2CB0 /* BehaviorSubjectTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C897EC3A1B10E000009C2CB0 /* BehaviorSubjectTest.swift */; };
C897EC4A1B1123DA009C2CB0 /* Observable+MultipleTest+Zip.swift in Sources */ = {isa = PBXBuildFile; fileRef = C897EC491B1123DA009C2CB0 /* Observable+MultipleTest+Zip.swift */; };
@ -112,10 +115,10 @@
C8E3812B1B2083C2008CDC33 /* PrimitiveMockObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8E3812A1B2083C2008CDC33 /* PrimitiveMockObserver.swift */; };
C8E3812C1B2083C2008CDC33 /* PrimitiveMockObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8E3812A1B2083C2008CDC33 /* PrimitiveMockObserver.swift */; };
C8E3813A1B21B77E008CDC33 /* Observable+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8E381221B2063CC008CDC33 /* Observable+Extensions.swift */; };
C8E9D2BD1BD422D80079D0DB /* Control+RxTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8E9D2BC1BD422D80079D0DB /* Control+RxTests.swift */; settings = {ASSET_TAGS = (); }; };
C8E9D2BE1BD422D80079D0DB /* Control+RxTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8E9D2BC1BD422D80079D0DB /* Control+RxTests.swift */; settings = {ASSET_TAGS = (); }; };
C8E9D2BF1BD422D80079D0DB /* Control+RxTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8E9D2BC1BD422D80079D0DB /* Control+RxTests.swift */; settings = {ASSET_TAGS = (); }; };
C8E9D2C41BD452650079D0DB /* Control+RxTests+Cocoa.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8E9D2C01BD4525B0079D0DB /* Control+RxTests+Cocoa.swift */; settings = {ASSET_TAGS = (); }; };
C8E9D2BD1BD422D80079D0DB /* Control+RxTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8E9D2BC1BD422D80079D0DB /* Control+RxTests.swift */; };
C8E9D2BE1BD422D80079D0DB /* Control+RxTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8E9D2BC1BD422D80079D0DB /* Control+RxTests.swift */; };
C8E9D2BF1BD422D80079D0DB /* Control+RxTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8E9D2BC1BD422D80079D0DB /* Control+RxTests.swift */; };
C8E9D2C41BD452650079D0DB /* Control+RxTests+Cocoa.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8E9D2C01BD4525B0079D0DB /* Control+RxTests+Cocoa.swift */; };
C8EA2D371BD02E1900FB22AC /* EquatableArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8EA2D361BD02E1900FB22AC /* EquatableArray.swift */; };
C8EA2D381BD02E1900FB22AC /* EquatableArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8EA2D361BD02E1900FB22AC /* EquatableArray.swift */; };
C8EA2D391BD02E1900FB22AC /* EquatableArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8EA2D361BD02E1900FB22AC /* EquatableArray.swift */; };
@ -221,6 +224,7 @@
C868D10B1BB950D4003D1474 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; };
C868D1121BB950D4003D1474 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
C88BB8B71B07E64B0064D411 /* RxTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RxTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
C8941BD81BD4F58C00A0E874 /* BackgroundThreadPrimitiveHotObservable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BackgroundThreadPrimitiveHotObservable.swift; sourceTree = "<group>"; };
C897EC3A1B10E000009C2CB0 /* BehaviorSubjectTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BehaviorSubjectTest.swift; sourceTree = "<group>"; };
C897EC461B112070009C2CB0 /* Observable+MultipleTest+Zip.tt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "Observable+MultipleTest+Zip.tt"; sourceTree = "<group>"; };
C897EC491B1123DA009C2CB0 /* Observable+MultipleTest+Zip.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Observable+MultipleTest+Zip.swift"; sourceTree = "<group>"; };
@ -380,6 +384,7 @@
C8E3812A1B2083C2008CDC33 /* PrimitiveMockObserver.swift */,
C80DDEDF1BCEE898006A1832 /* MainThreadPrimitiveHotObservable.swift */,
D2AF91961BD2EBB900A008C1 /* MockDisposable.swift */,
C8941BD81BD4F58C00A0E874 /* BackgroundThreadPrimitiveHotObservable.swift */,
);
path = Mocks;
sourceTree = "<group>";
@ -583,6 +588,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C8941BD91BD4F58C00A0E874 /* BackgroundThreadPrimitiveHotObservable.swift in Sources */,
C8B787FA1AF55CDE00206D02 /* Observable+ConcurrencyTest.swift in Sources */,
C81108691AF50E2A001C13E4 /* RxTest.swift in Sources */,
C81108671AF50E2A001C13E4 /* Observable+TimeTest.swift in Sources */,
@ -663,6 +669,7 @@
C88BB8991B07E64B0064D411 /* Observable+BindingTest.swift in Sources */,
C88BB89A1B07E64B0064D411 /* NSNotificationCenterTests.swift in Sources */,
C88BB89B1B07E64B0064D411 /* Observable+MultipleTest+CombineLatest.swift in Sources */,
C8941BDA1BD4F58C00A0E874 /* BackgroundThreadPrimitiveHotObservable.swift in Sources */,
C88BB89C1B07E64B0064D411 /* ConcurrencyTest.swift in Sources */,
C88BB89D1B07E64B0064D411 /* TestObserver.swift in Sources */,
C88BB89E1B07E64B0064D411 /* VirtualTimeSchedulerBase.swift in Sources */,
@ -709,6 +716,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C8941BDB1BD4F58C00A0E874 /* BackgroundThreadPrimitiveHotObservable.swift in Sources */,
D2EBEB5A1BB9B7CC003A27DC /* PrimitiveHotObservable.swift in Sources */,
D2EBEB521BB9B7CC003A27DC /* ColdObservable.swift in Sources */,
D2EBEB551BB9B7CC003A27DC /* MockObserver.swift in Sources */,