initial
This commit is contained in:
9
Pods/RxCocoa/LICENSE.md
generated
Normal file
9
Pods/RxCocoa/LICENSE.md
generated
Normal file
@@ -0,0 +1,9 @@
|
||||
**The MIT License**
|
||||
**Copyright © 2015 Krunoslav Zaher, Shai Mishali**
|
||||
**All rights reserved.**
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
181
Pods/RxCocoa/Platform/DataStructures/Bag.swift
generated
Normal file
181
Pods/RxCocoa/Platform/DataStructures/Bag.swift
generated
Normal file
@@ -0,0 +1,181 @@
|
||||
//
|
||||
// Bag.swift
|
||||
// Platform
|
||||
//
|
||||
// Created by Krunoslav Zaher on 2/28/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
import Swift
|
||||
|
||||
let arrayDictionaryMaxSize = 30
|
||||
|
||||
struct BagKey {
|
||||
/**
|
||||
Unique identifier for object added to `Bag`.
|
||||
|
||||
It's underlying type is UInt64. If we assume there in an idealized CPU that works at 4GHz,
|
||||
it would take ~150 years of continuous running time for it to overflow.
|
||||
*/
|
||||
fileprivate let rawValue: UInt64
|
||||
}
|
||||
|
||||
/**
|
||||
Data structure that represents a bag of elements typed `T`.
|
||||
|
||||
Single element can be stored multiple times.
|
||||
|
||||
Time and space complexity of insertion and deletion is O(n).
|
||||
|
||||
It is suitable for storing small number of elements.
|
||||
*/
|
||||
struct Bag<T> : CustomDebugStringConvertible {
|
||||
/// Type of identifier for inserted elements.
|
||||
typealias KeyType = BagKey
|
||||
|
||||
typealias Entry = (key: BagKey, value: T)
|
||||
|
||||
private var _nextKey: BagKey = BagKey(rawValue: 0)
|
||||
|
||||
// data
|
||||
|
||||
// first fill inline variables
|
||||
var _key0: BagKey?
|
||||
var _value0: T?
|
||||
|
||||
// then fill "array dictionary"
|
||||
var _pairs = ContiguousArray<Entry>()
|
||||
|
||||
// last is sparse dictionary
|
||||
var _dictionary: [BagKey: T]?
|
||||
|
||||
var _onlyFastPath = true
|
||||
|
||||
/// Creates new empty `Bag`.
|
||||
init() {
|
||||
}
|
||||
|
||||
/**
|
||||
Inserts `value` into bag.
|
||||
|
||||
- parameter element: Element to insert.
|
||||
- returns: Key that can be used to remove element from bag.
|
||||
*/
|
||||
mutating func insert(_ element: T) -> BagKey {
|
||||
let key = _nextKey
|
||||
|
||||
_nextKey = BagKey(rawValue: _nextKey.rawValue &+ 1)
|
||||
|
||||
if _key0 == nil {
|
||||
_key0 = key
|
||||
_value0 = element
|
||||
return key
|
||||
}
|
||||
|
||||
_onlyFastPath = false
|
||||
|
||||
if _dictionary != nil {
|
||||
_dictionary![key] = element
|
||||
return key
|
||||
}
|
||||
|
||||
if _pairs.count < arrayDictionaryMaxSize {
|
||||
_pairs.append((key: key, value: element))
|
||||
return key
|
||||
}
|
||||
|
||||
_dictionary = [key: element]
|
||||
|
||||
return key
|
||||
}
|
||||
|
||||
/// - returns: Number of elements in bag.
|
||||
var count: Int {
|
||||
let dictionaryCount: Int = _dictionary?.count ?? 0
|
||||
return (_value0 != nil ? 1 : 0) + _pairs.count + dictionaryCount
|
||||
}
|
||||
|
||||
/// Removes all elements from bag and clears capacity.
|
||||
mutating func removeAll() {
|
||||
_key0 = nil
|
||||
_value0 = nil
|
||||
|
||||
_pairs.removeAll(keepingCapacity: false)
|
||||
_dictionary?.removeAll(keepingCapacity: false)
|
||||
}
|
||||
|
||||
/**
|
||||
Removes element with a specific `key` from bag.
|
||||
|
||||
- parameter key: Key that identifies element to remove from bag.
|
||||
- returns: Element that bag contained, or nil in case element was already removed.
|
||||
*/
|
||||
mutating func removeKey(_ key: BagKey) -> T? {
|
||||
if _key0 == key {
|
||||
_key0 = nil
|
||||
let value = _value0!
|
||||
_value0 = nil
|
||||
return value
|
||||
}
|
||||
|
||||
if let existingObject = _dictionary?.removeValue(forKey: key) {
|
||||
return existingObject
|
||||
}
|
||||
|
||||
for i in 0 ..< _pairs.count where _pairs[i].key == key {
|
||||
let value = _pairs[i].value
|
||||
_pairs.remove(at: i)
|
||||
return value
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
extension Bag {
|
||||
/// A textual representation of `self`, suitable for debugging.
|
||||
var debugDescription : String {
|
||||
"\(self.count) elements in Bag"
|
||||
}
|
||||
}
|
||||
|
||||
extension Bag {
|
||||
/// Enumerates elements inside the bag.
|
||||
///
|
||||
/// - parameter action: Enumeration closure.
|
||||
func forEach(_ action: (T) -> Void) {
|
||||
if _onlyFastPath {
|
||||
if let value0 = _value0 {
|
||||
action(value0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
let value0 = _value0
|
||||
let dictionary = _dictionary
|
||||
|
||||
if let value0 = value0 {
|
||||
action(value0)
|
||||
}
|
||||
|
||||
for i in 0 ..< _pairs.count {
|
||||
action(_pairs[i].value)
|
||||
}
|
||||
|
||||
if dictionary?.count ?? 0 > 0 {
|
||||
for element in dictionary!.values {
|
||||
action(element)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension BagKey: Hashable {
|
||||
func hash(into hasher: inout Hasher) {
|
||||
hasher.combine(rawValue)
|
||||
}
|
||||
}
|
||||
|
||||
func ==(lhs: BagKey, rhs: BagKey) -> Bool {
|
||||
lhs.rawValue == rhs.rawValue
|
||||
}
|
||||
23
Pods/RxCocoa/Platform/DataStructures/InfiniteSequence.swift
generated
Normal file
23
Pods/RxCocoa/Platform/DataStructures/InfiniteSequence.swift
generated
Normal file
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// InfiniteSequence.swift
|
||||
// Platform
|
||||
//
|
||||
// Created by Krunoslav Zaher on 6/13/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
/// Sequence that repeats `repeatedValue` infinite number of times.
|
||||
struct InfiniteSequence<Element> : Sequence {
|
||||
typealias Iterator = AnyIterator<Element>
|
||||
|
||||
private let repeatedValue: Element
|
||||
|
||||
init(repeatedValue: Element) {
|
||||
self.repeatedValue = repeatedValue
|
||||
}
|
||||
|
||||
func makeIterator() -> Iterator {
|
||||
let repeatedValue = self.repeatedValue
|
||||
return AnyIterator { repeatedValue }
|
||||
}
|
||||
}
|
||||
111
Pods/RxCocoa/Platform/DataStructures/PriorityQueue.swift
generated
Normal file
111
Pods/RxCocoa/Platform/DataStructures/PriorityQueue.swift
generated
Normal file
@@ -0,0 +1,111 @@
|
||||
//
|
||||
// PriorityQueue.swift
|
||||
// Platform
|
||||
//
|
||||
// Created by Krunoslav Zaher on 12/27/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
struct PriorityQueue<Element> {
|
||||
private let hasHigherPriority: (Element, Element) -> Bool
|
||||
private let isEqual: (Element, Element) -> Bool
|
||||
|
||||
private var elements = [Element]()
|
||||
|
||||
init(hasHigherPriority: @escaping (Element, Element) -> Bool, isEqual: @escaping (Element, Element) -> Bool) {
|
||||
self.hasHigherPriority = hasHigherPriority
|
||||
self.isEqual = isEqual
|
||||
}
|
||||
|
||||
mutating func enqueue(_ element: Element) {
|
||||
elements.append(element)
|
||||
bubbleToHigherPriority(elements.count - 1)
|
||||
}
|
||||
|
||||
func peek() -> Element? {
|
||||
elements.first
|
||||
}
|
||||
|
||||
var isEmpty: Bool {
|
||||
elements.count == 0
|
||||
}
|
||||
|
||||
mutating func dequeue() -> Element? {
|
||||
guard let front = peek() else {
|
||||
return nil
|
||||
}
|
||||
|
||||
removeAt(0)
|
||||
|
||||
return front
|
||||
}
|
||||
|
||||
mutating func remove(_ element: Element) {
|
||||
for i in 0 ..< elements.count {
|
||||
if self.isEqual(elements[i], element) {
|
||||
removeAt(i)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private mutating func removeAt(_ index: Int) {
|
||||
let removingLast = index == elements.count - 1
|
||||
if !removingLast {
|
||||
elements.swapAt(index, elements.count - 1)
|
||||
}
|
||||
|
||||
_ = elements.popLast()
|
||||
|
||||
if !removingLast {
|
||||
bubbleToHigherPriority(index)
|
||||
bubbleToLowerPriority(index)
|
||||
}
|
||||
}
|
||||
|
||||
private mutating func bubbleToHigherPriority(_ initialUnbalancedIndex: Int) {
|
||||
precondition(initialUnbalancedIndex >= 0)
|
||||
precondition(initialUnbalancedIndex < elements.count)
|
||||
|
||||
var unbalancedIndex = initialUnbalancedIndex
|
||||
|
||||
while unbalancedIndex > 0 {
|
||||
let parentIndex = (unbalancedIndex - 1) / 2
|
||||
guard self.hasHigherPriority(elements[unbalancedIndex], elements[parentIndex]) else { break }
|
||||
elements.swapAt(unbalancedIndex, parentIndex)
|
||||
unbalancedIndex = parentIndex
|
||||
}
|
||||
}
|
||||
|
||||
private mutating func bubbleToLowerPriority(_ initialUnbalancedIndex: Int) {
|
||||
precondition(initialUnbalancedIndex >= 0)
|
||||
precondition(initialUnbalancedIndex < elements.count)
|
||||
|
||||
var unbalancedIndex = initialUnbalancedIndex
|
||||
while true {
|
||||
let leftChildIndex = unbalancedIndex * 2 + 1
|
||||
let rightChildIndex = unbalancedIndex * 2 + 2
|
||||
|
||||
var highestPriorityIndex = unbalancedIndex
|
||||
|
||||
if leftChildIndex < elements.count && self.hasHigherPriority(elements[leftChildIndex], elements[highestPriorityIndex]) {
|
||||
highestPriorityIndex = leftChildIndex
|
||||
}
|
||||
|
||||
if rightChildIndex < elements.count && self.hasHigherPriority(elements[rightChildIndex], elements[highestPriorityIndex]) {
|
||||
highestPriorityIndex = rightChildIndex
|
||||
}
|
||||
|
||||
guard highestPriorityIndex != unbalancedIndex else { break }
|
||||
elements.swapAt(highestPriorityIndex, unbalancedIndex)
|
||||
|
||||
unbalancedIndex = highestPriorityIndex
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension PriorityQueue : CustomDebugStringConvertible {
|
||||
var debugDescription: String {
|
||||
elements.debugDescription
|
||||
}
|
||||
}
|
||||
148
Pods/RxCocoa/Platform/DataStructures/Queue.swift
generated
Normal file
148
Pods/RxCocoa/Platform/DataStructures/Queue.swift
generated
Normal file
@@ -0,0 +1,148 @@
|
||||
//
|
||||
// Queue.swift
|
||||
// Platform
|
||||
//
|
||||
// Created by Krunoslav Zaher on 3/21/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
/**
|
||||
Data structure that represents queue.
|
||||
|
||||
Complexity of `enqueue`, `dequeue` is O(1) when number of operations is
|
||||
averaged over N operations.
|
||||
|
||||
Complexity of `peek` is O(1).
|
||||
*/
|
||||
struct Queue<T>: Sequence {
|
||||
/// Type of generator.
|
||||
typealias Generator = AnyIterator<T>
|
||||
|
||||
private let resizeFactor = 2
|
||||
|
||||
private var storage: ContiguousArray<T?>
|
||||
private var innerCount = 0
|
||||
private var pushNextIndex = 0
|
||||
private let initialCapacity: Int
|
||||
|
||||
/**
|
||||
Creates new queue.
|
||||
|
||||
- parameter capacity: Capacity of newly created queue.
|
||||
*/
|
||||
init(capacity: Int) {
|
||||
initialCapacity = capacity
|
||||
|
||||
storage = ContiguousArray<T?>(repeating: nil, count: capacity)
|
||||
}
|
||||
|
||||
private var dequeueIndex: Int {
|
||||
let index = pushNextIndex - count
|
||||
return index < 0 ? index + storage.count : index
|
||||
}
|
||||
|
||||
/// - returns: Is queue empty.
|
||||
var isEmpty: Bool { count == 0 }
|
||||
|
||||
/// - returns: Number of elements inside queue.
|
||||
var count: Int { innerCount }
|
||||
|
||||
/// - returns: Element in front of a list of elements to `dequeue`.
|
||||
func peek() -> T {
|
||||
precondition(count > 0)
|
||||
|
||||
return storage[dequeueIndex]!
|
||||
}
|
||||
|
||||
mutating private func resizeTo(_ size: Int) {
|
||||
var newStorage = ContiguousArray<T?>(repeating: nil, count: size)
|
||||
|
||||
let count = self.count
|
||||
|
||||
let dequeueIndex = self.dequeueIndex
|
||||
let spaceToEndOfQueue = storage.count - dequeueIndex
|
||||
|
||||
// first batch is from dequeue index to end of array
|
||||
let countElementsInFirstBatch = Swift.min(count, spaceToEndOfQueue)
|
||||
// second batch is wrapped from start of array to end of queue
|
||||
let numberOfElementsInSecondBatch = count - countElementsInFirstBatch
|
||||
|
||||
newStorage[0 ..< countElementsInFirstBatch] = storage[dequeueIndex ..< (dequeueIndex + countElementsInFirstBatch)]
|
||||
newStorage[countElementsInFirstBatch ..< (countElementsInFirstBatch + numberOfElementsInSecondBatch)] = storage[0 ..< numberOfElementsInSecondBatch]
|
||||
|
||||
self.innerCount = count
|
||||
pushNextIndex = count
|
||||
storage = newStorage
|
||||
}
|
||||
|
||||
/// Enqueues `element`.
|
||||
///
|
||||
/// - parameter element: Element to enqueue.
|
||||
mutating func enqueue(_ element: T) {
|
||||
if count == storage.count {
|
||||
resizeTo(Swift.max(storage.count, 1) * resizeFactor)
|
||||
}
|
||||
|
||||
storage[pushNextIndex] = element
|
||||
pushNextIndex += 1
|
||||
innerCount += 1
|
||||
|
||||
if pushNextIndex >= storage.count {
|
||||
pushNextIndex -= storage.count
|
||||
}
|
||||
}
|
||||
|
||||
private mutating func dequeueElementOnly() -> T {
|
||||
precondition(count > 0)
|
||||
|
||||
let index = dequeueIndex
|
||||
|
||||
defer {
|
||||
storage[index] = nil
|
||||
innerCount -= 1
|
||||
}
|
||||
|
||||
return storage[index]!
|
||||
}
|
||||
|
||||
/// Dequeues element or throws an exception in case queue is empty.
|
||||
///
|
||||
/// - returns: Dequeued element.
|
||||
mutating func dequeue() -> T? {
|
||||
if self.count == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
defer {
|
||||
let downsizeLimit = storage.count / (resizeFactor * resizeFactor)
|
||||
if count < downsizeLimit && downsizeLimit >= initialCapacity {
|
||||
resizeTo(storage.count / resizeFactor)
|
||||
}
|
||||
}
|
||||
|
||||
return dequeueElementOnly()
|
||||
}
|
||||
|
||||
/// - returns: Generator of contained elements.
|
||||
func makeIterator() -> AnyIterator<T> {
|
||||
var i = dequeueIndex
|
||||
var innerCount = count
|
||||
|
||||
return AnyIterator {
|
||||
if innerCount == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
defer {
|
||||
innerCount -= 1
|
||||
i += 1
|
||||
}
|
||||
|
||||
if i >= self.storage.count {
|
||||
i -= self.storage.count
|
||||
}
|
||||
|
||||
return self.storage[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
21
Pods/RxCocoa/Platform/DispatchQueue+Extensions.swift
generated
Normal file
21
Pods/RxCocoa/Platform/DispatchQueue+Extensions.swift
generated
Normal file
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// DispatchQueue+Extensions.swift
|
||||
// Platform
|
||||
//
|
||||
// Created by Krunoslav Zaher on 10/22/16.
|
||||
// Copyright © 2016 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
import Dispatch
|
||||
|
||||
extension DispatchQueue {
|
||||
private static var token: DispatchSpecificKey<()> = {
|
||||
let key = DispatchSpecificKey<()>()
|
||||
DispatchQueue.main.setSpecific(key: key, value: ())
|
||||
return key
|
||||
}()
|
||||
|
||||
static var isMain: Bool {
|
||||
DispatchQueue.getSpecific(key: token) != nil
|
||||
}
|
||||
}
|
||||
35
Pods/RxCocoa/Platform/Platform.Darwin.swift
generated
Normal file
35
Pods/RxCocoa/Platform/Platform.Darwin.swift
generated
Normal file
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// Platform.Darwin.swift
|
||||
// Platform
|
||||
//
|
||||
// Created by Krunoslav Zaher on 12/29/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
|
||||
|
||||
import Darwin
|
||||
import Foundation
|
||||
|
||||
extension Thread {
|
||||
static func setThreadLocalStorageValue<T: AnyObject>(_ value: T?, forKey key: NSCopying) {
|
||||
let currentThread = Thread.current
|
||||
let threadDictionary = currentThread.threadDictionary
|
||||
|
||||
if let newValue = value {
|
||||
threadDictionary[key] = newValue
|
||||
}
|
||||
else {
|
||||
threadDictionary[key] = nil
|
||||
}
|
||||
}
|
||||
|
||||
static func getThreadLocalStorageValueForKey<T>(_ key: NSCopying) -> T? {
|
||||
let currentThread = Thread.current
|
||||
let threadDictionary = currentThread.threadDictionary
|
||||
|
||||
return threadDictionary[key] as? T
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
32
Pods/RxCocoa/Platform/Platform.Linux.swift
generated
Normal file
32
Pods/RxCocoa/Platform/Platform.Linux.swift
generated
Normal file
@@ -0,0 +1,32 @@
|
||||
//
|
||||
// Platform.Linux.swift
|
||||
// Platform
|
||||
//
|
||||
// Created by Krunoslav Zaher on 12/29/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(Linux)
|
||||
|
||||
import Foundation
|
||||
|
||||
extension Thread {
|
||||
|
||||
static func setThreadLocalStorageValue<T: AnyObject>(_ value: T?, forKey key: String) {
|
||||
if let newValue = value {
|
||||
Thread.current.threadDictionary[key] = newValue
|
||||
}
|
||||
else {
|
||||
Thread.current.threadDictionary[key] = nil
|
||||
}
|
||||
}
|
||||
|
||||
static func getThreadLocalStorageValueForKey<T: AnyObject>(_ key: String) -> T? {
|
||||
let currentThread = Thread.current
|
||||
let threadDictionary = currentThread.threadDictionary
|
||||
|
||||
return threadDictionary[key] as? T
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
34
Pods/RxCocoa/Platform/RecursiveLock.swift
generated
Normal file
34
Pods/RxCocoa/Platform/RecursiveLock.swift
generated
Normal file
@@ -0,0 +1,34 @@
|
||||
//
|
||||
// RecursiveLock.swift
|
||||
// Platform
|
||||
//
|
||||
// Created by Krunoslav Zaher on 12/18/16.
|
||||
// Copyright © 2016 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
#if TRACE_RESOURCES
|
||||
class RecursiveLock: NSRecursiveLock {
|
||||
override init() {
|
||||
_ = Resources.incrementTotal()
|
||||
super.init()
|
||||
}
|
||||
|
||||
override func lock() {
|
||||
super.lock()
|
||||
_ = Resources.incrementTotal()
|
||||
}
|
||||
|
||||
override func unlock() {
|
||||
super.unlock()
|
||||
_ = Resources.decrementTotal()
|
||||
}
|
||||
|
||||
deinit {
|
||||
_ = Resources.decrementTotal()
|
||||
}
|
||||
}
|
||||
#else
|
||||
typealias RecursiveLock = NSRecursiveLock
|
||||
#endif
|
||||
254
Pods/RxCocoa/README.md
generated
Normal file
254
Pods/RxCocoa/README.md
generated
Normal file
@@ -0,0 +1,254 @@
|
||||
<p align="center">
|
||||
<img src="assets/RxSwift_Logo.png" width="35%" alt="RxSwift Logo" />
|
||||
<br />
|
||||
<a href="https://actions-badge.atrox.dev/ReactiveX/RxSwift/goto" target="_blank"><img src="https://github.com/ReactiveX/RxSwift/workflows/RxSwift/badge.svg?branch=main" alt="Build Status" /></a>
|
||||
<img src="https://img.shields.io/badge/platforms-iOS%20%7C%20macOS%20%7C%20tvOS%20%7C%20watchOS%20%7C%20Linux-333333.svg" alt="Supported Platforms: iOS, macOS, tvOS, watchOS & Linux" />
|
||||
<br />
|
||||
<a href="https://cocoapods.org/pods/RxSwift" alt="RxSwift on CocoaPods" title="RxSwift on CocoaPods"><img src="https://img.shields.io/cocoapods/v/RxSwift.svg" /></a>
|
||||
<a href="https://github.com/Carthage/Carthage" alt="RxSwift on Carthage" title="RxSwift on Carthage"><img src="https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat" /></a>
|
||||
<a href="https://github.com/apple/swift-package-manager" alt="RxSwift on Swift Package Manager" title="RxSwift on Swift Package Manager"><img src="https://img.shields.io/badge/Swift%20Package%20Manager-compatible-brightgreen.svg" /></a>
|
||||
</p>
|
||||
|
||||
Rx is a [generic abstraction of computation](https://youtu.be/looJcaeboBY) expressed through `Observable<Element>` interface, which lets you broadcast and subscribe to values and other events from an `Observable` stream.
|
||||
|
||||
RxSwift is the Swift-specific implementation of the [Reactive Extensions](http://reactivex.io) standard.
|
||||
|
||||
<p align="center"><img src="assets/example.png" width="55%" alt="RxSwift Observable Example of a price constantly changing and updating the app's UI" /></p>
|
||||
|
||||
While this version aims to stay true to the original spirit and naming conventions of Rx, this projects also aims to provide a true Swift-first API for Rx APIs.
|
||||
|
||||
Cross platform documentation can be found on [ReactiveX.io](http://reactivex.io/).
|
||||
|
||||
Like other Rx implementation, RxSwift's intention is to enable easy composition of asynchronous operations and streams of data in the form of `Observable` objects and a suite of methods to transform and compose these pieces of asynchronous work.
|
||||
|
||||
KVO observation, async operations, UI Events and other streams of data are all unified under [abstraction of sequence](Documentation/GettingStarted.md#observables-aka-sequences). This is the reason why Rx is so simple, elegant and powerful.
|
||||
|
||||
## I came here because I want to ...
|
||||
|
||||
###### ... understand
|
||||
|
||||
* [why use rx?](Documentation/Why.md)
|
||||
* [the basics, getting started with RxSwift](Documentation/GettingStarted.md)
|
||||
* [traits](Documentation/Traits.md) - what are `Single`, `Completable`, `Maybe`, `Driver`, and `ControlProperty` ... 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)
|
||||
|
||||
###### ... install
|
||||
|
||||
* Integrate RxSwift/RxCocoa with my app. [Installation Guide](#installation)
|
||||
|
||||
###### ... hack around
|
||||
|
||||
* with the example app. [Running Example App](Documentation/ExampleApp.md)
|
||||
* with operators in playgrounds. [Playgrounds](Documentation/Playgrounds.md)
|
||||
|
||||
###### ... interact
|
||||
|
||||
* All of this is great, but it would be nice to talk with other people using RxSwift and exchange experiences. <br />[Join Slack Channel](http://slack.rxswift.org)
|
||||
* Report a problem using the library. [Open an Issue With Bug Template](.github/ISSUE_TEMPLATE.md)
|
||||
* Request a new feature. [Open an Issue With Feature Request Template](Documentation/NewFeatureRequestTemplate.md)
|
||||
* Help out [Check out contribution guide](CONTRIBUTING.md)
|
||||
|
||||
###### ... compare
|
||||
|
||||
* [with Combine and ReactiveSwift](Documentation/ComparisonWithOtherLibraries.md).
|
||||
|
||||
###### ... understand the structure
|
||||
|
||||
RxSwift is as compositional as the asynchronous work it drives. The core unit is RxSwift itself, while other dependencies can be added for UI Work, testing, and more.
|
||||
|
||||
It comprises five separate components depending on each other in the following way:
|
||||
|
||||
```none
|
||||
┌──────────────┐ ┌──────────────┐
|
||||
│ RxCocoa ├────▶ RxRelay │
|
||||
└───────┬──────┘ └──────┬───────┘
|
||||
│ │
|
||||
┌───────▼──────────────────▼───────┐
|
||||
│ RxSwift │
|
||||
└───────▲──────────────────▲───────┘
|
||||
│ │
|
||||
┌───────┴──────┐ ┌──────┴───────┐
|
||||
│ RxTest │ │ RxBlocking │
|
||||
└──────────────┘ └──────────────┘
|
||||
```
|
||||
|
||||
* **RxSwift**: The core of RxSwift, providing the Rx standard as (mostly) defined by [ReactiveX](https://reactivex.io). It has no other dependencies.
|
||||
* **RxCocoa**: Provides Cocoa-specific capabilities for general iOS/macOS/watchOS & tvOS app development, such as Shared Sequences, Traits, and much more. It depends on both `RxSwift` and `RxRelay`.
|
||||
* **RxRelay**: Provides `PublishRelay`, `BehaviorRelay` and `ReplayRelay`, three [simple wrappers around Subjects](https://github.com/ReactiveX/RxSwift/blob/main/Documentation/Subjects.md#relays). It depends on `RxSwift`.
|
||||
* **RxTest** and **RxBlocking**: Provides testing capabilities for Rx-based systems. It depends on `RxSwift`.
|
||||
|
||||
## Usage
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th width="30%">Here's an example</th>
|
||||
<th width="30%">In Action</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Define search for GitHub repositories ...</td>
|
||||
<th rowspan="9"><img src="https://raw.githubusercontent.com/kzaher/rxswiftcontent/master/GithubSearch.gif"></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><div class="highlight highlight-source-swift"><pre>
|
||||
let searchResults = searchBar.rx.text.orEmpty
|
||||
.throttle(.milliseconds(300), scheduler: MainScheduler.instance)
|
||||
.distinctUntilChanged()
|
||||
.flatMapLatest { query -> Observable<[Repository]> in
|
||||
if query.isEmpty {
|
||||
return .just([])
|
||||
}
|
||||
return searchGitHub(query)
|
||||
.catchAndReturn([])
|
||||
}
|
||||
.observe(on: MainScheduler.instance)</pre></div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>... then bind the results to your tableview</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="30%"><div class="highlight highlight-source-swift"><pre>
|
||||
searchResults
|
||||
.bind(to: tableView.rx.items(cellIdentifier: "Cell")) {
|
||||
(index, repository: Repository, cell) in
|
||||
cell.textLabel?.text = repository.name
|
||||
cell.detailTextLabel?.text = repository.url
|
||||
}
|
||||
.disposed(by: disposeBag)</pre></div></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
## Requirements
|
||||
|
||||
* Xcode 12.x
|
||||
* Swift 5.x
|
||||
|
||||
For Xcode 11 and below, [use RxSwift 5.x](https://github.com/ReactiveX/RxSwift/releases/tag/5.1.1).
|
||||
|
||||
## Installation
|
||||
|
||||
RxSwift doesn't contain any external dependencies.
|
||||
|
||||
These are currently the supported installation options:
|
||||
|
||||
### Manual
|
||||
|
||||
Open Rx.xcworkspace, choose `RxExample` and hit run. This method will build everything and run the sample app
|
||||
|
||||
### [CocoaPods](https://guides.cocoapods.org/using/using-cocoapods.html)
|
||||
|
||||
```ruby
|
||||
# Podfile
|
||||
use_frameworks!
|
||||
|
||||
target 'YOUR_TARGET_NAME' do
|
||||
pod 'RxSwift', '6.5.0'
|
||||
pod 'RxCocoa', '6.5.0'
|
||||
end
|
||||
|
||||
# RxTest and RxBlocking make the most sense in the context of unit/integration tests
|
||||
target 'YOUR_TESTING_TARGET' do
|
||||
pod 'RxBlocking', '6.5.0'
|
||||
pod 'RxTest', '6.5.0'
|
||||
end
|
||||
```
|
||||
|
||||
Replace `YOUR_TARGET_NAME` and then, in the `Podfile` directory, type:
|
||||
|
||||
```bash
|
||||
$ pod install
|
||||
```
|
||||
|
||||
### XCFrameworks
|
||||
|
||||
Each release starting with RxSwift 6 includes `*.xcframework` framework binaries.
|
||||
|
||||
Simply drag the needed framework binaries to your **Frameworks, Libraries, and Embedded Content** section under your target's **General** tab.
|
||||
|
||||
> **Note**: If you're using `RxCocoa`, be sure to also drag **RxCocoaRuntime.xcframework** before importing `RxCocoa`.
|
||||
|
||||
<img src="https://raw.githubusercontent.com/ReactiveX/RxSwift/main/assets/xcframeworks.png" alt="XCFrameworks instructions" width="65%">
|
||||
|
||||
### [Carthage](https://github.com/Carthage/Carthage)
|
||||
|
||||
Add this to `Cartfile`
|
||||
|
||||
```
|
||||
github "ReactiveX/RxSwift" "6.5.0"
|
||||
```
|
||||
|
||||
```bash
|
||||
$ carthage update
|
||||
```
|
||||
|
||||
#### Carthage as a Static Library
|
||||
|
||||
Carthage defaults to building RxSwift as a Dynamic Library.
|
||||
|
||||
If you wish to build RxSwift as a Static Library using Carthage you may use the script below to manually modify the framework type before building with Carthage:
|
||||
|
||||
```bash
|
||||
carthage update RxSwift --platform iOS --no-build
|
||||
sed -i -e 's/MACH_O_TYPE = mh_dylib/MACH_O_TYPE = staticlib/g' Carthage/Checkouts/RxSwift/Rx.xcodeproj/project.pbxproj
|
||||
carthage build RxSwift --platform iOS
|
||||
```
|
||||
|
||||
### [Swift Package Manager](https://github.com/apple/swift-package-manager)
|
||||
|
||||
> **Note**: There is a critical cross-dependency bug affecting many projects including RxSwift in Swift Package Manager. We've [filed a bug (SR-12303)](https://bugs.swift.org/browse/SR-12303) in early 2020 but have no answer yet. Your mileage may vary. A partial workaround can be found [here](https://github.com/ReactiveX/RxSwift/issues/2127#issuecomment-717830502).
|
||||
|
||||
Create a `Package.swift` file.
|
||||
|
||||
```swift
|
||||
// swift-tools-version:5.0
|
||||
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "RxTestProject",
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/ReactiveX/RxSwift.git", .exact("6.5.0"))
|
||||
],
|
||||
targets: [
|
||||
.target(name: "RxTestProject", dependencies: ["RxSwift", "RxCocoa"])
|
||||
]
|
||||
)
|
||||
```
|
||||
|
||||
```bash
|
||||
$ swift build
|
||||
```
|
||||
|
||||
To build or test a module with RxTest dependency, set `TEST=1`.
|
||||
|
||||
```bash
|
||||
$ TEST=1 swift test
|
||||
```
|
||||
|
||||
### Manually using git submodules
|
||||
|
||||
* Add RxSwift as a submodule
|
||||
|
||||
```bash
|
||||
$ git submodule add git@github.com:ReactiveX/RxSwift.git
|
||||
```
|
||||
|
||||
* Drag `Rx.xcodeproj` into Project Navigator
|
||||
* Go to `Project > Targets > Build Phases > Link Binary With Libraries`, click `+` and select `RxSwift`, `RxCocoa` and `RxRelay` targets
|
||||
|
||||
## References
|
||||
|
||||
* [http://reactivex.io/](http://reactivex.io/)
|
||||
* [Reactive Extensions GitHub (GitHub)](https://github.com/Reactive-Extensions)
|
||||
* [RxSwift RayWenderlich.com Book](https://store.raywenderlich.com/products/rxswift-reactive-programming-with-swift)
|
||||
* [RxSwift: Debunking the myth of hard (YouTube)](https://www.youtube.com/watch?v=GdvLP0ZAhhc)
|
||||
* [Boxue.io RxSwift Online Course](https://boxueio.com/series/rxswift-101) (Chinese 🇨🇳)
|
||||
* [Expert to Expert: Brian Beckman and Erik Meijer - Inside the .NET Reactive Framework (Rx) (video)](https://youtu.be/looJcaeboBY)
|
||||
* [Reactive Programming Overview (Jafar Husain from Netflix)](https://youtu.be/-8Y1-lE6NSA)
|
||||
* [Subject/Observer is Dual to Iterator (paper)](http://csl.stanford.edu/~christos/pldi2010.fit/meijer.duality.pdf)
|
||||
* [Rx standard sequence operators visualized (visualization tool)](http://rxmarbles.com/)
|
||||
* [Haskell](https://www.haskell.org/)
|
||||
88
Pods/RxCocoa/RxCocoa/Common/ControlTarget.swift
generated
Normal file
88
Pods/RxCocoa/RxCocoa/Common/ControlTarget.swift
generated
Normal file
@@ -0,0 +1,88 @@
|
||||
//
|
||||
// ControlTarget.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 2/21/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS) || os(tvOS) || os(macOS)
|
||||
|
||||
import RxSwift
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
import UIKit
|
||||
|
||||
typealias Control = UIKit.UIControl
|
||||
#elseif os(macOS)
|
||||
import Cocoa
|
||||
|
||||
typealias Control = Cocoa.NSControl
|
||||
#endif
|
||||
|
||||
// This should be only used from `MainScheduler`
|
||||
final class ControlTarget: RxTarget {
|
||||
typealias Callback = (Control) -> Void
|
||||
|
||||
let selector: Selector = #selector(ControlTarget.eventHandler(_:))
|
||||
|
||||
weak var control: Control?
|
||||
#if os(iOS) || os(tvOS)
|
||||
let controlEvents: UIControl.Event
|
||||
#endif
|
||||
var callback: Callback?
|
||||
#if os(iOS) || os(tvOS)
|
||||
init(control: Control, controlEvents: UIControl.Event, callback: @escaping Callback) {
|
||||
MainScheduler.ensureRunningOnMainThread()
|
||||
|
||||
self.control = control
|
||||
self.controlEvents = controlEvents
|
||||
self.callback = callback
|
||||
|
||||
super.init()
|
||||
|
||||
control.addTarget(self, action: selector, for: controlEvents)
|
||||
|
||||
let method = self.method(for: selector)
|
||||
if method == nil {
|
||||
rxFatalError("Can't find method")
|
||||
}
|
||||
}
|
||||
#elseif os(macOS)
|
||||
init(control: Control, callback: @escaping Callback) {
|
||||
MainScheduler.ensureRunningOnMainThread()
|
||||
|
||||
self.control = control
|
||||
self.callback = callback
|
||||
|
||||
super.init()
|
||||
|
||||
control.target = self
|
||||
control.action = self.selector
|
||||
|
||||
let method = self.method(for: self.selector)
|
||||
if method == nil {
|
||||
rxFatalError("Can't find method")
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@objc func eventHandler(_ sender: Control!) {
|
||||
if let callback = self.callback, let control = self.control {
|
||||
callback(control)
|
||||
}
|
||||
}
|
||||
|
||||
override func dispose() {
|
||||
super.dispose()
|
||||
#if os(iOS) || os(tvOS)
|
||||
self.control?.removeTarget(self, action: self.selector, for: self.controlEvents)
|
||||
#elseif os(macOS)
|
||||
self.control?.target = nil
|
||||
self.control?.action = nil
|
||||
#endif
|
||||
self.callback = nil
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
294
Pods/RxCocoa/RxCocoa/Common/DelegateProxy.swift
generated
Normal file
294
Pods/RxCocoa/RxCocoa/Common/DelegateProxy.swift
generated
Normal file
@@ -0,0 +1,294 @@
|
||||
//
|
||||
// DelegateProxy.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 6/14/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if !os(Linux)
|
||||
|
||||
import RxSwift
|
||||
#if SWIFT_PACKAGE && !os(Linux)
|
||||
import RxCocoaRuntime
|
||||
#endif
|
||||
|
||||
/// Base class for `DelegateProxyType` protocol.
|
||||
///
|
||||
/// This implementation is not thread safe and can be used only from one thread (Main thread).
|
||||
open class DelegateProxy<P: AnyObject, D>: _RXDelegateProxy {
|
||||
public typealias ParentObject = P
|
||||
public typealias Delegate = D
|
||||
|
||||
private var _sentMessageForSelector = [Selector: MessageDispatcher]()
|
||||
private var _methodInvokedForSelector = [Selector: MessageDispatcher]()
|
||||
|
||||
/// Parent object associated with delegate proxy.
|
||||
private weak var _parentObject: ParentObject?
|
||||
|
||||
private let _currentDelegateFor: (ParentObject) -> AnyObject?
|
||||
private let _setCurrentDelegateTo: (AnyObject?, ParentObject) -> Void
|
||||
|
||||
/// Initializes new instance.
|
||||
///
|
||||
/// - parameter parentObject: Optional parent object that owns `DelegateProxy` as associated object.
|
||||
public init<Proxy: DelegateProxyType>(parentObject: ParentObject, delegateProxy: Proxy.Type)
|
||||
where Proxy: DelegateProxy<ParentObject, Delegate>, Proxy.ParentObject == ParentObject, Proxy.Delegate == Delegate {
|
||||
self._parentObject = parentObject
|
||||
self._currentDelegateFor = delegateProxy._currentDelegate
|
||||
self._setCurrentDelegateTo = delegateProxy._setCurrentDelegate
|
||||
|
||||
MainScheduler.ensureRunningOnMainThread()
|
||||
#if TRACE_RESOURCES
|
||||
_ = Resources.incrementTotal()
|
||||
#endif
|
||||
super.init()
|
||||
}
|
||||
|
||||
/**
|
||||
Returns observable sequence of invocations of delegate methods. Elements are sent *before method is invoked*.
|
||||
|
||||
Only methods that have `void` return value can be observed using this method because
|
||||
those methods are used as a notification mechanism. It doesn't matter if they are optional
|
||||
or not. Observing is performed by installing a hidden associated `PublishSubject` that is
|
||||
used to dispatch messages to observers.
|
||||
|
||||
Delegate methods that have non `void` return value can't be observed directly using this method
|
||||
because:
|
||||
* those methods are not intended to be used as a notification mechanism, but as a behavior customization mechanism
|
||||
* there is no sensible automatic way to determine a default return value
|
||||
|
||||
In case observing of delegate methods that have return type is required, it can be done by
|
||||
manually installing a `PublishSubject` or `BehaviorSubject` and implementing delegate method.
|
||||
|
||||
e.g.
|
||||
|
||||
// delegate proxy part (RxScrollViewDelegateProxy)
|
||||
|
||||
let internalSubject = PublishSubject<CGPoint>
|
||||
|
||||
public func requiredDelegateMethod(scrollView: UIScrollView, arg1: CGPoint) -> Bool {
|
||||
internalSubject.on(.next(arg1))
|
||||
return self._forwardToDelegate?.requiredDelegateMethod?(scrollView, arg1: arg1) ?? defaultReturnValue
|
||||
}
|
||||
|
||||
....
|
||||
|
||||
// reactive property implementation in a real class (`UIScrollView`)
|
||||
public var property: Observable<CGPoint> {
|
||||
let proxy = RxScrollViewDelegateProxy.proxy(for: base)
|
||||
return proxy.internalSubject.asObservable()
|
||||
}
|
||||
|
||||
**In case calling this method prints "Delegate proxy is already implementing `\(selector)`,
|
||||
a more performant way of registering might exist.", that means that manual observing method
|
||||
is required analog to the example above because delegate method has already been implemented.**
|
||||
|
||||
- parameter selector: Selector used to filter observed invocations of delegate methods.
|
||||
- returns: Observable sequence of arguments passed to `selector` method.
|
||||
*/
|
||||
open func sentMessage(_ selector: Selector) -> Observable<[Any]> {
|
||||
MainScheduler.ensureRunningOnMainThread()
|
||||
|
||||
let subject = self._sentMessageForSelector[selector]
|
||||
|
||||
if let subject = subject {
|
||||
return subject.asObservable()
|
||||
}
|
||||
else {
|
||||
let subject = MessageDispatcher(selector: selector, delegateProxy: self)
|
||||
self._sentMessageForSelector[selector] = subject
|
||||
return subject.asObservable()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Returns observable sequence of invoked delegate methods. Elements are sent *after method is invoked*.
|
||||
|
||||
Only methods that have `void` return value can be observed using this method because
|
||||
those methods are used as a notification mechanism. It doesn't matter if they are optional
|
||||
or not. Observing is performed by installing a hidden associated `PublishSubject` that is
|
||||
used to dispatch messages to observers.
|
||||
|
||||
Delegate methods that have non `void` return value can't be observed directly using this method
|
||||
because:
|
||||
* those methods are not intended to be used as a notification mechanism, but as a behavior customization mechanism
|
||||
* there is no sensible automatic way to determine a default return value
|
||||
|
||||
In case observing of delegate methods that have return type is required, it can be done by
|
||||
manually installing a `PublishSubject` or `BehaviorSubject` and implementing delegate method.
|
||||
|
||||
e.g.
|
||||
|
||||
// delegate proxy part (RxScrollViewDelegateProxy)
|
||||
|
||||
let internalSubject = PublishSubject<CGPoint>
|
||||
|
||||
public func requiredDelegateMethod(scrollView: UIScrollView, arg1: CGPoint) -> Bool {
|
||||
internalSubject.on(.next(arg1))
|
||||
return self._forwardToDelegate?.requiredDelegateMethod?(scrollView, arg1: arg1) ?? defaultReturnValue
|
||||
}
|
||||
|
||||
....
|
||||
|
||||
// reactive property implementation in a real class (`UIScrollView`)
|
||||
public var property: Observable<CGPoint> {
|
||||
let proxy = RxScrollViewDelegateProxy.proxy(for: base)
|
||||
return proxy.internalSubject.asObservable()
|
||||
}
|
||||
|
||||
**In case calling this method prints "Delegate proxy is already implementing `\(selector)`,
|
||||
a more performant way of registering might exist.", that means that manual observing method
|
||||
is required analog to the example above because delegate method has already been implemented.**
|
||||
|
||||
- parameter selector: Selector used to filter observed invocations of delegate methods.
|
||||
- returns: Observable sequence of arguments passed to `selector` method.
|
||||
*/
|
||||
open func methodInvoked(_ selector: Selector) -> Observable<[Any]> {
|
||||
MainScheduler.ensureRunningOnMainThread()
|
||||
|
||||
let subject = self._methodInvokedForSelector[selector]
|
||||
|
||||
if let subject = subject {
|
||||
return subject.asObservable()
|
||||
}
|
||||
else {
|
||||
let subject = MessageDispatcher(selector: selector, delegateProxy: self)
|
||||
self._methodInvokedForSelector[selector] = subject
|
||||
return subject.asObservable()
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate func checkSelectorIsObservable(_ selector: Selector) {
|
||||
MainScheduler.ensureRunningOnMainThread()
|
||||
|
||||
if self.hasWiredImplementation(for: selector) {
|
||||
print("⚠️ Delegate proxy is already implementing `\(selector)`, a more performant way of registering might exist.")
|
||||
return
|
||||
}
|
||||
|
||||
if self.voidDelegateMethodsContain(selector) {
|
||||
return
|
||||
}
|
||||
|
||||
// In case `_forwardToDelegate` is `nil`, it is assumed the check is being done prematurely.
|
||||
if !(self._forwardToDelegate?.responds(to: selector) ?? true) {
|
||||
print("⚠️ Using delegate proxy dynamic interception method but the target delegate object doesn't respond to the requested selector. " +
|
||||
"In case pure Swift delegate proxy is being used please use manual observing method by using`PublishSubject`s. " +
|
||||
" (selector: `\(selector)`, forwardToDelegate: `\(self._forwardToDelegate ?? self)`)")
|
||||
}
|
||||
}
|
||||
|
||||
// proxy
|
||||
|
||||
open override func _sentMessage(_ selector: Selector, withArguments arguments: [Any]) {
|
||||
self._sentMessageForSelector[selector]?.on(.next(arguments))
|
||||
}
|
||||
|
||||
open override func _methodInvoked(_ selector: Selector, withArguments arguments: [Any]) {
|
||||
self._methodInvokedForSelector[selector]?.on(.next(arguments))
|
||||
}
|
||||
|
||||
/// Returns reference of normal delegate that receives all forwarded messages
|
||||
/// through `self`.
|
||||
///
|
||||
/// - returns: Value of reference if set or nil.
|
||||
open func forwardToDelegate() -> Delegate? {
|
||||
return castOptionalOrFatalError(self._forwardToDelegate)
|
||||
}
|
||||
|
||||
/// Sets reference of normal delegate that receives all forwarded messages
|
||||
/// through `self`.
|
||||
///
|
||||
/// - parameter delegate: Reference of delegate that receives all messages through `self`.
|
||||
/// - parameter retainDelegate: Should `self` retain `forwardToDelegate`.
|
||||
open func setForwardToDelegate(_ delegate: Delegate?, retainDelegate: Bool) {
|
||||
#if DEBUG // 4.0 all configurations
|
||||
MainScheduler.ensureRunningOnMainThread()
|
||||
#endif
|
||||
self._setForwardToDelegate(delegate, retainDelegate: retainDelegate)
|
||||
|
||||
let sentSelectors: [Selector] = self._sentMessageForSelector.values.filter { $0.hasObservers }.map { $0.selector }
|
||||
let invokedSelectors: [Selector] = self._methodInvokedForSelector.values.filter { $0.hasObservers }.map { $0.selector }
|
||||
let allUsedSelectors = sentSelectors + invokedSelectors
|
||||
|
||||
for selector in Set(allUsedSelectors) {
|
||||
self.checkSelectorIsObservable(selector)
|
||||
}
|
||||
|
||||
self.reset()
|
||||
}
|
||||
|
||||
private func hasObservers(selector: Selector) -> Bool {
|
||||
return (self._sentMessageForSelector[selector]?.hasObservers ?? false)
|
||||
|| (self._methodInvokedForSelector[selector]?.hasObservers ?? false)
|
||||
}
|
||||
|
||||
override open func responds(to aSelector: Selector!) -> Bool {
|
||||
guard let aSelector = aSelector else { return false }
|
||||
return super.responds(to: aSelector)
|
||||
|| (self._forwardToDelegate?.responds(to: aSelector) ?? false)
|
||||
|| (self.voidDelegateMethodsContain(aSelector) && self.hasObservers(selector: aSelector))
|
||||
}
|
||||
|
||||
fileprivate func reset() {
|
||||
guard let parentObject = self._parentObject else { return }
|
||||
|
||||
let maybeCurrentDelegate = self._currentDelegateFor(parentObject)
|
||||
|
||||
if maybeCurrentDelegate === self {
|
||||
self._setCurrentDelegateTo(nil, parentObject)
|
||||
self._setCurrentDelegateTo(castOrFatalError(self), parentObject)
|
||||
}
|
||||
}
|
||||
|
||||
deinit {
|
||||
for v in self._sentMessageForSelector.values {
|
||||
v.on(.completed)
|
||||
}
|
||||
for v in self._methodInvokedForSelector.values {
|
||||
v.on(.completed)
|
||||
}
|
||||
#if TRACE_RESOURCES
|
||||
_ = Resources.decrementTotal()
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private let mainScheduler = MainScheduler()
|
||||
|
||||
private final class MessageDispatcher {
|
||||
private let dispatcher: PublishSubject<[Any]>
|
||||
private let result: Observable<[Any]>
|
||||
|
||||
fileprivate let selector: Selector
|
||||
|
||||
init<P, D>(selector: Selector, delegateProxy _delegateProxy: DelegateProxy<P, D>) {
|
||||
weak var weakDelegateProxy = _delegateProxy
|
||||
|
||||
let dispatcher = PublishSubject<[Any]>()
|
||||
self.dispatcher = dispatcher
|
||||
self.selector = selector
|
||||
|
||||
self.result = dispatcher
|
||||
.do(onSubscribed: { weakDelegateProxy?.checkSelectorIsObservable(selector); weakDelegateProxy?.reset() }, onDispose: { weakDelegateProxy?.reset() })
|
||||
.share()
|
||||
.subscribe(on: mainScheduler)
|
||||
}
|
||||
|
||||
var on: (Event<[Any]>) -> Void {
|
||||
return self.dispatcher.on
|
||||
}
|
||||
|
||||
var hasObservers: Bool {
|
||||
return self.dispatcher.hasObservers
|
||||
}
|
||||
|
||||
func asObservable() -> Observable<[Any]> {
|
||||
return self.result
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
435
Pods/RxCocoa/RxCocoa/Common/DelegateProxyType.swift
generated
Normal file
435
Pods/RxCocoa/RxCocoa/Common/DelegateProxyType.swift
generated
Normal file
@@ -0,0 +1,435 @@
|
||||
//
|
||||
// DelegateProxyType.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 6/15/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if !os(Linux)
|
||||
|
||||
import Foundation
|
||||
import RxSwift
|
||||
|
||||
/**
|
||||
`DelegateProxyType` protocol enables using both normal delegates and Rx observable sequences with
|
||||
views that can have only one delegate/datasource registered.
|
||||
|
||||
`Proxies` store information about observers, subscriptions and delegates
|
||||
for specific views.
|
||||
|
||||
Type implementing `DelegateProxyType` should never be initialized directly.
|
||||
|
||||
To fetch initialized instance of type implementing `DelegateProxyType`, `proxy` method
|
||||
should be used.
|
||||
|
||||
This is more or less how it works.
|
||||
|
||||
|
||||
|
||||
+-------------------------------------------+
|
||||
| |
|
||||
| UIView subclass (UIScrollView) |
|
||||
| |
|
||||
+-----------+-------------------------------+
|
||||
|
|
||||
| Delegate
|
||||
|
|
||||
|
|
||||
+-----------v-------------------------------+
|
||||
| |
|
||||
| Delegate proxy : DelegateProxyType +-----+----> Observable<T1>
|
||||
| , UIScrollViewDelegate | |
|
||||
+-----------+-------------------------------+ +----> Observable<T2>
|
||||
| |
|
||||
| +----> Observable<T3>
|
||||
| |
|
||||
| forwards events |
|
||||
| to custom delegate |
|
||||
| v
|
||||
+-----------v-------------------------------+
|
||||
| |
|
||||
| Custom delegate (UIScrollViewDelegate) |
|
||||
| |
|
||||
+-------------------------------------------+
|
||||
|
||||
|
||||
Since RxCocoa needs to automagically create those Proxies and because views that have delegates can be hierarchical
|
||||
|
||||
UITableView : UIScrollView : UIView
|
||||
|
||||
.. and corresponding delegates are also hierarchical
|
||||
|
||||
UITableViewDelegate : UIScrollViewDelegate : NSObject
|
||||
|
||||
... this mechanism can be extended by using the following snippet in `registerKnownImplementations` or in some other
|
||||
part of your app that executes before using `rx.*` (e.g. appDidFinishLaunching).
|
||||
|
||||
RxScrollViewDelegateProxy.register { RxTableViewDelegateProxy(parentObject: $0) }
|
||||
|
||||
*/
|
||||
public protocol DelegateProxyType: AnyObject {
|
||||
associatedtype ParentObject: AnyObject
|
||||
associatedtype Delegate
|
||||
|
||||
/// It is require that enumerate call `register` of the extended DelegateProxy subclasses here.
|
||||
static func registerKnownImplementations()
|
||||
|
||||
/// Unique identifier for delegate
|
||||
static var identifier: UnsafeRawPointer { get }
|
||||
|
||||
/// Returns designated delegate property for object.
|
||||
///
|
||||
/// Objects can have multiple delegate properties.
|
||||
///
|
||||
/// Each delegate property needs to have it's own type implementing `DelegateProxyType`.
|
||||
///
|
||||
/// It's abstract method.
|
||||
///
|
||||
/// - parameter object: Object that has delegate property.
|
||||
/// - returns: Value of delegate property.
|
||||
static func currentDelegate(for object: ParentObject) -> Delegate?
|
||||
|
||||
/// Sets designated delegate property for object.
|
||||
///
|
||||
/// Objects can have multiple delegate properties.
|
||||
///
|
||||
/// Each delegate property needs to have it's own type implementing `DelegateProxyType`.
|
||||
///
|
||||
/// It's abstract method.
|
||||
///
|
||||
/// - parameter delegate: Delegate value.
|
||||
/// - parameter object: Object that has delegate property.
|
||||
static func setCurrentDelegate(_ delegate: Delegate?, to object: ParentObject)
|
||||
|
||||
/// Returns reference of normal delegate that receives all forwarded messages
|
||||
/// through `self`.
|
||||
///
|
||||
/// - returns: Value of reference if set or nil.
|
||||
func forwardToDelegate() -> Delegate?
|
||||
|
||||
/// Sets reference of normal delegate that receives all forwarded messages
|
||||
/// through `self`.
|
||||
///
|
||||
/// - parameter forwardToDelegate: Reference of delegate that receives all messages through `self`.
|
||||
/// - parameter retainDelegate: Should `self` retain `forwardToDelegate`.
|
||||
func setForwardToDelegate(_ forwardToDelegate: Delegate?, retainDelegate: Bool)
|
||||
}
|
||||
|
||||
// default implementations
|
||||
extension DelegateProxyType {
|
||||
/// Unique identifier for delegate
|
||||
public static var identifier: UnsafeRawPointer {
|
||||
let delegateIdentifier = ObjectIdentifier(Delegate.self)
|
||||
let integerIdentifier = Int(bitPattern: delegateIdentifier)
|
||||
return UnsafeRawPointer(bitPattern: integerIdentifier)!
|
||||
}
|
||||
}
|
||||
|
||||
// workaround of Delegate: class
|
||||
extension DelegateProxyType {
|
||||
static func _currentDelegate(for object: ParentObject) -> AnyObject? {
|
||||
currentDelegate(for: object).map { $0 as AnyObject }
|
||||
}
|
||||
|
||||
static func _setCurrentDelegate(_ delegate: AnyObject?, to object: ParentObject) {
|
||||
setCurrentDelegate(castOptionalOrFatalError(delegate), to: object)
|
||||
}
|
||||
|
||||
func _forwardToDelegate() -> AnyObject? {
|
||||
self.forwardToDelegate().map { $0 as AnyObject }
|
||||
}
|
||||
|
||||
func _setForwardToDelegate(_ forwardToDelegate: AnyObject?, retainDelegate: Bool) {
|
||||
self.setForwardToDelegate(castOptionalOrFatalError(forwardToDelegate), retainDelegate: retainDelegate)
|
||||
}
|
||||
}
|
||||
|
||||
extension DelegateProxyType {
|
||||
|
||||
/// Store DelegateProxy subclass to factory.
|
||||
/// When make 'Rx*DelegateProxy' subclass, call 'Rx*DelegateProxySubclass.register(for:_)' 1 time, or use it in DelegateProxyFactory
|
||||
/// 'Rx*DelegateProxy' can have one subclass implementation per concrete ParentObject type.
|
||||
/// Should call it from concrete DelegateProxy type, not generic.
|
||||
public static func register<Parent>(make: @escaping (Parent) -> Self) {
|
||||
self.factory.extend(make: make)
|
||||
}
|
||||
|
||||
/// Creates new proxy for target object.
|
||||
/// Should not call this function directory, use 'DelegateProxy.proxy(for:)'
|
||||
public static func createProxy(for object: AnyObject) -> Self {
|
||||
castOrFatalError(factory.createProxy(for: object))
|
||||
}
|
||||
|
||||
/// Returns existing proxy for object or installs new instance of delegate proxy.
|
||||
///
|
||||
/// - parameter object: Target object on which to install delegate proxy.
|
||||
/// - returns: Installed instance of delegate proxy.
|
||||
///
|
||||
///
|
||||
/// extension Reactive where Base: UISearchBar {
|
||||
///
|
||||
/// public var delegate: DelegateProxy<UISearchBar, UISearchBarDelegate> {
|
||||
/// return RxSearchBarDelegateProxy.proxy(for: base)
|
||||
/// }
|
||||
///
|
||||
/// public var text: ControlProperty<String> {
|
||||
/// let source: Observable<String> = self.delegate.observe(#selector(UISearchBarDelegate.searchBar(_:textDidChange:)))
|
||||
/// ...
|
||||
/// }
|
||||
/// }
|
||||
public static func proxy(for object: ParentObject) -> Self {
|
||||
MainScheduler.ensureRunningOnMainThread()
|
||||
|
||||
let maybeProxy = self.assignedProxy(for: object)
|
||||
|
||||
let proxy: AnyObject
|
||||
if let existingProxy = maybeProxy {
|
||||
proxy = existingProxy
|
||||
}
|
||||
else {
|
||||
proxy = castOrFatalError(self.createProxy(for: object))
|
||||
self.assignProxy(proxy, toObject: object)
|
||||
assert(self.assignedProxy(for: object) === proxy)
|
||||
}
|
||||
let currentDelegate = self._currentDelegate(for: object)
|
||||
let delegateProxy: Self = castOrFatalError(proxy)
|
||||
|
||||
if currentDelegate !== delegateProxy {
|
||||
delegateProxy._setForwardToDelegate(currentDelegate, retainDelegate: false)
|
||||
assert(delegateProxy._forwardToDelegate() === currentDelegate)
|
||||
self._setCurrentDelegate(proxy, to: object)
|
||||
assert(self._currentDelegate(for: object) === proxy)
|
||||
assert(delegateProxy._forwardToDelegate() === currentDelegate)
|
||||
}
|
||||
|
||||
return delegateProxy
|
||||
}
|
||||
|
||||
/// Sets forward delegate for `DelegateProxyType` associated with a specific object and return disposable that can be used to unset the forward to delegate.
|
||||
/// Using this method will also make sure that potential original object cached selectors are cleared and will report any accidental forward delegate mutations.
|
||||
///
|
||||
/// - parameter forwardDelegate: Delegate object to set.
|
||||
/// - parameter retainDelegate: Retain `forwardDelegate` while it's being set.
|
||||
/// - parameter onProxyForObject: Object that has `delegate` property.
|
||||
/// - returns: Disposable object that can be used to clear forward delegate.
|
||||
public static func installForwardDelegate(_ forwardDelegate: Delegate, retainDelegate: Bool, onProxyForObject object: ParentObject) -> Disposable {
|
||||
weak var weakForwardDelegate: AnyObject? = forwardDelegate as AnyObject
|
||||
let proxy = self.proxy(for: object)
|
||||
|
||||
assert(proxy._forwardToDelegate() === nil, "This is a feature to warn you that there is already a delegate (or data source) set somewhere previously. The action you are trying to perform will clear that delegate (data source) and that means that some of your features that depend on that delegate (data source) being set will likely stop working.\n" +
|
||||
"If you are ok with this, try to set delegate (data source) to `nil` in front of this operation.\n" +
|
||||
" This is the source object value: \(object)\n" +
|
||||
" This is the original delegate (data source) value: \(proxy.forwardToDelegate()!)\n" +
|
||||
"Hint: Maybe delegate was already set in xib or storyboard and now it's being overwritten in code.\n")
|
||||
|
||||
proxy.setForwardToDelegate(forwardDelegate, retainDelegate: retainDelegate)
|
||||
|
||||
return Disposables.create {
|
||||
MainScheduler.ensureRunningOnMainThread()
|
||||
|
||||
let delegate: AnyObject? = weakForwardDelegate
|
||||
|
||||
assert(delegate == nil || proxy._forwardToDelegate() === delegate, "Delegate was changed from time it was first set. Current \(String(describing: proxy.forwardToDelegate())), and it should have been \(proxy)")
|
||||
|
||||
proxy.setForwardToDelegate(nil, retainDelegate: retainDelegate)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// private extensions
|
||||
extension DelegateProxyType {
|
||||
private static var factory: DelegateProxyFactory {
|
||||
DelegateProxyFactory.sharedFactory(for: self)
|
||||
}
|
||||
|
||||
private static func assignedProxy(for object: ParentObject) -> AnyObject? {
|
||||
let maybeDelegate = objc_getAssociatedObject(object, self.identifier)
|
||||
return castOptionalOrFatalError(maybeDelegate)
|
||||
}
|
||||
|
||||
private static func assignProxy(_ proxy: AnyObject, toObject object: ParentObject) {
|
||||
objc_setAssociatedObject(object, self.identifier, proxy, .OBJC_ASSOCIATION_RETAIN)
|
||||
}
|
||||
}
|
||||
|
||||
/// Describes an object that has a delegate.
|
||||
public protocol HasDelegate: AnyObject {
|
||||
/// Delegate type
|
||||
associatedtype Delegate
|
||||
|
||||
/// Delegate
|
||||
var delegate: Delegate? { get set }
|
||||
}
|
||||
|
||||
extension DelegateProxyType where ParentObject: HasDelegate, Self.Delegate == ParentObject.Delegate {
|
||||
public static func currentDelegate(for object: ParentObject) -> Delegate? {
|
||||
object.delegate
|
||||
}
|
||||
|
||||
public static func setCurrentDelegate(_ delegate: Delegate?, to object: ParentObject) {
|
||||
object.delegate = delegate
|
||||
}
|
||||
}
|
||||
|
||||
/// Describes an object that has a data source.
|
||||
public protocol HasDataSource: AnyObject {
|
||||
/// Data source type
|
||||
associatedtype DataSource
|
||||
|
||||
/// Data source
|
||||
var dataSource: DataSource? { get set }
|
||||
}
|
||||
|
||||
extension DelegateProxyType where ParentObject: HasDataSource, Self.Delegate == ParentObject.DataSource {
|
||||
public static func currentDelegate(for object: ParentObject) -> Delegate? {
|
||||
object.dataSource
|
||||
}
|
||||
|
||||
public static func setCurrentDelegate(_ delegate: Delegate?, to object: ParentObject) {
|
||||
object.dataSource = delegate
|
||||
}
|
||||
}
|
||||
|
||||
/// Describes an object that has a prefetch data source.
|
||||
@available(iOS 10.0, tvOS 10.0, *)
|
||||
public protocol HasPrefetchDataSource: AnyObject {
|
||||
/// Prefetch data source type
|
||||
associatedtype PrefetchDataSource
|
||||
|
||||
/// Prefetch data source
|
||||
var prefetchDataSource: PrefetchDataSource? { get set }
|
||||
}
|
||||
|
||||
@available(iOS 10.0, tvOS 10.0, *)
|
||||
extension DelegateProxyType where ParentObject: HasPrefetchDataSource, Self.Delegate == ParentObject.PrefetchDataSource {
|
||||
public static func currentDelegate(for object: ParentObject) -> Delegate? {
|
||||
object.prefetchDataSource
|
||||
}
|
||||
|
||||
public static func setCurrentDelegate(_ delegate: Delegate?, to object: ParentObject) {
|
||||
object.prefetchDataSource = delegate
|
||||
}
|
||||
}
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
import UIKit
|
||||
|
||||
extension ObservableType {
|
||||
func subscribeProxyDataSource<DelegateProxy: DelegateProxyType>(ofObject object: DelegateProxy.ParentObject, dataSource: DelegateProxy.Delegate, retainDataSource: Bool, binding: @escaping (DelegateProxy, Event<Element>) -> Void)
|
||||
-> Disposable
|
||||
where DelegateProxy.ParentObject: UIView
|
||||
, DelegateProxy.Delegate: AnyObject {
|
||||
let proxy = DelegateProxy.proxy(for: object)
|
||||
let unregisterDelegate = DelegateProxy.installForwardDelegate(dataSource, retainDelegate: retainDataSource, onProxyForObject: object)
|
||||
|
||||
// Do not perform layoutIfNeeded if the object is still not in the view hierarchy
|
||||
if object.window != nil {
|
||||
// this is needed to flush any delayed old state (https://github.com/RxSwiftCommunity/RxDataSources/pull/75)
|
||||
object.layoutIfNeeded()
|
||||
}
|
||||
|
||||
let subscription = self.asObservable()
|
||||
.observe(on:MainScheduler())
|
||||
.catch { error in
|
||||
bindingError(error)
|
||||
return Observable.empty()
|
||||
}
|
||||
// source can never end, otherwise it would release the subscriber, and deallocate the data source
|
||||
.concat(Observable.never())
|
||||
.take(until: object.rx.deallocated)
|
||||
.subscribe { [weak object] (event: Event<Element>) in
|
||||
|
||||
if let object = object {
|
||||
assert(proxy === DelegateProxy.currentDelegate(for: object), "Proxy changed from the time it was first set.\nOriginal: \(proxy)\nExisting: \(String(describing: DelegateProxy.currentDelegate(for: object)))")
|
||||
}
|
||||
|
||||
binding(proxy, event)
|
||||
|
||||
switch event {
|
||||
case .error(let error):
|
||||
bindingError(error)
|
||||
unregisterDelegate.dispose()
|
||||
case .completed:
|
||||
unregisterDelegate.dispose()
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return Disposables.create { [weak object] in
|
||||
subscription.dispose()
|
||||
|
||||
if object?.window != nil {
|
||||
object?.layoutIfNeeded()
|
||||
}
|
||||
|
||||
unregisterDelegate.dispose()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
To add delegate proxy subclasses call `DelegateProxySubclass.register()` in `registerKnownImplementations` or in some other
|
||||
part of your app that executes before using `rx.*` (e.g. appDidFinishLaunching).
|
||||
|
||||
class RxScrollViewDelegateProxy: DelegateProxy {
|
||||
public static func registerKnownImplementations() {
|
||||
self.register { RxTableViewDelegateProxy(parentObject: $0) }
|
||||
}
|
||||
...
|
||||
|
||||
|
||||
*/
|
||||
private class DelegateProxyFactory {
|
||||
private static var _sharedFactories: [UnsafeRawPointer: DelegateProxyFactory] = [:]
|
||||
|
||||
fileprivate static func sharedFactory<DelegateProxy: DelegateProxyType>(for proxyType: DelegateProxy.Type) -> DelegateProxyFactory {
|
||||
MainScheduler.ensureRunningOnMainThread()
|
||||
let identifier = DelegateProxy.identifier
|
||||
if let factory = _sharedFactories[identifier] {
|
||||
return factory
|
||||
}
|
||||
let factory = DelegateProxyFactory(for: proxyType)
|
||||
_sharedFactories[identifier] = factory
|
||||
DelegateProxy.registerKnownImplementations()
|
||||
return factory
|
||||
}
|
||||
|
||||
private var _factories: [ObjectIdentifier: ((AnyObject) -> AnyObject)]
|
||||
private var _delegateProxyType: Any.Type
|
||||
private var _identifier: UnsafeRawPointer
|
||||
|
||||
private init<DelegateProxy: DelegateProxyType>(for proxyType: DelegateProxy.Type) {
|
||||
self._factories = [:]
|
||||
self._delegateProxyType = proxyType
|
||||
self._identifier = proxyType.identifier
|
||||
}
|
||||
|
||||
fileprivate func extend<DelegateProxy: DelegateProxyType, ParentObject>(make: @escaping (ParentObject) -> DelegateProxy) {
|
||||
MainScheduler.ensureRunningOnMainThread()
|
||||
precondition(self._identifier == DelegateProxy.identifier, "Delegate proxy has inconsistent identifier")
|
||||
guard self._factories[ObjectIdentifier(ParentObject.self)] == nil else {
|
||||
rxFatalError("The factory of \(ParentObject.self) is duplicated. DelegateProxy is not allowed of duplicated base object type.")
|
||||
}
|
||||
self._factories[ObjectIdentifier(ParentObject.self)] = { make(castOrFatalError($0)) }
|
||||
}
|
||||
|
||||
fileprivate func createProxy(for object: AnyObject) -> AnyObject {
|
||||
MainScheduler.ensureRunningOnMainThread()
|
||||
var maybeMirror: Mirror? = Mirror(reflecting: object)
|
||||
while let mirror = maybeMirror {
|
||||
if let factory = self._factories[ObjectIdentifier(mirror.subjectType)] {
|
||||
return factory(object)
|
||||
}
|
||||
maybeMirror = mirror.superclassMirror
|
||||
}
|
||||
rxFatalError("DelegateProxy has no factory of \(object). Implement DelegateProxy subclass for \(object) first.")
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
148
Pods/RxCocoa/RxCocoa/Common/Infallible+Bind.swift
generated
Normal file
148
Pods/RxCocoa/RxCocoa/Common/Infallible+Bind.swift
generated
Normal file
@@ -0,0 +1,148 @@
|
||||
//
|
||||
// Infallible+Bind.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Shai Mishali on 27/08/2020.
|
||||
// Copyright © 2020 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
import RxSwift
|
||||
|
||||
extension InfallibleType {
|
||||
/**
|
||||
Creates new subscription and sends elements to observer(s).
|
||||
In this form, it's equivalent to the `subscribe` method, but it better conveys intent, and enables
|
||||
writing more consistent binding code.
|
||||
- parameter observers: Observers to receives events.
|
||||
- returns: Disposable object that can be used to unsubscribe the observers.
|
||||
*/
|
||||
public func bind<Observer: ObserverType>(to observers: Observer...) -> Disposable where Observer.Element == Element {
|
||||
self.subscribe { event in
|
||||
observers.forEach { $0.on(event) }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Creates new subscription and sends elements to observer(s).
|
||||
In this form, it's equivalent to the `subscribe` method, but it better conveys intent, and enables
|
||||
writing more consistent binding code.
|
||||
- parameter observers: Observers to receives events.
|
||||
- returns: Disposable object that can be used to unsubscribe the observers.
|
||||
*/
|
||||
public func bind<Observer: ObserverType>(to observers: Observer...) -> Disposable where Observer.Element == Element? {
|
||||
self.map { $0 as Element? }
|
||||
.subscribe { event in
|
||||
observers.forEach { $0.on(event) }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Subscribes to observable sequence using custom binder function.
|
||||
|
||||
- parameter binder: Function used to bind elements from `self`.
|
||||
- returns: Object representing subscription.
|
||||
*/
|
||||
public func bind<Result>(to binder: (Self) -> Result) -> Result {
|
||||
binder(self)
|
||||
}
|
||||
|
||||
/**
|
||||
Subscribes to observable sequence using custom binder function and final parameter passed to binder function
|
||||
after `self` is passed.
|
||||
|
||||
public func bind<R1, R2>(to binder: Self -> R1 -> R2, curriedArgument: R1) -> R2 {
|
||||
return binder(self)(curriedArgument)
|
||||
}
|
||||
|
||||
- parameter binder: Function used to bind elements from `self`.
|
||||
- parameter curriedArgument: Final argument passed to `binder` to finish binding process.
|
||||
- returns: Object representing subscription.
|
||||
*/
|
||||
public func bind<R1, R2>(to binder: (Self) -> (R1) -> R2, curriedArgument: R1) -> R2 {
|
||||
binder(self)(curriedArgument)
|
||||
}
|
||||
|
||||
/**
|
||||
Subscribes an element handler to an observable sequence.
|
||||
In case error occurs in debug mode, `fatalError` will be raised.
|
||||
In case error occurs in release mode, `error` will be logged.
|
||||
|
||||
- parameter onNext: Action to invoke for each element in the observable sequence.
|
||||
- returns: Subscription object used to unsubscribe from the observable sequence.
|
||||
*/
|
||||
public func bind(onNext: @escaping (Element) -> Void) -> Disposable {
|
||||
self.subscribe(onNext: onNext)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates new subscription and sends elements to `BehaviorRelay`.
|
||||
|
||||
- parameter relays: Target relay for sequence elements.
|
||||
- returns: Disposable object that can be used to unsubscribe the observer from the relay.
|
||||
*/
|
||||
public func bind(to relays: BehaviorRelay<Element>...) -> Disposable {
|
||||
return self.subscribe(onNext: { e in
|
||||
relays.forEach { $0.accept(e) }
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
Creates new subscription and sends elements to `BehaviorRelay`.
|
||||
|
||||
- parameter relays: Target relay for sequence elements.
|
||||
- returns: Disposable object that can be used to unsubscribe the observer from the relay.
|
||||
*/
|
||||
public func bind(to relays: BehaviorRelay<Element?>...) -> Disposable {
|
||||
return self.subscribe(onNext: { e in
|
||||
relays.forEach { $0.accept(e) }
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
Creates new subscription and sends elements to `PublishRelay`.
|
||||
|
||||
- parameter relays: Target relay for sequence elements.
|
||||
- returns: Disposable object that can be used to unsubscribe the observer from the relay.
|
||||
*/
|
||||
public func bind(to relays: PublishRelay<Element>...) -> Disposable {
|
||||
return self.subscribe(onNext: { e in
|
||||
relays.forEach { $0.accept(e) }
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
Creates new subscription and sends elements to `PublishRelay`.
|
||||
|
||||
- parameter relays: Target relay for sequence elements.
|
||||
- returns: Disposable object that can be used to unsubscribe the observer from the relay.
|
||||
*/
|
||||
public func bind(to relays: PublishRelay<Element?>...) -> Disposable {
|
||||
return self.subscribe(onNext: { e in
|
||||
relays.forEach { $0.accept(e) }
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
Creates new subscription and sends elements to `ReplayRelay`.
|
||||
|
||||
- parameter relays: Target relay for sequence elements.
|
||||
- returns: Disposable object that can be used to unsubscribe the observer from the relay.
|
||||
*/
|
||||
public func bind(to relays: ReplayRelay<Element>...) -> Disposable {
|
||||
return self.subscribe(onNext: { e in
|
||||
relays.forEach { $0.accept(e) }
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
Creates new subscription and sends elements to `ReplayRelay`.
|
||||
|
||||
- parameter relays: Target relay for sequence elements.
|
||||
- returns: Disposable object that can be used to unsubscribe the observer from the relay.
|
||||
*/
|
||||
public func bind(to relays: ReplayRelay<Element?>...) -> Disposable {
|
||||
return self.subscribe(onNext: { e in
|
||||
relays.forEach { $0.accept(e) }
|
||||
})
|
||||
}
|
||||
}
|
||||
103
Pods/RxCocoa/RxCocoa/Common/Observable+Bind.swift
generated
Normal file
103
Pods/RxCocoa/RxCocoa/Common/Observable+Bind.swift
generated
Normal file
@@ -0,0 +1,103 @@
|
||||
//
|
||||
// Observable+Bind.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 8/29/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
import RxSwift
|
||||
|
||||
extension ObservableType {
|
||||
/**
|
||||
Creates new subscription and sends elements to observer(s).
|
||||
In this form, it's equivalent to the `subscribe` method, but it better conveys intent, and enables
|
||||
writing more consistent binding code.
|
||||
- parameter observers: Observers to receives events.
|
||||
- returns: Disposable object that can be used to unsubscribe the observers.
|
||||
*/
|
||||
public func bind<Observer: ObserverType>(to observers: Observer...) -> Disposable where Observer.Element == Element {
|
||||
self.subscribe { event in
|
||||
observers.forEach { $0.on(event) }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Creates new subscription and sends elements to observer(s).
|
||||
In this form, it's equivalent to the `subscribe` method, but it better conveys intent, and enables
|
||||
writing more consistent binding code.
|
||||
- parameter observers: Observers to receives events.
|
||||
- returns: Disposable object that can be used to unsubscribe the observers.
|
||||
*/
|
||||
public func bind<Observer: ObserverType>(to observers: Observer...) -> Disposable where Observer.Element == Element? {
|
||||
self.map { $0 as Element? }
|
||||
.subscribe { event in
|
||||
observers.forEach { $0.on(event) }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Subscribes to observable sequence using custom binder function.
|
||||
|
||||
- parameter binder: Function used to bind elements from `self`.
|
||||
- returns: Object representing subscription.
|
||||
*/
|
||||
public func bind<Result>(to binder: (Self) -> Result) -> Result {
|
||||
binder(self)
|
||||
}
|
||||
|
||||
/**
|
||||
Subscribes to observable sequence using custom binder function and final parameter passed to binder function
|
||||
after `self` is passed.
|
||||
|
||||
public func bind<R1, R2>(to binder: Self -> R1 -> R2, curriedArgument: R1) -> R2 {
|
||||
return binder(self)(curriedArgument)
|
||||
}
|
||||
|
||||
- parameter binder: Function used to bind elements from `self`.
|
||||
- parameter curriedArgument: Final argument passed to `binder` to finish binding process.
|
||||
- returns: Object representing subscription.
|
||||
*/
|
||||
public func bind<R1, R2>(to binder: (Self) -> (R1) -> R2, curriedArgument: R1) -> R2 {
|
||||
binder(self)(curriedArgument)
|
||||
}
|
||||
|
||||
/**
|
||||
Subscribes an element handler to an observable sequence.
|
||||
In case error occurs in debug mode, `fatalError` will be raised.
|
||||
In case error occurs in release mode, `error` will be logged.
|
||||
|
||||
- Note: If `object` can't be retained, none of the other closures will be invoked.
|
||||
|
||||
- parameter object: The object to provide an unretained reference on.
|
||||
- parameter onNext: Action to invoke for each element in the observable sequence.
|
||||
- returns: Subscription object used to unsubscribe from the observable sequence.
|
||||
*/
|
||||
public func bind<Object: AnyObject>(
|
||||
with object: Object,
|
||||
onNext: @escaping (Object, Element) -> Void
|
||||
) -> Disposable {
|
||||
self.subscribe(onNext: { [weak object] in
|
||||
guard let object = object else { return }
|
||||
onNext(object, $0)
|
||||
},
|
||||
onError: { error in
|
||||
rxFatalErrorInDebug("Binding error: \(error)")
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
Subscribes an element handler to an observable sequence.
|
||||
In case error occurs in debug mode, `fatalError` will be raised.
|
||||
In case error occurs in release mode, `error` will be logged.
|
||||
|
||||
- parameter onNext: Action to invoke for each element in the observable sequence.
|
||||
- returns: Subscription object used to unsubscribe from the observable sequence.
|
||||
*/
|
||||
public func bind(onNext: @escaping (Element) -> Void) -> Disposable {
|
||||
self.subscribe(onNext: onNext,
|
||||
onError: { error in
|
||||
rxFatalErrorInDebug("Binding error: \(error)")
|
||||
})
|
||||
}
|
||||
}
|
||||
161
Pods/RxCocoa/RxCocoa/Common/RxCocoaObjCRuntimeError+Extensions.swift
generated
Normal file
161
Pods/RxCocoa/RxCocoa/Common/RxCocoaObjCRuntimeError+Extensions.swift
generated
Normal file
@@ -0,0 +1,161 @@
|
||||
//
|
||||
// RxCocoaObjCRuntimeError+Extensions.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 10/9/16.
|
||||
// Copyright © 2016 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if SWIFT_PACKAGE && !DISABLE_SWIZZLING && !os(Linux)
|
||||
import RxCocoaRuntime
|
||||
#endif
|
||||
|
||||
#if !DISABLE_SWIZZLING && !os(Linux)
|
||||
/// RxCocoa ObjC runtime interception mechanism.
|
||||
public enum RxCocoaInterceptionMechanism {
|
||||
/// Unknown message interception mechanism.
|
||||
case unknown
|
||||
/// Key value observing interception mechanism.
|
||||
case kvo
|
||||
}
|
||||
|
||||
/// RxCocoa ObjC runtime modification errors.
|
||||
public enum RxCocoaObjCRuntimeError
|
||||
: Swift.Error
|
||||
, CustomDebugStringConvertible {
|
||||
/// Unknown error has occurred.
|
||||
case unknown(target: AnyObject)
|
||||
|
||||
/**
|
||||
If the object is reporting a different class then it's real class, that means that there is probably
|
||||
already some interception mechanism in place or something weird is happening.
|
||||
|
||||
The most common case when this would happen is when using a combination of KVO (`observe`) and `sentMessage`.
|
||||
|
||||
This error is easily resolved by just using `sentMessage` observing before `observe`.
|
||||
|
||||
The reason why the other way around could create issues is because KVO will unregister it's interceptor
|
||||
class and restore original class. Unfortunately that will happen no matter was there another interceptor
|
||||
subclass registered in hierarchy or not.
|
||||
|
||||
Failure scenario:
|
||||
* KVO sets class to be `__KVO__OriginalClass` (subclass of `OriginalClass`)
|
||||
* `sentMessage` sets object class to be `_RX_namespace___KVO__OriginalClass` (subclass of `__KVO__OriginalClass`)
|
||||
* then unobserving with KVO will restore class to be `OriginalClass` -> failure point (possibly a bug in KVO)
|
||||
|
||||
The reason why changing order of observing works is because any interception method on unregistration
|
||||
should return object's original real class (if that doesn't happen then it's really easy to argue that's a bug
|
||||
in that interception mechanism).
|
||||
|
||||
This library won't remove registered interceptor even if there aren't any observers left because
|
||||
it's highly unlikely it would have any benefit in real world use cases, and it's even more
|
||||
dangerous.
|
||||
*/
|
||||
case objectMessagesAlreadyBeingIntercepted(target: AnyObject, interceptionMechanism: RxCocoaInterceptionMechanism)
|
||||
|
||||
/// Trying to observe messages for selector that isn't implemented.
|
||||
case selectorNotImplemented(target: AnyObject)
|
||||
|
||||
/// Core Foundation classes are usually toll free bridged. Those classes crash the program in case
|
||||
/// `object_setClass` is performed on them.
|
||||
///
|
||||
/// There is a possibility to just swizzle methods on original object, but since those won't be usual use
|
||||
/// cases for this library, then an error will just be reported for now.
|
||||
case cantInterceptCoreFoundationTollFreeBridgedObjects(target: AnyObject)
|
||||
|
||||
/// Two libraries have simultaneously tried to modify ObjC runtime and that was detected. This can only
|
||||
/// happen in scenarios where multiple interception libraries are used.
|
||||
///
|
||||
/// To synchronize other libraries intercepting messages for an object, use `synchronized` on target object and
|
||||
/// it's meta-class.
|
||||
case threadingCollisionWithOtherInterceptionMechanism(target: AnyObject)
|
||||
|
||||
/// For some reason saving original method implementation under RX namespace failed.
|
||||
case savingOriginalForwardingMethodFailed(target: AnyObject)
|
||||
|
||||
/// Intercepting a sent message by replacing a method implementation with `_objc_msgForward` failed for some reason.
|
||||
case replacingMethodWithForwardingImplementation(target: AnyObject)
|
||||
|
||||
/// Attempt to intercept one of the performance sensitive methods:
|
||||
/// * class
|
||||
/// * respondsToSelector:
|
||||
/// * methodSignatureForSelector:
|
||||
/// * forwardingTargetForSelector:
|
||||
case observingPerformanceSensitiveMessages(target: AnyObject)
|
||||
|
||||
/// Message implementation has unsupported return type (for example large struct). The reason why this is a error
|
||||
/// is because in some cases intercepting sent messages requires replacing implementation with `_objc_msgForward_stret`
|
||||
/// instead of `_objc_msgForward`.
|
||||
///
|
||||
/// The unsupported cases should be fairly uncommon.
|
||||
case observingMessagesWithUnsupportedReturnType(target: AnyObject)
|
||||
}
|
||||
|
||||
extension RxCocoaObjCRuntimeError {
|
||||
/// A textual representation of `self`, suitable for debugging.
|
||||
public var debugDescription: String {
|
||||
switch self {
|
||||
case let .unknown(target):
|
||||
return "Unknown error occurred.\nTarget: `\(target)`"
|
||||
case let .objectMessagesAlreadyBeingIntercepted(target, interceptionMechanism):
|
||||
let interceptionMechanismDescription = interceptionMechanism == .kvo ? "KVO" : "other interception mechanism"
|
||||
return "Collision between RxCocoa interception mechanism and \(interceptionMechanismDescription)."
|
||||
+ " To resolve this conflict please use this interception mechanism first.\nTarget: \(target)"
|
||||
case let .selectorNotImplemented(target):
|
||||
return "Trying to observe messages for selector that isn't implemented.\nTarget: \(target)"
|
||||
case let .cantInterceptCoreFoundationTollFreeBridgedObjects(target):
|
||||
return "Interception of messages sent to Core Foundation isn't supported.\nTarget: \(target)"
|
||||
case let .threadingCollisionWithOtherInterceptionMechanism(target):
|
||||
return "Detected a conflict while modifying ObjC runtime.\nTarget: \(target)"
|
||||
case let .savingOriginalForwardingMethodFailed(target):
|
||||
return "Saving original method implementation failed.\nTarget: \(target)"
|
||||
case let .replacingMethodWithForwardingImplementation(target):
|
||||
return "Intercepting a sent message by replacing a method implementation with `_objc_msgForward` failed for some reason.\nTarget: \(target)"
|
||||
case let .observingPerformanceSensitiveMessages(target):
|
||||
return "Attempt to intercept one of the performance sensitive methods. \nTarget: \(target)"
|
||||
case let .observingMessagesWithUnsupportedReturnType(target):
|
||||
return "Attempt to intercept a method with unsupported return type. \nTarget: \(target)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Conversions `NSError` > `RxCocoaObjCRuntimeError`
|
||||
|
||||
extension Error {
|
||||
func rxCocoaErrorForTarget(_ target: AnyObject) -> RxCocoaObjCRuntimeError {
|
||||
let error = self as NSError
|
||||
|
||||
if error.domain == RXObjCRuntimeErrorDomain {
|
||||
let errorCode = RXObjCRuntimeError(rawValue: error.code) ?? .unknown
|
||||
|
||||
switch errorCode {
|
||||
case .unknown:
|
||||
return .unknown(target: target)
|
||||
case .objectMessagesAlreadyBeingIntercepted:
|
||||
let isKVO = (error.userInfo[RXObjCRuntimeErrorIsKVOKey] as? NSNumber)?.boolValue ?? false
|
||||
return .objectMessagesAlreadyBeingIntercepted(target: target, interceptionMechanism: isKVO ? .kvo : .unknown)
|
||||
case .selectorNotImplemented:
|
||||
return .selectorNotImplemented(target: target)
|
||||
case .cantInterceptCoreFoundationTollFreeBridgedObjects:
|
||||
return .cantInterceptCoreFoundationTollFreeBridgedObjects(target: target)
|
||||
case .threadingCollisionWithOtherInterceptionMechanism:
|
||||
return .threadingCollisionWithOtherInterceptionMechanism(target: target)
|
||||
case .savingOriginalForwardingMethodFailed:
|
||||
return .savingOriginalForwardingMethodFailed(target: target)
|
||||
case .replacingMethodWithForwardingImplementation:
|
||||
return .replacingMethodWithForwardingImplementation(target: target)
|
||||
case .observingPerformanceSensitiveMessages:
|
||||
return .observingPerformanceSensitiveMessages(target: target)
|
||||
case .observingMessagesWithUnsupportedReturnType:
|
||||
return .observingMessagesWithUnsupportedReturnType(target: target)
|
||||
@unknown default:
|
||||
fatalError("Unhandled Objective C Runtime Error")
|
||||
}
|
||||
}
|
||||
|
||||
return RxCocoaObjCRuntimeError.unknown(target: target)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
43
Pods/RxCocoa/RxCocoa/Common/RxTarget.swift
generated
Normal file
43
Pods/RxCocoa/RxCocoa/Common/RxTarget.swift
generated
Normal file
@@ -0,0 +1,43 @@
|
||||
//
|
||||
// RxTarget.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 7/12/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
import RxSwift
|
||||
|
||||
class RxTarget : NSObject
|
||||
, Disposable {
|
||||
|
||||
private var retainSelf: RxTarget?
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
self.retainSelf = self
|
||||
|
||||
#if TRACE_RESOURCES
|
||||
_ = Resources.incrementTotal()
|
||||
#endif
|
||||
|
||||
#if DEBUG
|
||||
MainScheduler.ensureRunningOnMainThread()
|
||||
#endif
|
||||
}
|
||||
|
||||
func dispose() {
|
||||
#if DEBUG
|
||||
MainScheduler.ensureRunningOnMainThread()
|
||||
#endif
|
||||
self.retainSelf = nil
|
||||
}
|
||||
|
||||
#if TRACE_RESOURCES
|
||||
deinit {
|
||||
_ = Resources.decrementTotal()
|
||||
}
|
||||
#endif
|
||||
}
|
||||
20
Pods/RxCocoa/RxCocoa/Common/SectionedViewDataSourceType.swift
generated
Normal file
20
Pods/RxCocoa/RxCocoa/Common/SectionedViewDataSourceType.swift
generated
Normal file
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// SectionedViewDataSourceType.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 1/10/16.
|
||||
// Copyright © 2016 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
/// Data source with access to underlying sectioned model.
|
||||
public protocol SectionedViewDataSourceType {
|
||||
/// Returns model at index path.
|
||||
///
|
||||
/// In case data source doesn't contain any sections when this method is being called, `RxCocoaError.ItemsNotYetBound(object: self)` is thrown.
|
||||
|
||||
/// - parameter indexPath: Model index path
|
||||
/// - returns: Model at index path.
|
||||
func model(at indexPath: IndexPath) throws -> Any
|
||||
}
|
||||
78
Pods/RxCocoa/RxCocoa/Common/TextInput.swift
generated
Normal file
78
Pods/RxCocoa/RxCocoa/Common/TextInput.swift
generated
Normal file
@@ -0,0 +1,78 @@
|
||||
//
|
||||
// TextInput.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 5/12/16.
|
||||
// Copyright © 2016 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
import RxSwift
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
import UIKit
|
||||
|
||||
/// Represents text input with reactive extensions.
|
||||
public struct TextInput<Base: UITextInput> {
|
||||
/// Base text input to extend.
|
||||
public let base: Base
|
||||
|
||||
/// Reactive wrapper for `text` property.
|
||||
public let text: ControlProperty<String?>
|
||||
|
||||
/// Initializes new text input.
|
||||
///
|
||||
/// - parameter base: Base object.
|
||||
/// - parameter text: Textual control property.
|
||||
public init(base: Base, text: ControlProperty<String?>) {
|
||||
self.base = base
|
||||
self.text = text
|
||||
}
|
||||
}
|
||||
|
||||
extension Reactive where Base: UITextField {
|
||||
/// Reactive text input.
|
||||
public var textInput: TextInput<Base> {
|
||||
return TextInput(base: base, text: self.text)
|
||||
}
|
||||
}
|
||||
|
||||
extension Reactive where Base: UITextView {
|
||||
/// Reactive text input.
|
||||
public var textInput: TextInput<Base> {
|
||||
return TextInput(base: base, text: self.text)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if os(macOS)
|
||||
import Cocoa
|
||||
|
||||
/// Represents text input with reactive extensions.
|
||||
public struct TextInput<Base: NSTextInputClient> {
|
||||
/// Base text input to extend.
|
||||
public let base: Base
|
||||
|
||||
/// Reactive wrapper for `text` property.
|
||||
public let text: ControlProperty<String?>
|
||||
|
||||
/// Initializes new text input.
|
||||
///
|
||||
/// - parameter base: Base object.
|
||||
/// - parameter text: Textual control property.
|
||||
public init(base: Base, text: ControlProperty<String?>) {
|
||||
self.base = base
|
||||
self.text = text
|
||||
}
|
||||
}
|
||||
|
||||
extension Reactive where Base: NSTextField, Base: NSTextInputClient {
|
||||
/// Reactive text input.
|
||||
public var textInput: TextInput<Base> {
|
||||
return TextInput(base: self.base, text: self.text)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
68
Pods/RxCocoa/RxCocoa/Foundation/KVORepresentable+CoreGraphics.swift
generated
Normal file
68
Pods/RxCocoa/RxCocoa/Foundation/KVORepresentable+CoreGraphics.swift
generated
Normal file
@@ -0,0 +1,68 @@
|
||||
//
|
||||
// KVORepresentable+CoreGraphics.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 11/14/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if !os(Linux)
|
||||
|
||||
import RxSwift
|
||||
import CoreGraphics
|
||||
|
||||
import Foundation
|
||||
|
||||
#if arch(x86_64) || arch(arm64)
|
||||
let CGRectType = "{CGRect={CGPoint=dd}{CGSize=dd}}"
|
||||
let CGSizeType = "{CGSize=dd}"
|
||||
let CGPointType = "{CGPoint=dd}"
|
||||
#elseif arch(i386) || arch(arm) || os(watchOS)
|
||||
let CGRectType = "{CGRect={CGPoint=ff}{CGSize=ff}}"
|
||||
let CGSizeType = "{CGSize=ff}"
|
||||
let CGPointType = "{CGPoint=ff}"
|
||||
#endif
|
||||
|
||||
extension CGRect : KVORepresentable {
|
||||
public typealias KVOType = NSValue
|
||||
|
||||
/// Constructs self from `NSValue`.
|
||||
public init?(KVOValue: KVOType) {
|
||||
if strcmp(KVOValue.objCType, CGRectType) != 0 {
|
||||
return nil
|
||||
}
|
||||
var typedValue = CGRect(x: 0, y: 0, width: 0, height: 0)
|
||||
KVOValue.getValue(&typedValue)
|
||||
self = typedValue
|
||||
}
|
||||
}
|
||||
|
||||
extension CGPoint : KVORepresentable {
|
||||
public typealias KVOType = NSValue
|
||||
|
||||
/// Constructs self from `NSValue`.
|
||||
public init?(KVOValue: KVOType) {
|
||||
if strcmp(KVOValue.objCType, CGPointType) != 0 {
|
||||
return nil
|
||||
}
|
||||
var typedValue = CGPoint(x: 0, y: 0)
|
||||
KVOValue.getValue(&typedValue)
|
||||
self = typedValue
|
||||
}
|
||||
}
|
||||
|
||||
extension CGSize : KVORepresentable {
|
||||
public typealias KVOType = NSValue
|
||||
|
||||
/// Constructs self from `NSValue`.
|
||||
public init?(KVOValue: KVOType) {
|
||||
if strcmp(KVOValue.objCType, CGSizeType) != 0 {
|
||||
return nil
|
||||
}
|
||||
var typedValue = CGSize(width: 0, height: 0)
|
||||
KVOValue.getValue(&typedValue)
|
||||
self = typedValue
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
88
Pods/RxCocoa/RxCocoa/Foundation/KVORepresentable+Swift.swift
generated
Normal file
88
Pods/RxCocoa/RxCocoa/Foundation/KVORepresentable+Swift.swift
generated
Normal file
@@ -0,0 +1,88 @@
|
||||
//
|
||||
// KVORepresentable+Swift.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 11/14/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension Int : KVORepresentable {
|
||||
public typealias KVOType = NSNumber
|
||||
|
||||
/// Constructs `Self` using KVO value.
|
||||
public init?(KVOValue: KVOType) {
|
||||
self.init(KVOValue.int32Value)
|
||||
}
|
||||
}
|
||||
|
||||
extension Int32 : KVORepresentable {
|
||||
public typealias KVOType = NSNumber
|
||||
|
||||
/// Constructs `Self` using KVO value.
|
||||
public init?(KVOValue: KVOType) {
|
||||
self.init(KVOValue.int32Value)
|
||||
}
|
||||
}
|
||||
|
||||
extension Int64 : KVORepresentable {
|
||||
public typealias KVOType = NSNumber
|
||||
|
||||
/// Constructs `Self` using KVO value.
|
||||
public init?(KVOValue: KVOType) {
|
||||
self.init(KVOValue.int64Value)
|
||||
}
|
||||
}
|
||||
|
||||
extension UInt : KVORepresentable {
|
||||
public typealias KVOType = NSNumber
|
||||
|
||||
/// Constructs `Self` using KVO value.
|
||||
public init?(KVOValue: KVOType) {
|
||||
self.init(KVOValue.uintValue)
|
||||
}
|
||||
}
|
||||
|
||||
extension UInt32 : KVORepresentable {
|
||||
public typealias KVOType = NSNumber
|
||||
|
||||
/// Constructs `Self` using KVO value.
|
||||
public init?(KVOValue: KVOType) {
|
||||
self.init(KVOValue.uint32Value)
|
||||
}
|
||||
}
|
||||
|
||||
extension UInt64 : KVORepresentable {
|
||||
public typealias KVOType = NSNumber
|
||||
|
||||
/// Constructs `Self` using KVO value.
|
||||
public init?(KVOValue: KVOType) {
|
||||
self.init(KVOValue.uint64Value)
|
||||
}
|
||||
}
|
||||
|
||||
extension Bool : KVORepresentable {
|
||||
public typealias KVOType = NSNumber
|
||||
|
||||
/// Constructs `Self` using KVO value.
|
||||
public init?(KVOValue: KVOType) {
|
||||
self.init(KVOValue.boolValue)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extension RawRepresentable where RawValue: KVORepresentable {
|
||||
/// Constructs `Self` using optional KVO value.
|
||||
init?(KVOValue: RawValue.KVOType?) {
|
||||
guard let KVOValue = KVOValue else {
|
||||
return nil
|
||||
}
|
||||
|
||||
guard let rawValue = RawValue(KVOValue: KVOValue) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
self.init(rawValue: rawValue)
|
||||
}
|
||||
}
|
||||
28
Pods/RxCocoa/RxCocoa/Foundation/KVORepresentable.swift
generated
Normal file
28
Pods/RxCocoa/RxCocoa/Foundation/KVORepresentable.swift
generated
Normal file
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// KVORepresentable.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 11/14/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
/// Type that is KVO representable (KVO mechanism can be used to observe it).
|
||||
public protocol KVORepresentable {
|
||||
/// Associated KVO type.
|
||||
associatedtype KVOType
|
||||
|
||||
/// Constructs `Self` using KVO value.
|
||||
init?(KVOValue: KVOType)
|
||||
}
|
||||
|
||||
extension KVORepresentable {
|
||||
/// Initializes `KVORepresentable` with optional value.
|
||||
init?(KVOValue: KVOType?) {
|
||||
guard let KVOValue = KVOValue else {
|
||||
return nil
|
||||
}
|
||||
|
||||
self.init(KVOValue: KVOValue)
|
||||
}
|
||||
}
|
||||
|
||||
60
Pods/RxCocoa/RxCocoa/Foundation/NSObject+Rx+KVORepresentable.swift
generated
Normal file
60
Pods/RxCocoa/RxCocoa/Foundation/NSObject+Rx+KVORepresentable.swift
generated
Normal file
@@ -0,0 +1,60 @@
|
||||
//
|
||||
// NSObject+Rx+KVORepresentable.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 11/14/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if !os(Linux)
|
||||
|
||||
import Foundation
|
||||
import RxSwift
|
||||
|
||||
/// Key value observing options
|
||||
public struct KeyValueObservingOptions: OptionSet {
|
||||
/// Raw value
|
||||
public let rawValue: UInt
|
||||
|
||||
public init(rawValue: UInt) {
|
||||
self.rawValue = rawValue
|
||||
}
|
||||
|
||||
/// Whether a sequence element should be sent to the observer immediately, before the subscribe method even returns.
|
||||
public static let initial = KeyValueObservingOptions(rawValue: 1 << 0)
|
||||
/// Whether to send updated values.
|
||||
public static let new = KeyValueObservingOptions(rawValue: 1 << 1)
|
||||
}
|
||||
|
||||
extension Reactive where Base: NSObject {
|
||||
|
||||
/**
|
||||
Specialization of generic `observe` method.
|
||||
|
||||
This is a special overload because to observe values of some type (for example `Int`), first values of KVO type
|
||||
need to be observed (`NSNumber`), and then converted to result type.
|
||||
|
||||
For more information take a look at `observe` method.
|
||||
*/
|
||||
public func observe<Element: KVORepresentable>(_ type: Element.Type, _ keyPath: String, options: KeyValueObservingOptions = [.new, .initial], retainSelf: Bool = true) -> Observable<Element?> {
|
||||
return self.observe(Element.KVOType.self, keyPath, options: options, retainSelf: retainSelf)
|
||||
.map(Element.init)
|
||||
}
|
||||
}
|
||||
|
||||
#if !DISABLE_SWIZZLING && !os(Linux)
|
||||
// KVO
|
||||
extension Reactive where Base: NSObject {
|
||||
/**
|
||||
Specialization of generic `observeWeakly` method.
|
||||
|
||||
For more information take a look at `observeWeakly` method.
|
||||
*/
|
||||
public func observeWeakly<Element: KVORepresentable>(_ type: Element.Type, _ keyPath: String, options: KeyValueObservingOptions = [.new, .initial]) -> Observable<Element?> {
|
||||
return self.observeWeakly(Element.KVOType.self, keyPath, options: options)
|
||||
.map(Element.init)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
52
Pods/RxCocoa/RxCocoa/Foundation/NSObject+Rx+RawRepresentable.swift
generated
Normal file
52
Pods/RxCocoa/RxCocoa/Foundation/NSObject+Rx+RawRepresentable.swift
generated
Normal file
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// NSObject+Rx+RawRepresentable.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 11/9/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if !os(Linux)
|
||||
|
||||
import RxSwift
|
||||
|
||||
import Foundation
|
||||
|
||||
extension Reactive where Base: NSObject {
|
||||
/**
|
||||
Specialization of generic `observe` method.
|
||||
|
||||
This specialization first observes `KVORepresentable` value and then converts it to `RawRepresentable` value.
|
||||
|
||||
It is useful for observing bridged ObjC enum values.
|
||||
|
||||
For more information take a look at `observe` method.
|
||||
*/
|
||||
public func observe<Element: RawRepresentable>(_ type: Element.Type, _ keyPath: String, options: KeyValueObservingOptions = [.new, .initial], retainSelf: Bool = true) -> Observable<Element?> where Element.RawValue: KVORepresentable {
|
||||
return self.observe(Element.RawValue.KVOType.self, keyPath, options: options, retainSelf: retainSelf)
|
||||
.map(Element.init)
|
||||
}
|
||||
}
|
||||
|
||||
#if !DISABLE_SWIZZLING
|
||||
|
||||
// observeWeakly + RawRepresentable
|
||||
extension Reactive where Base: NSObject {
|
||||
|
||||
/**
|
||||
Specialization of generic `observeWeakly` method.
|
||||
|
||||
This specialization first observes `KVORepresentable` value and then converts it to `RawRepresentable` value.
|
||||
|
||||
It is useful for observing bridged ObjC enum values.
|
||||
|
||||
For more information take a look at `observeWeakly` method.
|
||||
*/
|
||||
public func observeWeakly<Element: RawRepresentable>(_ type: Element.Type, _ keyPath: String, options: KeyValueObservingOptions = [.new, .initial]) -> Observable<Element?> where Element.RawValue: KVORepresentable {
|
||||
return self.observeWeakly(Element.RawValue.KVOType.self, keyPath, options: options)
|
||||
.map(Element.init)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
569
Pods/RxCocoa/RxCocoa/Foundation/NSObject+Rx.swift
generated
Normal file
569
Pods/RxCocoa/RxCocoa/Foundation/NSObject+Rx.swift
generated
Normal file
@@ -0,0 +1,569 @@
|
||||
//
|
||||
// NSObject+Rx.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 2/21/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if !os(Linux)
|
||||
|
||||
import Foundation
|
||||
import RxSwift
|
||||
#if SWIFT_PACKAGE && !DISABLE_SWIZZLING && !os(Linux)
|
||||
import RxCocoaRuntime
|
||||
#endif
|
||||
|
||||
#if !DISABLE_SWIZZLING && !os(Linux)
|
||||
private var deallocatingSubjectTriggerContext: UInt8 = 0
|
||||
private var deallocatingSubjectContext: UInt8 = 0
|
||||
#endif
|
||||
private var deallocatedSubjectTriggerContext: UInt8 = 0
|
||||
private var deallocatedSubjectContext: UInt8 = 0
|
||||
|
||||
#if !os(Linux)
|
||||
|
||||
/**
|
||||
KVO is a tricky mechanism.
|
||||
|
||||
When observing child in a ownership hierarchy, usually retaining observing target is wanted behavior.
|
||||
When observing parent in a ownership hierarchy, usually retaining target isn't wanter behavior.
|
||||
|
||||
KVO with weak references is especially tricky. For it to work, some kind of swizzling is required.
|
||||
That can be done by
|
||||
* replacing object class dynamically (like KVO does)
|
||||
* by swizzling `dealloc` method on all instances for a class.
|
||||
* some third method ...
|
||||
|
||||
Both approaches can fail in certain scenarios:
|
||||
* problems arise when swizzlers return original object class (like KVO does when nobody is observing)
|
||||
* Problems can arise because replacing dealloc method isn't atomic operation (get implementation,
|
||||
set implementation).
|
||||
|
||||
Second approach is chosen. It can fail in case there are multiple libraries dynamically trying
|
||||
to replace dealloc method. In case that isn't the case, it should be ok.
|
||||
*/
|
||||
extension Reactive where Base: NSObject {
|
||||
|
||||
|
||||
/**
|
||||
Observes values on `keyPath` starting from `self` with `options` and retains `self` if `retainSelf` is set.
|
||||
|
||||
`observe` is just a simple and performant wrapper around KVO mechanism.
|
||||
|
||||
* it can be used to observe paths starting from `self` or from ancestors in ownership graph (`retainSelf = false`)
|
||||
* it can be used to observe paths starting from descendants in ownership graph (`retainSelf = true`)
|
||||
* the paths have to consist only of `strong` properties, otherwise you are risking crashing the system by not unregistering KVO observer before dealloc.
|
||||
|
||||
If support for weak properties is needed or observing arbitrary or unknown relationships in the
|
||||
ownership tree, `observeWeakly` is the preferred option.
|
||||
- parameter type: Optional type hint of the observed sequence elements.
|
||||
- parameter keyPath: Key path of property names to observe.
|
||||
- parameter options: KVO mechanism notification options.
|
||||
- parameter retainSelf: Retains self during observation if set `true`.
|
||||
- returns: Observable sequence of objects on `keyPath`.
|
||||
*/
|
||||
public func observe<Element>(_ type: Element.Type,
|
||||
_ keyPath: String,
|
||||
options: KeyValueObservingOptions = [.new, .initial],
|
||||
retainSelf: Bool = true) -> Observable<Element?> {
|
||||
KVOObservable(object: self.base, keyPath: keyPath, options: options, retainTarget: retainSelf).asObservable()
|
||||
}
|
||||
|
||||
/**
|
||||
Observes values at the provided key path using the provided options.
|
||||
|
||||
- parameter keyPath: A key path between the object and one of its properties.
|
||||
- parameter options: Key-value observation options, defaults to `.new` and `.initial`.
|
||||
|
||||
- note: When the object is deallocated, a completion event is emitted.
|
||||
|
||||
- returns: An observable emitting value changes at the provided key path.
|
||||
*/
|
||||
public func observe<Element>(_ keyPath: KeyPath<Base, Element>,
|
||||
options: NSKeyValueObservingOptions = [.new, .initial]) -> Observable<Element> {
|
||||
Observable<Element>.create { [weak base] observer in
|
||||
let observation = base?.observe(keyPath, options: options) { obj, _ in
|
||||
observer.on(.next(obj[keyPath: keyPath]))
|
||||
}
|
||||
|
||||
return Disposables.create { observation?.invalidate() }
|
||||
}
|
||||
.take(until: base.rx.deallocated)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if !DISABLE_SWIZZLING && !os(Linux)
|
||||
// KVO
|
||||
extension Reactive where Base: NSObject {
|
||||
/**
|
||||
Observes values on `keyPath` starting from `self` with `options` and doesn't retain `self`.
|
||||
|
||||
It can be used in all cases where `observe` can be used and additionally
|
||||
|
||||
* because it won't retain observed target, it can be used to observe arbitrary object graph whose ownership relation is unknown
|
||||
* it can be used to observe `weak` properties
|
||||
|
||||
**Since it needs to intercept object deallocation process it needs to perform swizzling of `dealloc` method on observed object.**
|
||||
- parameter type: Optional type hint of the observed sequence elements.
|
||||
- parameter keyPath: Key path of property names to observe.
|
||||
- parameter options: KVO mechanism notification options.
|
||||
- returns: Observable sequence of objects on `keyPath`.
|
||||
*/
|
||||
public func observeWeakly<Element>(_ type: Element.Type, _ keyPath: String, options: KeyValueObservingOptions = [.new, .initial]) -> Observable<Element?> {
|
||||
return observeWeaklyKeyPathFor(self.base, keyPath: keyPath, options: options)
|
||||
.map { n in
|
||||
return n as? Element
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Dealloc
|
||||
extension Reactive where Base: AnyObject {
|
||||
|
||||
/**
|
||||
Observable sequence of object deallocated events.
|
||||
|
||||
After object is deallocated one `()` element will be produced and sequence will immediately complete.
|
||||
|
||||
- returns: Observable sequence of object deallocated events.
|
||||
*/
|
||||
public var deallocated: Observable<Void> {
|
||||
return self.synchronized {
|
||||
if let deallocObservable = objc_getAssociatedObject(self.base, &deallocatedSubjectContext) as? DeallocObservable {
|
||||
return deallocObservable.subject
|
||||
}
|
||||
|
||||
let deallocObservable = DeallocObservable()
|
||||
|
||||
objc_setAssociatedObject(self.base, &deallocatedSubjectContext, deallocObservable, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
|
||||
return deallocObservable.subject
|
||||
}
|
||||
}
|
||||
|
||||
#if !DISABLE_SWIZZLING && !os(Linux)
|
||||
|
||||
/**
|
||||
Observable sequence of message arguments that completes when object is deallocated.
|
||||
|
||||
Each element is produced before message is invoked on target object. `methodInvoked`
|
||||
exists in case observing of invoked messages is needed.
|
||||
|
||||
In case an error occurs sequence will fail with `RxCocoaObjCRuntimeError`.
|
||||
|
||||
In case some argument is `nil`, instance of `NSNull()` will be sent.
|
||||
|
||||
- returns: Observable sequence of arguments passed to `selector` method.
|
||||
*/
|
||||
public func sentMessage(_ selector: Selector) -> Observable<[Any]> {
|
||||
return self.synchronized {
|
||||
// in case of dealloc selector replay subject behavior needs to be used
|
||||
if selector == deallocSelector {
|
||||
return self.deallocating.map { _ in [] }
|
||||
}
|
||||
|
||||
do {
|
||||
let proxy: MessageSentProxy = try self.registerMessageInterceptor(selector)
|
||||
return proxy.messageSent.asObservable()
|
||||
}
|
||||
catch let e {
|
||||
return Observable.error(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Observable sequence of message arguments that completes when object is deallocated.
|
||||
|
||||
Each element is produced after message is invoked on target object. `sentMessage`
|
||||
exists in case interception of sent messages before they were invoked is needed.
|
||||
|
||||
In case an error occurs sequence will fail with `RxCocoaObjCRuntimeError`.
|
||||
|
||||
In case some argument is `nil`, instance of `NSNull()` will be sent.
|
||||
|
||||
- returns: Observable sequence of arguments passed to `selector` method.
|
||||
*/
|
||||
public func methodInvoked(_ selector: Selector) -> Observable<[Any]> {
|
||||
return self.synchronized {
|
||||
// in case of dealloc selector replay subject behavior needs to be used
|
||||
if selector == deallocSelector {
|
||||
return self.deallocated.map { _ in [] }
|
||||
}
|
||||
|
||||
|
||||
do {
|
||||
let proxy: MessageSentProxy = try self.registerMessageInterceptor(selector)
|
||||
return proxy.methodInvoked.asObservable()
|
||||
}
|
||||
catch let e {
|
||||
return Observable.error(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Observable sequence of object deallocating events.
|
||||
|
||||
When `dealloc` message is sent to `self` one `()` element will be produced and after object is deallocated sequence
|
||||
will immediately complete.
|
||||
|
||||
In case an error occurs sequence will fail with `RxCocoaObjCRuntimeError`.
|
||||
|
||||
- returns: Observable sequence of object deallocating events.
|
||||
*/
|
||||
public var deallocating: Observable<()> {
|
||||
return self.synchronized {
|
||||
do {
|
||||
let proxy: DeallocatingProxy = try self.registerMessageInterceptor(deallocSelector)
|
||||
return proxy.messageSent.asObservable()
|
||||
}
|
||||
catch let e {
|
||||
return Observable.error(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func registerMessageInterceptor<T: MessageInterceptorSubject>(_ selector: Selector) throws -> T {
|
||||
let rxSelector = RX_selector(selector)
|
||||
let selectorReference = RX_reference_from_selector(rxSelector)
|
||||
|
||||
let subject: T
|
||||
if let existingSubject = objc_getAssociatedObject(self.base, selectorReference) as? T {
|
||||
subject = existingSubject
|
||||
}
|
||||
else {
|
||||
subject = T()
|
||||
objc_setAssociatedObject(
|
||||
self.base,
|
||||
selectorReference,
|
||||
subject,
|
||||
.OBJC_ASSOCIATION_RETAIN_NONATOMIC
|
||||
)
|
||||
}
|
||||
|
||||
if subject.isActive {
|
||||
return subject
|
||||
}
|
||||
|
||||
var error: NSError?
|
||||
let targetImplementation = RX_ensure_observing(self.base, selector, &error)
|
||||
if targetImplementation == nil {
|
||||
throw error?.rxCocoaErrorForTarget(self.base) ?? RxCocoaError.unknown
|
||||
}
|
||||
|
||||
subject.targetImplementation = targetImplementation!
|
||||
|
||||
return subject
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// MARK: Message interceptors
|
||||
|
||||
#if !DISABLE_SWIZZLING && !os(Linux)
|
||||
|
||||
private protocol MessageInterceptorSubject: AnyObject {
|
||||
init()
|
||||
|
||||
var isActive: Bool {
|
||||
get
|
||||
}
|
||||
|
||||
var targetImplementation: IMP { get set }
|
||||
}
|
||||
|
||||
private final class DeallocatingProxy
|
||||
: MessageInterceptorSubject
|
||||
, RXDeallocatingObserver {
|
||||
typealias Element = ()
|
||||
|
||||
let messageSent = ReplaySubject<()>.create(bufferSize: 1)
|
||||
|
||||
@objc var targetImplementation: IMP = RX_default_target_implementation()
|
||||
|
||||
var isActive: Bool {
|
||||
return self.targetImplementation != RX_default_target_implementation()
|
||||
}
|
||||
|
||||
init() {
|
||||
}
|
||||
|
||||
@objc func deallocating() {
|
||||
self.messageSent.on(.next(()))
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.messageSent.on(.completed)
|
||||
}
|
||||
}
|
||||
|
||||
private final class MessageSentProxy
|
||||
: MessageInterceptorSubject
|
||||
, RXMessageSentObserver {
|
||||
typealias Element = [AnyObject]
|
||||
|
||||
let messageSent = PublishSubject<[Any]>()
|
||||
let methodInvoked = PublishSubject<[Any]>()
|
||||
|
||||
@objc var targetImplementation: IMP = RX_default_target_implementation()
|
||||
|
||||
var isActive: Bool {
|
||||
return self.targetImplementation != RX_default_target_implementation()
|
||||
}
|
||||
|
||||
init() {
|
||||
}
|
||||
|
||||
@objc func messageSent(withArguments arguments: [Any]) {
|
||||
self.messageSent.on(.next(arguments))
|
||||
}
|
||||
|
||||
@objc func methodInvoked(withArguments arguments: [Any]) {
|
||||
self.methodInvoked.on(.next(arguments))
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.messageSent.on(.completed)
|
||||
self.methodInvoked.on(.completed)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
private final class DeallocObservable {
|
||||
let subject = ReplaySubject<Void>.create(bufferSize:1)
|
||||
|
||||
init() {
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.subject.on(.next(()))
|
||||
self.subject.on(.completed)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: KVO
|
||||
|
||||
#if !os(Linux)
|
||||
|
||||
private protocol KVOObservableProtocol {
|
||||
var target: AnyObject { get }
|
||||
var keyPath: String { get }
|
||||
var retainTarget: Bool { get }
|
||||
var options: KeyValueObservingOptions { get }
|
||||
}
|
||||
|
||||
private final class KVOObserver
|
||||
: _RXKVOObserver
|
||||
, Disposable {
|
||||
typealias Callback = (Any?) -> Void
|
||||
|
||||
var retainSelf: KVOObserver?
|
||||
|
||||
init(parent: KVOObservableProtocol, callback: @escaping Callback) {
|
||||
#if TRACE_RESOURCES
|
||||
_ = Resources.incrementTotal()
|
||||
#endif
|
||||
|
||||
super.init(target: parent.target, retainTarget: parent.retainTarget, keyPath: parent.keyPath, options: parent.options.nsOptions, callback: callback)
|
||||
self.retainSelf = self
|
||||
}
|
||||
|
||||
override func dispose() {
|
||||
super.dispose()
|
||||
self.retainSelf = nil
|
||||
}
|
||||
|
||||
deinit {
|
||||
#if TRACE_RESOURCES
|
||||
_ = Resources.decrementTotal()
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
private final class KVOObservable<Element>
|
||||
: ObservableType
|
||||
, KVOObservableProtocol {
|
||||
typealias Element = Element?
|
||||
|
||||
unowned var target: AnyObject
|
||||
var strongTarget: AnyObject?
|
||||
|
||||
var keyPath: String
|
||||
var options: KeyValueObservingOptions
|
||||
var retainTarget: Bool
|
||||
|
||||
init(object: AnyObject, keyPath: String, options: KeyValueObservingOptions, retainTarget: Bool) {
|
||||
self.target = object
|
||||
self.keyPath = keyPath
|
||||
self.options = options
|
||||
self.retainTarget = retainTarget
|
||||
if retainTarget {
|
||||
self.strongTarget = object
|
||||
}
|
||||
}
|
||||
|
||||
func subscribe<Observer: ObserverType>(_ observer: Observer) -> Disposable where Observer.Element == Element? {
|
||||
let observer = KVOObserver(parent: self) { value in
|
||||
if value as? NSNull != nil {
|
||||
observer.on(.next(nil))
|
||||
return
|
||||
}
|
||||
observer.on(.next(value as? Element))
|
||||
}
|
||||
|
||||
return Disposables.create(with: observer.dispose)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private extension KeyValueObservingOptions {
|
||||
var nsOptions: NSKeyValueObservingOptions {
|
||||
var result: UInt = 0
|
||||
if self.contains(.new) {
|
||||
result |= NSKeyValueObservingOptions.new.rawValue
|
||||
}
|
||||
if self.contains(.initial) {
|
||||
result |= NSKeyValueObservingOptions.initial.rawValue
|
||||
}
|
||||
|
||||
return NSKeyValueObservingOptions(rawValue: result)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if !DISABLE_SWIZZLING && !os(Linux)
|
||||
|
||||
private func observeWeaklyKeyPathFor(_ target: NSObject, keyPath: String, options: KeyValueObservingOptions) -> Observable<AnyObject?> {
|
||||
let components = keyPath.components(separatedBy: ".").filter { $0 != "self" }
|
||||
|
||||
let observable = observeWeaklyKeyPathFor(target, keyPathSections: components, options: options)
|
||||
.finishWithNilWhenDealloc(target)
|
||||
|
||||
if !options.isDisjoint(with: .initial) {
|
||||
return observable
|
||||
}
|
||||
else {
|
||||
return observable
|
||||
.skip(1)
|
||||
}
|
||||
}
|
||||
|
||||
// This should work correctly
|
||||
// Identifiers can't contain `,`, so the only place where `,` can appear
|
||||
// is as a delimiter.
|
||||
// This means there is `W` as element in an array of property attributes.
|
||||
private func isWeakProperty(_ properyRuntimeInfo: String) -> Bool {
|
||||
properyRuntimeInfo.range(of: ",W,") != nil
|
||||
}
|
||||
|
||||
private extension ObservableType where Element == AnyObject? {
|
||||
func finishWithNilWhenDealloc(_ target: NSObject)
|
||||
-> Observable<AnyObject?> {
|
||||
let deallocating = target.rx.deallocating
|
||||
|
||||
return deallocating
|
||||
.map { _ in
|
||||
return Observable.just(nil)
|
||||
}
|
||||
.startWith(self.asObservable())
|
||||
.switchLatest()
|
||||
}
|
||||
}
|
||||
|
||||
private func observeWeaklyKeyPathFor(
|
||||
_ target: NSObject,
|
||||
keyPathSections: [String],
|
||||
options: KeyValueObservingOptions
|
||||
) -> Observable<AnyObject?> {
|
||||
|
||||
weak var weakTarget: AnyObject? = target
|
||||
|
||||
let propertyName = keyPathSections[0]
|
||||
let remainingPaths = Array(keyPathSections[1..<keyPathSections.count])
|
||||
|
||||
let property = class_getProperty(object_getClass(target), propertyName)
|
||||
if property == nil {
|
||||
return Observable.error(RxCocoaError.invalidPropertyName(object: target, propertyName: propertyName))
|
||||
}
|
||||
let propertyAttributes = property_getAttributes(property!)
|
||||
|
||||
// should dealloc hook be in place if week property, or just create strong reference because it doesn't matter
|
||||
let isWeak = isWeakProperty(propertyAttributes.map(String.init) ?? "")
|
||||
let propertyObservable = KVOObservable(object: target, keyPath: propertyName, options: options.union(.initial), retainTarget: false) as KVOObservable<AnyObject>
|
||||
|
||||
// KVO recursion for value changes
|
||||
return propertyObservable
|
||||
.flatMapLatest { (nextTarget: AnyObject?) -> Observable<AnyObject?> in
|
||||
if nextTarget == nil {
|
||||
return Observable.just(nil)
|
||||
}
|
||||
let nextObject = nextTarget! as? NSObject
|
||||
|
||||
let strongTarget: AnyObject? = weakTarget
|
||||
|
||||
if nextObject == nil {
|
||||
return Observable.error(RxCocoaError.invalidObjectOnKeyPath(object: nextTarget!, sourceObject: strongTarget ?? NSNull(), propertyName: propertyName))
|
||||
}
|
||||
|
||||
// if target is alive, then send change
|
||||
// if it's deallocated, don't send anything
|
||||
if strongTarget == nil {
|
||||
return Observable.empty()
|
||||
}
|
||||
|
||||
let nextElementsObservable = keyPathSections.count == 1
|
||||
? Observable.just(nextTarget)
|
||||
: observeWeaklyKeyPathFor(nextObject!, keyPathSections: remainingPaths, options: options)
|
||||
|
||||
if isWeak {
|
||||
return nextElementsObservable
|
||||
.finishWithNilWhenDealloc(nextObject!)
|
||||
}
|
||||
else {
|
||||
return nextElementsObservable
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// MARK: Constants
|
||||
|
||||
private let deallocSelector = NSSelectorFromString("dealloc")
|
||||
|
||||
// MARK: AnyObject + Reactive
|
||||
|
||||
extension Reactive where Base: AnyObject {
|
||||
func synchronized<T>( _ action: () -> T) -> T {
|
||||
objc_sync_enter(self.base)
|
||||
let result = action()
|
||||
objc_sync_exit(self.base)
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
extension Reactive where Base: AnyObject {
|
||||
/**
|
||||
Helper to make sure that `Observable` returned from `createCachedObservable` is only created once.
|
||||
This is important because there is only one `target` and `action` properties on `NSControl` or `UIBarButtonItem`.
|
||||
*/
|
||||
func lazyInstanceObservable<T: AnyObject>(_ key: UnsafeRawPointer, createCachedObservable: () -> T) -> T {
|
||||
if let value = objc_getAssociatedObject(self.base, key) {
|
||||
return value as! T
|
||||
}
|
||||
|
||||
let observable = createCachedObservable()
|
||||
|
||||
objc_setAssociatedObject(self.base, key, observable, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
|
||||
|
||||
return observable
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
31
Pods/RxCocoa/RxCocoa/Foundation/NotificationCenter+Rx.swift
generated
Normal file
31
Pods/RxCocoa/RxCocoa/Foundation/NotificationCenter+Rx.swift
generated
Normal file
@@ -0,0 +1,31 @@
|
||||
//
|
||||
// NotificationCenter+Rx.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 5/2/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import RxSwift
|
||||
|
||||
extension Reactive where Base: NotificationCenter {
|
||||
/**
|
||||
Transforms notifications posted to notification center to observable sequence of notifications.
|
||||
|
||||
- parameter name: Optional name used to filter notifications.
|
||||
- parameter object: Optional object used to filter notifications.
|
||||
- returns: Observable sequence of posted notifications.
|
||||
*/
|
||||
public func notification(_ name: Notification.Name?, object: AnyObject? = nil) -> Observable<Notification> {
|
||||
return Observable.create { [weak object] observer in
|
||||
let nsObserver = self.base.addObserver(forName: name, object: object, queue: nil) { notification in
|
||||
observer.on(.next(notification))
|
||||
}
|
||||
|
||||
return Disposables.create {
|
||||
self.base.removeObserver(nsObserver)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
240
Pods/RxCocoa/RxCocoa/Foundation/URLSession+Rx.swift
generated
Normal file
240
Pods/RxCocoa/RxCocoa/Foundation/URLSession+Rx.swift
generated
Normal file
@@ -0,0 +1,240 @@
|
||||
//
|
||||
// URLSession+Rx.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 3/23/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import RxSwift
|
||||
|
||||
#if canImport(FoundationNetworking)
|
||||
import FoundationNetworking
|
||||
#endif
|
||||
|
||||
/// RxCocoa URL errors.
|
||||
public enum RxCocoaURLError
|
||||
: Swift.Error {
|
||||
/// Unknown error occurred.
|
||||
case unknown
|
||||
/// Response is not NSHTTPURLResponse
|
||||
case nonHTTPResponse(response: URLResponse)
|
||||
/// Response is not successful. (not in `200 ..< 300` range)
|
||||
case httpRequestFailed(response: HTTPURLResponse, data: Data?)
|
||||
/// Deserialization error.
|
||||
case deserializationError(error: Swift.Error)
|
||||
}
|
||||
|
||||
extension RxCocoaURLError
|
||||
: CustomDebugStringConvertible {
|
||||
/// A textual representation of `self`, suitable for debugging.
|
||||
public var debugDescription: String {
|
||||
switch self {
|
||||
case .unknown:
|
||||
return "Unknown error has occurred."
|
||||
case let .nonHTTPResponse(response):
|
||||
return "Response is not NSHTTPURLResponse `\(response)`."
|
||||
case let .httpRequestFailed(response, _):
|
||||
return "HTTP request failed with `\(response.statusCode)`."
|
||||
case let .deserializationError(error):
|
||||
return "Error during deserialization of the response: \(error)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func escapeTerminalString(_ value: String) -> String {
|
||||
return value.replacingOccurrences(of: "\"", with: "\\\"", options:[], range: nil)
|
||||
}
|
||||
|
||||
private func convertURLRequestToCurlCommand(_ request: URLRequest) -> String {
|
||||
let method = request.httpMethod ?? "GET"
|
||||
var returnValue = "curl -X \(method) "
|
||||
|
||||
if let httpBody = request.httpBody {
|
||||
let maybeBody = String(data: httpBody, encoding: String.Encoding.utf8)
|
||||
if let body = maybeBody {
|
||||
returnValue += "-d \"\(escapeTerminalString(body))\" "
|
||||
}
|
||||
}
|
||||
|
||||
for (key, value) in request.allHTTPHeaderFields ?? [:] {
|
||||
let escapedKey = escapeTerminalString(key as String)
|
||||
let escapedValue = escapeTerminalString(value as String)
|
||||
returnValue += "\n -H \"\(escapedKey): \(escapedValue)\" "
|
||||
}
|
||||
|
||||
let URLString = request.url?.absoluteString ?? "<unknown url>"
|
||||
|
||||
returnValue += "\n\"\(escapeTerminalString(URLString))\""
|
||||
|
||||
returnValue += " -i -v"
|
||||
|
||||
return returnValue
|
||||
}
|
||||
|
||||
private func convertResponseToString(_ response: URLResponse?, _ error: NSError?, _ interval: TimeInterval) -> String {
|
||||
let ms = Int(interval * 1000)
|
||||
|
||||
if let response = response as? HTTPURLResponse {
|
||||
if 200 ..< 300 ~= response.statusCode {
|
||||
return "Success (\(ms)ms): Status \(response.statusCode)"
|
||||
}
|
||||
else {
|
||||
return "Failure (\(ms)ms): Status \(response.statusCode)"
|
||||
}
|
||||
}
|
||||
|
||||
if let error = error {
|
||||
if error.domain == NSURLErrorDomain && error.code == NSURLErrorCancelled {
|
||||
return "Canceled (\(ms)ms)"
|
||||
}
|
||||
return "Failure (\(ms)ms): NSError > \(error)"
|
||||
}
|
||||
|
||||
return "<Unhandled response from server>"
|
||||
}
|
||||
|
||||
extension Reactive where Base: URLSession {
|
||||
/**
|
||||
Observable sequence of responses for URL request.
|
||||
|
||||
Performing of request starts after observer is subscribed and not after invoking this method.
|
||||
|
||||
**URL requests will be performed per subscribed observer.**
|
||||
|
||||
Any error during fetching of the response will cause observed sequence to terminate with error.
|
||||
|
||||
- parameter request: URL request.
|
||||
- returns: Observable sequence of URL responses.
|
||||
*/
|
||||
public func response(request: URLRequest) -> Observable<(response: HTTPURLResponse, data: Data)> {
|
||||
return Observable.create { observer in
|
||||
|
||||
// smart compiler should be able to optimize this out
|
||||
let d: Date?
|
||||
|
||||
if URLSession.rx.shouldLogRequest(request) {
|
||||
d = Date()
|
||||
}
|
||||
else {
|
||||
d = nil
|
||||
}
|
||||
|
||||
let task = self.base.dataTask(with: request) { data, response, error in
|
||||
|
||||
if URLSession.rx.shouldLogRequest(request) {
|
||||
let interval = Date().timeIntervalSince(d ?? Date())
|
||||
print(convertURLRequestToCurlCommand(request))
|
||||
#if os(Linux)
|
||||
print(convertResponseToString(response, error.flatMap { $0 as NSError }, interval))
|
||||
#else
|
||||
print(convertResponseToString(response, error.map { $0 as NSError }, interval))
|
||||
#endif
|
||||
}
|
||||
|
||||
guard let response = response, let data = data else {
|
||||
observer.on(.error(error ?? RxCocoaURLError.unknown))
|
||||
return
|
||||
}
|
||||
|
||||
guard let httpResponse = response as? HTTPURLResponse else {
|
||||
observer.on(.error(RxCocoaURLError.nonHTTPResponse(response: response)))
|
||||
return
|
||||
}
|
||||
|
||||
observer.on(.next((httpResponse, data)))
|
||||
observer.on(.completed)
|
||||
}
|
||||
|
||||
task.resume()
|
||||
|
||||
return Disposables.create(with: task.cancel)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Observable sequence of response data for URL request.
|
||||
|
||||
Performing of request starts after observer is subscribed and not after invoking this method.
|
||||
|
||||
**URL requests will be performed per subscribed observer.**
|
||||
|
||||
Any error during fetching of the response will cause observed sequence to terminate with error.
|
||||
|
||||
If response is not HTTP response with status code in the range of `200 ..< 300`, sequence
|
||||
will terminate with `(RxCocoaErrorDomain, RxCocoaError.NetworkError)`.
|
||||
|
||||
- parameter request: URL request.
|
||||
- returns: Observable sequence of response data.
|
||||
*/
|
||||
public func data(request: URLRequest) -> Observable<Data> {
|
||||
return self.response(request: request).map { pair -> Data in
|
||||
if 200 ..< 300 ~= pair.0.statusCode {
|
||||
return pair.1
|
||||
}
|
||||
else {
|
||||
throw RxCocoaURLError.httpRequestFailed(response: pair.0, data: pair.1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Observable sequence of response JSON for URL request.
|
||||
|
||||
Performing of request starts after observer is subscribed and not after invoking this method.
|
||||
|
||||
**URL requests will be performed per subscribed observer.**
|
||||
|
||||
Any error during fetching of the response will cause observed sequence to terminate with error.
|
||||
|
||||
If response is not HTTP response with status code in the range of `200 ..< 300`, sequence
|
||||
will terminate with `(RxCocoaErrorDomain, RxCocoaError.NetworkError)`.
|
||||
|
||||
If there is an error during JSON deserialization observable sequence will fail with that error.
|
||||
|
||||
- parameter request: URL request.
|
||||
- returns: Observable sequence of response JSON.
|
||||
*/
|
||||
public func json(request: URLRequest, options: JSONSerialization.ReadingOptions = []) -> Observable<Any> {
|
||||
return self.data(request: request).map { data -> Any in
|
||||
do {
|
||||
return try JSONSerialization.jsonObject(with: data, options: options)
|
||||
} catch let error {
|
||||
throw RxCocoaURLError.deserializationError(error: error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Observable sequence of response JSON for GET request with `URL`.
|
||||
|
||||
Performing of request starts after observer is subscribed and not after invoking this method.
|
||||
|
||||
**URL requests will be performed per subscribed observer.**
|
||||
|
||||
Any error during fetching of the response will cause observed sequence to terminate with error.
|
||||
|
||||
If response is not HTTP response with status code in the range of `200 ..< 300`, sequence
|
||||
will terminate with `(RxCocoaErrorDomain, RxCocoaError.NetworkError)`.
|
||||
|
||||
If there is an error during JSON deserialization observable sequence will fail with that error.
|
||||
|
||||
- parameter url: URL of `NSURLRequest` request.
|
||||
- returns: Observable sequence of response JSON.
|
||||
*/
|
||||
public func json(url: Foundation.URL) -> Observable<Any> {
|
||||
self.json(request: URLRequest(url: url))
|
||||
}
|
||||
}
|
||||
|
||||
extension Reactive where Base == URLSession {
|
||||
/// Log URL requests to standard output in curl format.
|
||||
public static var shouldLogRequest: (URLRequest) -> Bool = { _ in
|
||||
#if DEBUG
|
||||
return true
|
||||
#else
|
||||
return false
|
||||
#endif
|
||||
}
|
||||
}
|
||||
10
Pods/RxCocoa/RxCocoa/Runtime/_RX.m
generated
Normal file
10
Pods/RxCocoa/RxCocoa/Runtime/_RX.m
generated
Normal file
@@ -0,0 +1,10 @@
|
||||
//
|
||||
// _RX.m
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 7/12/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#import "include/_RX.h"
|
||||
|
||||
147
Pods/RxCocoa/RxCocoa/Runtime/_RXDelegateProxy.m
generated
Normal file
147
Pods/RxCocoa/RxCocoa/Runtime/_RXDelegateProxy.m
generated
Normal file
@@ -0,0 +1,147 @@
|
||||
//
|
||||
// _RXDelegateProxy.m
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 7/4/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#import "include/_RXDelegateProxy.h"
|
||||
#import "include/_RX.h"
|
||||
#import "include/_RXObjCRuntime.h"
|
||||
|
||||
@interface _RXDelegateProxy () {
|
||||
id __weak __forwardToDelegate;
|
||||
}
|
||||
|
||||
@property (nonatomic, strong) id strongForwardDelegate;
|
||||
|
||||
@end
|
||||
|
||||
static NSMutableDictionary *voidSelectorsPerClass = nil;
|
||||
|
||||
@implementation _RXDelegateProxy
|
||||
|
||||
+(NSSet*)collectVoidSelectorsForProtocol:(Protocol *)protocol {
|
||||
NSMutableSet *selectors = [NSMutableSet set];
|
||||
|
||||
unsigned int protocolMethodCount = 0;
|
||||
struct objc_method_description *pMethods = protocol_copyMethodDescriptionList(protocol, NO, YES, &protocolMethodCount);
|
||||
|
||||
for (unsigned int i = 0; i < protocolMethodCount; ++i) {
|
||||
struct objc_method_description method = pMethods[i];
|
||||
if (RX_is_method_with_description_void(method)) {
|
||||
[selectors addObject:SEL_VALUE(method.name)];
|
||||
}
|
||||
}
|
||||
|
||||
free(pMethods);
|
||||
|
||||
unsigned int numberOfBaseProtocols = 0;
|
||||
Protocol * __unsafe_unretained * pSubprotocols = protocol_copyProtocolList(protocol, &numberOfBaseProtocols);
|
||||
|
||||
for (unsigned int i = 0; i < numberOfBaseProtocols; ++i) {
|
||||
[selectors unionSet:[self collectVoidSelectorsForProtocol:pSubprotocols[i]]];
|
||||
}
|
||||
|
||||
free(pSubprotocols);
|
||||
|
||||
return selectors;
|
||||
}
|
||||
|
||||
+(void)initialize {
|
||||
@synchronized (_RXDelegateProxy.class) {
|
||||
if (voidSelectorsPerClass == nil) {
|
||||
voidSelectorsPerClass = [[NSMutableDictionary alloc] init];
|
||||
}
|
||||
|
||||
NSMutableSet *voidSelectors = [NSMutableSet set];
|
||||
|
||||
#define CLASS_HIERARCHY_MAX_DEPTH 100
|
||||
|
||||
NSInteger classHierarchyDepth = 0;
|
||||
Class targetClass = NULL;
|
||||
|
||||
for (classHierarchyDepth = 0, targetClass = self;
|
||||
classHierarchyDepth < CLASS_HIERARCHY_MAX_DEPTH && targetClass != nil;
|
||||
++classHierarchyDepth, targetClass = class_getSuperclass(targetClass)
|
||||
) {
|
||||
unsigned int count;
|
||||
Protocol *__unsafe_unretained *pProtocols = class_copyProtocolList(targetClass, &count);
|
||||
|
||||
for (unsigned int i = 0; i < count; i++) {
|
||||
NSSet *selectorsForProtocol = [self collectVoidSelectorsForProtocol:pProtocols[i]];
|
||||
[voidSelectors unionSet:selectorsForProtocol];
|
||||
}
|
||||
|
||||
free(pProtocols);
|
||||
}
|
||||
|
||||
if (classHierarchyDepth == CLASS_HIERARCHY_MAX_DEPTH) {
|
||||
NSLog(@"Detected weird class hierarchy with depth over %d. Starting with this class -> %@", CLASS_HIERARCHY_MAX_DEPTH, self);
|
||||
#if DEBUG
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
voidSelectorsPerClass[CLASS_VALUE(self)] = voidSelectors;
|
||||
}
|
||||
}
|
||||
|
||||
-(id)_forwardToDelegate {
|
||||
return __forwardToDelegate;
|
||||
}
|
||||
|
||||
-(void)_setForwardToDelegate:(id __nullable)forwardToDelegate retainDelegate:(BOOL)retainDelegate {
|
||||
__forwardToDelegate = forwardToDelegate;
|
||||
if (retainDelegate) {
|
||||
self.strongForwardDelegate = forwardToDelegate;
|
||||
}
|
||||
else {
|
||||
self.strongForwardDelegate = nil;
|
||||
}
|
||||
}
|
||||
|
||||
-(BOOL)hasWiredImplementationForSelector:(SEL)selector {
|
||||
return [super respondsToSelector:selector];
|
||||
}
|
||||
|
||||
-(BOOL)voidDelegateMethodsContain:(SEL)selector {
|
||||
@synchronized(_RXDelegateProxy.class) {
|
||||
NSSet *voidSelectors = voidSelectorsPerClass[CLASS_VALUE(self.class)];
|
||||
NSAssert(voidSelectors != nil, @"Set of allowed methods not initialized");
|
||||
return [voidSelectors containsObject:SEL_VALUE(selector)];
|
||||
}
|
||||
}
|
||||
|
||||
-(void)forwardInvocation:(NSInvocation *)anInvocation {
|
||||
BOOL isVoid = RX_is_method_signature_void(anInvocation.methodSignature);
|
||||
NSArray *arguments = nil;
|
||||
if (isVoid) {
|
||||
arguments = RX_extract_arguments(anInvocation);
|
||||
[self _sentMessage:anInvocation.selector withArguments:arguments];
|
||||
}
|
||||
|
||||
if (self._forwardToDelegate && [self._forwardToDelegate respondsToSelector:anInvocation.selector]) {
|
||||
[anInvocation invokeWithTarget:self._forwardToDelegate];
|
||||
}
|
||||
|
||||
if (isVoid) {
|
||||
[self _methodInvoked:anInvocation.selector withArguments:arguments];
|
||||
}
|
||||
}
|
||||
|
||||
// abstract method
|
||||
-(void)_sentMessage:(SEL)selector withArguments:(NSArray *)arguments {
|
||||
|
||||
}
|
||||
|
||||
// abstract method
|
||||
-(void)_methodInvoked:(SEL)selector withArguments:(NSArray *)arguments {
|
||||
|
||||
}
|
||||
|
||||
-(void)dealloc {
|
||||
}
|
||||
|
||||
@end
|
||||
54
Pods/RxCocoa/RxCocoa/Runtime/_RXKVOObserver.m
generated
Normal file
54
Pods/RxCocoa/RxCocoa/Runtime/_RXKVOObserver.m
generated
Normal file
@@ -0,0 +1,54 @@
|
||||
//
|
||||
// _RXKVOObserver.m
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 7/11/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#import "include/_RXKVOObserver.h"
|
||||
|
||||
@interface _RXKVOObserver ()
|
||||
|
||||
@property (nonatomic, unsafe_unretained) id target;
|
||||
@property (nonatomic, strong ) id retainedTarget;
|
||||
@property (nonatomic, copy ) NSString *keyPath;
|
||||
@property (nonatomic, copy ) void (^callback)(id);
|
||||
|
||||
@end
|
||||
|
||||
@implementation _RXKVOObserver
|
||||
|
||||
-(instancetype)initWithTarget:(id)target
|
||||
retainTarget:(BOOL)retainTarget
|
||||
keyPath:(NSString*)keyPath
|
||||
options:(NSKeyValueObservingOptions)options
|
||||
callback:(void (^)(id))callback {
|
||||
self = [super init];
|
||||
if (!self) return nil;
|
||||
|
||||
self.target = target;
|
||||
if (retainTarget) {
|
||||
self.retainedTarget = target;
|
||||
}
|
||||
self.keyPath = keyPath;
|
||||
self.callback = callback;
|
||||
|
||||
[self.target addObserver:self forKeyPath:self.keyPath options:options context:nil];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
|
||||
@synchronized(self) {
|
||||
self.callback(change[NSKeyValueChangeNewKey]);
|
||||
}
|
||||
}
|
||||
|
||||
-(void)dispose {
|
||||
[self.target removeObserver:self forKeyPath:self.keyPath context:nil];
|
||||
self.target = nil;
|
||||
self.retainedTarget = nil;
|
||||
}
|
||||
|
||||
@end
|
||||
1062
Pods/RxCocoa/RxCocoa/Runtime/_RXObjCRuntime.m
generated
Normal file
1062
Pods/RxCocoa/RxCocoa/Runtime/_RXObjCRuntime.m
generated
Normal file
File diff suppressed because it is too large
Load Diff
19
Pods/RxCocoa/RxCocoa/Runtime/include/RxCocoaRuntime.h
generated
Normal file
19
Pods/RxCocoa/RxCocoa/Runtime/include/RxCocoaRuntime.h
generated
Normal file
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// RxCocoaRuntime.h
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 2/21/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "_RX.h"
|
||||
#import "_RXDelegateProxy.h"
|
||||
#import "_RXKVOObserver.h"
|
||||
#import "_RXObjCRuntime.h"
|
||||
|
||||
//! Project version number for RxCocoa.
|
||||
FOUNDATION_EXPORT double RxCocoaVersionNumber;
|
||||
|
||||
//! Project version string for RxCocoa.
|
||||
FOUNDATION_EXPORT const unsigned char RxCocoaVersionString[];
|
||||
93
Pods/RxCocoa/RxCocoa/Runtime/include/_RX.h
generated
Normal file
93
Pods/RxCocoa/RxCocoa/Runtime/include/_RX.h
generated
Normal file
@@ -0,0 +1,93 @@
|
||||
//
|
||||
// _RX.h
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 7/12/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <objc/runtime.h>
|
||||
|
||||
/**
|
||||
################################################################################
|
||||
This file is part of RX private API
|
||||
################################################################################
|
||||
*/
|
||||
|
||||
#if TRACE_RESOURCES >= 2
|
||||
# define DLOG(...) NSLog(__VA_ARGS__)
|
||||
#else
|
||||
# define DLOG(...)
|
||||
#endif
|
||||
|
||||
#if DEBUG
|
||||
# define ABORT_IN_DEBUG abort();
|
||||
#else
|
||||
# define ABORT_IN_DEBUG
|
||||
#endif
|
||||
|
||||
|
||||
#define SEL_VALUE(x) [NSValue valueWithPointer:(x)]
|
||||
#define CLASS_VALUE(x) [NSValue valueWithNonretainedObject:(x)]
|
||||
#define IMP_VALUE(x) [NSValue valueWithPointer:(x)]
|
||||
|
||||
/**
|
||||
Checks that the local `error` instance exists before assigning it's value by reference.
|
||||
This macro exists to work around static analysis warnings — `NSError` is always assumed to be `nullable`, even though we explicitly define the method parameter as `nonnull`. See http://www.openradar.me/21766176 for more details.
|
||||
*/
|
||||
#define RX_THROW_ERROR(errorValue, returnValue) if (error != nil) { *error = (errorValue); } return (returnValue);
|
||||
|
||||
#define RX_CAT2(_1, _2) _RX_CAT2(_1, _2)
|
||||
#define _RX_CAT2(_1, _2) _1 ## _2
|
||||
|
||||
#define RX_ELEMENT_AT(n, ...) RX_CAT2(_RX_ELEMENT_AT_, n)(__VA_ARGS__)
|
||||
#define _RX_ELEMENT_AT_0(x, ...) x
|
||||
#define _RX_ELEMENT_AT_1(_0, x, ...) x
|
||||
#define _RX_ELEMENT_AT_2(_0, _1, x, ...) x
|
||||
#define _RX_ELEMENT_AT_3(_0, _1, _2, x, ...) x
|
||||
#define _RX_ELEMENT_AT_4(_0, _1, _2, _3, x, ...) x
|
||||
#define _RX_ELEMENT_AT_5(_0, _1, _2, _3, _4, x, ...) x
|
||||
#define _RX_ELEMENT_AT_6(_0, _1, _2, _3, _4, _5, x, ...) x
|
||||
|
||||
#define RX_COUNT(...) RX_ELEMENT_AT(6, ## __VA_ARGS__, 6, 5, 4, 3, 2, 1, 0)
|
||||
#define RX_EMPTY(...) RX_ELEMENT_AT(6, ## __VA_ARGS__, 0, 0, 0, 0, 0, 0, 1)
|
||||
|
||||
/**
|
||||
#define SUM(context, index, head, tail) head + tail
|
||||
#define MAP(context, index, element) (context)[index] * (element)
|
||||
|
||||
RX_FOR(numbers, SUM, MAP, b0, b1, b2);
|
||||
|
||||
(numbers)[0] * (b0) + (numbers)[1] * (b1) + (numbers[2]) * (b2)
|
||||
*/
|
||||
|
||||
#define RX_FOREACH(context, concat, map, ...) RX_FOR_MAX(RX_COUNT(__VA_ARGS__), _RX_FOREACH_CONCAT, _RX_FOREACH_MAP, context, concat, map, __VA_ARGS__)
|
||||
#define _RX_FOREACH_CONCAT(index, head, tail, context, concat, map, ...) concat(context, index, head, tail)
|
||||
#define _RX_FOREACH_MAP(index, context, concat, map, ...) map(context, index, RX_ELEMENT_AT(index, __VA_ARGS__))
|
||||
|
||||
/**
|
||||
#define MAP(context, index, item) (context)[index] * (item)
|
||||
|
||||
RX_FOR_COMMA(numbers, MAP, b0, b1);
|
||||
|
||||
,(numbers)[0] * b0, (numbers)[1] * b1
|
||||
*/
|
||||
#define RX_FOREACH_COMMA(context, map, ...) RX_CAT2(_RX_FOREACH_COMMA_EMPTY_, RX_EMPTY(__VA_ARGS__))(context, map, ## __VA_ARGS__)
|
||||
#define _RX_FOREACH_COMMA_EMPTY_1(context, map, ...)
|
||||
#define _RX_FOREACH_COMMA_EMPTY_0(context, map, ...) , RX_FOR_MAX(RX_COUNT(__VA_ARGS__), _RX_FOREACH_COMMA_CONCAT, _RX_FOREACH_COMMA_MAP, context, map, __VA_ARGS__)
|
||||
#define _RX_FOREACH_COMMA_CONCAT(index, head, tail, context, map, ...) head, tail
|
||||
#define _RX_FOREACH_COMMA_MAP(index, context, map, ...) map(context, index, RX_ELEMENT_AT(index, __VA_ARGS__))
|
||||
|
||||
// rx for
|
||||
|
||||
#define RX_FOR_MAX(max, concat, map, ...) RX_CAT2(RX_FOR_, max)(concat, map, ## __VA_ARGS__)
|
||||
|
||||
#define RX_FOR_0(concat, map, ...)
|
||||
#define RX_FOR_1(concat, map, ...) map(0, __VA_ARGS__)
|
||||
#define RX_FOR_2(concat, map, ...) concat(1, RX_FOR_1(concat, map, ## __VA_ARGS__), map(1, __VA_ARGS__), __VA_ARGS__)
|
||||
#define RX_FOR_3(concat, map, ...) concat(2, RX_FOR_2(concat, map, ## __VA_ARGS__), map(2, __VA_ARGS__), __VA_ARGS__)
|
||||
#define RX_FOR_4(concat, map, ...) concat(3, RX_FOR_3(concat, map, ## __VA_ARGS__), map(3, __VA_ARGS__), __VA_ARGS__)
|
||||
#define RX_FOR_5(concat, map, ...) concat(4, RX_FOR_4(concat, map, ## __VA_ARGS__), map(4, __VA_ARGS__), __VA_ARGS__)
|
||||
#define RX_FOR_6(concat, map, ...) concat(5, RX_FOR_5(concat, map, ## __VA_ARGS__), map(5, __VA_ARGS__), __VA_ARGS__)
|
||||
|
||||
27
Pods/RxCocoa/RxCocoa/Runtime/include/_RXDelegateProxy.h
generated
Normal file
27
Pods/RxCocoa/RxCocoa/Runtime/include/_RXDelegateProxy.h
generated
Normal file
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// _RXDelegateProxy.h
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 7/4/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface _RXDelegateProxy : NSObject
|
||||
|
||||
@property (nonatomic, weak, readonly) id _forwardToDelegate;
|
||||
|
||||
-(void)_setForwardToDelegate:(id __nullable)forwardToDelegate retainDelegate:(BOOL)retainDelegate NS_SWIFT_NAME(_setForwardToDelegate(_:retainDelegate:)) ;
|
||||
|
||||
-(BOOL)hasWiredImplementationForSelector:(SEL)selector;
|
||||
-(BOOL)voidDelegateMethodsContain:(SEL)selector;
|
||||
|
||||
-(void)_sentMessage:(SEL)selector withArguments:(NSArray*)arguments;
|
||||
-(void)_methodInvoked:(SEL)selector withArguments:(NSArray*)arguments;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
28
Pods/RxCocoa/RxCocoa/Runtime/include/_RXKVOObserver.h
generated
Normal file
28
Pods/RxCocoa/RxCocoa/Runtime/include/_RXKVOObserver.h
generated
Normal file
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// _RXKVOObserver.h
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 7/11/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
/**
|
||||
################################################################################
|
||||
This file is part of RX private API
|
||||
################################################################################
|
||||
*/
|
||||
|
||||
// Exists because if written in Swift, reading unowned is disabled during dealloc process
|
||||
@interface _RXKVOObserver : NSObject
|
||||
|
||||
-(instancetype)initWithTarget:(id)target
|
||||
retainTarget:(BOOL)retainTarget
|
||||
keyPath:(NSString*)keyPath
|
||||
options:(NSKeyValueObservingOptions)options
|
||||
callback:(void (^)(id))callback;
|
||||
|
||||
-(void)dispose;
|
||||
|
||||
@end
|
||||
102
Pods/RxCocoa/RxCocoa/Runtime/include/_RXObjCRuntime.h
generated
Normal file
102
Pods/RxCocoa/RxCocoa/Runtime/include/_RXObjCRuntime.h
generated
Normal file
@@ -0,0 +1,102 @@
|
||||
//
|
||||
// _RXObjCRuntime.h
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 7/11/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#if !DISABLE_SWIZZLING
|
||||
|
||||
/**
|
||||
################################################################################
|
||||
This file is part of RX private API
|
||||
################################################################################
|
||||
*/
|
||||
|
||||
/**
|
||||
This flag controls `RELEASE` configuration behavior in case race was detecting while modifying
|
||||
ObjC runtime.
|
||||
|
||||
In case this value is set to `YES`, after runtime race is detected, `abort()` will be called.
|
||||
Otherwise, only error will be reported using normal error reporting mechanism.
|
||||
|
||||
In `DEBUG` mode `abort` will be always called in case race is detected.
|
||||
|
||||
Races can't happen in case this is the only library modifying ObjC runtime, but in case there are multiple libraries
|
||||
changing ObjC runtime, race conditions can occur because there is no way to synchronize multiple libraries unaware of
|
||||
each other.
|
||||
|
||||
To help remedy this situation this library will use `synchronized` on target object and it's meta-class, but
|
||||
there aren't any guarantees of how other libraries will behave.
|
||||
|
||||
Default value is `NO`.
|
||||
|
||||
*/
|
||||
extern BOOL RXAbortOnThreadingHazard;
|
||||
|
||||
/// Error domain for RXObjCRuntime.
|
||||
extern NSString * __nonnull const RXObjCRuntimeErrorDomain;
|
||||
|
||||
/// `userInfo` key with additional information is interceptor probably KVO.
|
||||
extern NSString * __nonnull const RXObjCRuntimeErrorIsKVOKey;
|
||||
|
||||
typedef NS_ENUM(NSInteger, RXObjCRuntimeError) {
|
||||
RXObjCRuntimeErrorUnknown = 1,
|
||||
RXObjCRuntimeErrorObjectMessagesAlreadyBeingIntercepted = 2,
|
||||
RXObjCRuntimeErrorSelectorNotImplemented = 3,
|
||||
RXObjCRuntimeErrorCantInterceptCoreFoundationTollFreeBridgedObjects = 4,
|
||||
RXObjCRuntimeErrorThreadingCollisionWithOtherInterceptionMechanism = 5,
|
||||
RXObjCRuntimeErrorSavingOriginalForwardingMethodFailed = 6,
|
||||
RXObjCRuntimeErrorReplacingMethodWithForwardingImplementation = 7,
|
||||
RXObjCRuntimeErrorObservingPerformanceSensitiveMessages = 8,
|
||||
RXObjCRuntimeErrorObservingMessagesWithUnsupportedReturnType = 9,
|
||||
};
|
||||
|
||||
/// Transforms normal selector into a selector with RX prefix.
|
||||
SEL _Nonnull RX_selector(SEL _Nonnull selector);
|
||||
|
||||
/// Transforms selector into a unique pointer (because of Swift conversion rules)
|
||||
void * __nonnull RX_reference_from_selector(SEL __nonnull selector);
|
||||
|
||||
/// Protocol that interception observers must implement.
|
||||
@protocol RXMessageSentObserver
|
||||
|
||||
/// In case the same selector is being intercepted for a pair of base/sub classes,
|
||||
/// this property will differentiate between interceptors that need to fire.
|
||||
@property (nonatomic, assign, readonly) IMP __nonnull targetImplementation;
|
||||
|
||||
-(void)messageSentWithArguments:(NSArray* __nonnull)arguments;
|
||||
-(void)methodInvokedWithArguments:(NSArray* __nonnull)arguments;
|
||||
|
||||
@end
|
||||
|
||||
/// Protocol that deallocating observer must implement.
|
||||
@protocol RXDeallocatingObserver
|
||||
|
||||
/// In case the same selector is being intercepted for a pair of base/sub classes,
|
||||
/// this property will differentiate between interceptors that need to fire.
|
||||
@property (nonatomic, assign, readonly) IMP __nonnull targetImplementation;
|
||||
|
||||
-(void)deallocating;
|
||||
|
||||
@end
|
||||
|
||||
/// Ensures interceptor is installed on target object.
|
||||
IMP __nullable RX_ensure_observing(id __nonnull target, SEL __nonnull selector, NSError *__autoreleasing __nullable * __nullable error);
|
||||
|
||||
#endif
|
||||
|
||||
/// Extracts arguments for `invocation`.
|
||||
NSArray * __nonnull RX_extract_arguments(NSInvocation * __nonnull invocation);
|
||||
|
||||
/// Returns `YES` in case method has `void` return type.
|
||||
BOOL RX_is_method_with_description_void(struct objc_method_description method);
|
||||
|
||||
/// Returns `YES` in case methodSignature has `void` return type.
|
||||
BOOL RX_is_method_signature_void(NSMethodSignature * __nonnull methodSignature);
|
||||
|
||||
/// Default value for `RXInterceptionObserver.targetImplementation`.
|
||||
IMP __nonnull RX_default_target_implementation(void);
|
||||
19
Pods/RxCocoa/RxCocoa/RxCocoa.h
generated
Normal file
19
Pods/RxCocoa/RxCocoa/RxCocoa.h
generated
Normal file
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// RxCocoa.h
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 2/21/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <RxCocoa/_RX.h>
|
||||
#import <RxCocoa/_RXDelegateProxy.h>
|
||||
#import <RxCocoa/_RXKVOObserver.h>
|
||||
#import <RxCocoa/_RXObjCRuntime.h>
|
||||
|
||||
//! Project version number for RxCocoa.
|
||||
FOUNDATION_EXPORT double RxCocoaVersionNumber;
|
||||
|
||||
//! Project version string for RxCocoa.
|
||||
FOUNDATION_EXPORT const unsigned char RxCocoaVersionString[];
|
||||
155
Pods/RxCocoa/RxCocoa/RxCocoa.swift
generated
Normal file
155
Pods/RxCocoa/RxCocoa/RxCocoa.swift
generated
Normal file
@@ -0,0 +1,155 @@
|
||||
//
|
||||
// RxCocoa.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 2/21/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
// Importing RxCocoa also imports RxRelay
|
||||
@_exported import RxRelay
|
||||
|
||||
import RxSwift
|
||||
#if os(iOS)
|
||||
import UIKit
|
||||
#endif
|
||||
|
||||
/// RxCocoa errors.
|
||||
public enum RxCocoaError
|
||||
: Swift.Error
|
||||
, CustomDebugStringConvertible {
|
||||
/// Unknown error has occurred.
|
||||
case unknown
|
||||
/// Invalid operation was attempted.
|
||||
case invalidOperation(object: Any)
|
||||
/// Items are not yet bound to user interface but have been requested.
|
||||
case itemsNotYetBound(object: Any)
|
||||
/// Invalid KVO Path.
|
||||
case invalidPropertyName(object: Any, propertyName: String)
|
||||
/// Invalid object on key path.
|
||||
case invalidObjectOnKeyPath(object: Any, sourceObject: AnyObject, propertyName: String)
|
||||
/// Error during swizzling.
|
||||
case errorDuringSwizzling
|
||||
/// Casting error.
|
||||
case castingError(object: Any, targetType: Any.Type)
|
||||
}
|
||||
|
||||
|
||||
// MARK: Debug descriptions
|
||||
|
||||
extension RxCocoaError {
|
||||
/// A textual representation of `self`, suitable for debugging.
|
||||
public var debugDescription: String {
|
||||
switch self {
|
||||
case .unknown:
|
||||
return "Unknown error occurred."
|
||||
case let .invalidOperation(object):
|
||||
return "Invalid operation was attempted on `\(object)`."
|
||||
case let .itemsNotYetBound(object):
|
||||
return "Data source is set, but items are not yet bound to user interface for `\(object)`."
|
||||
case let .invalidPropertyName(object, propertyName):
|
||||
return "Object `\(object)` doesn't have a property named `\(propertyName)`."
|
||||
case let .invalidObjectOnKeyPath(object, sourceObject, propertyName):
|
||||
return "Unobservable object `\(object)` was observed as `\(propertyName)` of `\(sourceObject)`."
|
||||
case .errorDuringSwizzling:
|
||||
return "Error during swizzling."
|
||||
case let .castingError(object, targetType):
|
||||
return "Error casting `\(object)` to `\(targetType)`"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// MARK: Error binding policies
|
||||
|
||||
func bindingError(_ error: Swift.Error) {
|
||||
let error = "Binding error: \(error)"
|
||||
#if DEBUG
|
||||
rxFatalError(error)
|
||||
#else
|
||||
print(error)
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Swift does not implement abstract methods. This method is used as a runtime check to ensure that methods which intended to be abstract (i.e., they should be implemented in subclasses) are not called directly on the superclass.
|
||||
func rxAbstractMethod(message: String = "Abstract method", file: StaticString = #file, line: UInt = #line) -> Swift.Never {
|
||||
rxFatalError(message, file: file, line: line)
|
||||
}
|
||||
|
||||
func rxFatalError(_ lastMessage: @autoclosure () -> String, file: StaticString = #file, line: UInt = #line) -> Swift.Never {
|
||||
// The temptation to comment this line is great, but please don't, it's for your own good. The choice is yours.
|
||||
fatalError(lastMessage(), file: file, line: line)
|
||||
}
|
||||
|
||||
func rxFatalErrorInDebug(_ lastMessage: @autoclosure () -> String, file: StaticString = #file, line: UInt = #line) {
|
||||
#if DEBUG
|
||||
fatalError(lastMessage(), file: file, line: line)
|
||||
#else
|
||||
print("\(file):\(line): \(lastMessage())")
|
||||
#endif
|
||||
}
|
||||
|
||||
// MARK: casts or fatal error
|
||||
|
||||
// workaround for Swift compiler bug, cheers compiler team :)
|
||||
func castOptionalOrFatalError<T>(_ value: Any?) -> T? {
|
||||
if value == nil {
|
||||
return nil
|
||||
}
|
||||
let v: T = castOrFatalError(value)
|
||||
return v
|
||||
}
|
||||
|
||||
func castOrThrow<T>(_ resultType: T.Type, _ object: Any) throws -> T {
|
||||
guard let returnValue = object as? T else {
|
||||
throw RxCocoaError.castingError(object: object, targetType: resultType)
|
||||
}
|
||||
|
||||
return returnValue
|
||||
}
|
||||
|
||||
func castOptionalOrThrow<T>(_ resultType: T.Type, _ object: AnyObject) throws -> T? {
|
||||
if NSNull().isEqual(object) {
|
||||
return nil
|
||||
}
|
||||
|
||||
guard let returnValue = object as? T else {
|
||||
throw RxCocoaError.castingError(object: object, targetType: resultType)
|
||||
}
|
||||
|
||||
return returnValue
|
||||
}
|
||||
|
||||
func castOrFatalError<T>(_ value: AnyObject!, message: String) -> T {
|
||||
let maybeResult: T? = value as? T
|
||||
guard let result = maybeResult else {
|
||||
rxFatalError(message)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func castOrFatalError<T>(_ value: Any!) -> T {
|
||||
let maybeResult: T? = value as? T
|
||||
guard let result = maybeResult else {
|
||||
rxFatalError("Failure converting from \(String(describing: value)) to \(T.self)")
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// MARK: Error messages
|
||||
|
||||
let dataSourceNotSet = "DataSource not set"
|
||||
let delegateNotSet = "Delegate not set"
|
||||
|
||||
// MARK: Shared with RxSwift
|
||||
|
||||
func rxFatalError(_ lastMessage: String) -> Never {
|
||||
// The temptation to comment this line is great, but please don't, it's for your own good. The choice is yours.
|
||||
fatalError(lastMessage)
|
||||
}
|
||||
|
||||
68
Pods/RxCocoa/RxCocoa/Traits/ControlEvent.swift
generated
Normal file
68
Pods/RxCocoa/RxCocoa/Traits/ControlEvent.swift
generated
Normal file
@@ -0,0 +1,68 @@
|
||||
//
|
||||
// ControlEvent.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 8/28/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
import RxSwift
|
||||
|
||||
/// A protocol that extends `ControlEvent`.
|
||||
public protocol ControlEventType : ObservableType {
|
||||
|
||||
/// - returns: `ControlEvent` interface
|
||||
func asControlEvent() -> ControlEvent<Element>
|
||||
}
|
||||
|
||||
/**
|
||||
A trait for `Observable`/`ObservableType` that represents an event on a UI element.
|
||||
|
||||
Properties:
|
||||
|
||||
- it doesn’t send any initial value on subscription,
|
||||
- it `Complete`s the sequence when the control deallocates,
|
||||
- it never errors out
|
||||
- it delivers events on `MainScheduler.instance`.
|
||||
|
||||
**The implementation of `ControlEvent` will ensure that sequence of events is being subscribed on main scheduler
|
||||
(`subscribe(on: ConcurrentMainScheduler.instance)` behavior).**
|
||||
|
||||
**It is the implementor’s responsibility to make sure that all other properties enumerated above are satisfied.**
|
||||
|
||||
**If they aren’t, using this trait will communicate wrong properties, and could potentially break someone’s code.**
|
||||
|
||||
**If the `events` observable sequence passed into the initializer doesn’t satisfy all enumerated
|
||||
properties, don’t use this trait.**
|
||||
*/
|
||||
public struct ControlEvent<PropertyType> : ControlEventType {
|
||||
public typealias Element = PropertyType
|
||||
|
||||
let events: Observable<PropertyType>
|
||||
|
||||
/// Initializes control event with a observable sequence that represents events.
|
||||
///
|
||||
/// - parameter events: Observable sequence that represents events.
|
||||
/// - returns: Control event created with a observable sequence of events.
|
||||
public init<Ev: ObservableType>(events: Ev) where Ev.Element == Element {
|
||||
self.events = events.subscribe(on: ConcurrentMainScheduler.instance)
|
||||
}
|
||||
|
||||
/// Subscribes an observer to control events.
|
||||
///
|
||||
/// - parameter observer: Observer to subscribe to events.
|
||||
/// - returns: Disposable object that can be used to unsubscribe the observer from receiving control events.
|
||||
public func subscribe<Observer: ObserverType>(_ observer: Observer) -> Disposable where Observer.Element == Element {
|
||||
self.events.subscribe(observer)
|
||||
}
|
||||
|
||||
/// - returns: `Observable` interface.
|
||||
public func asObservable() -> Observable<Element> {
|
||||
self.events
|
||||
}
|
||||
|
||||
/// - returns: `ControlEvent` interface.
|
||||
public func asControlEvent() -> ControlEvent<Element> {
|
||||
self
|
||||
}
|
||||
}
|
||||
118
Pods/RxCocoa/RxCocoa/Traits/ControlProperty.swift
generated
Normal file
118
Pods/RxCocoa/RxCocoa/Traits/ControlProperty.swift
generated
Normal file
@@ -0,0 +1,118 @@
|
||||
//
|
||||
// ControlProperty.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 8/28/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
import RxSwift
|
||||
|
||||
/// Protocol that enables extension of `ControlProperty`.
|
||||
public protocol ControlPropertyType : ObservableType, ObserverType {
|
||||
|
||||
/// - returns: `ControlProperty` interface
|
||||
func asControlProperty() -> ControlProperty<Element>
|
||||
}
|
||||
|
||||
/**
|
||||
Trait for `Observable`/`ObservableType` that represents property of UI element.
|
||||
|
||||
Sequence of values only represents initial control value and user initiated value changes.
|
||||
Programmatic value changes won't be reported.
|
||||
|
||||
It's properties are:
|
||||
|
||||
- `shareReplay(1)` behavior
|
||||
- it's stateful, upon subscription (calling subscribe) last element is immediately replayed if it was produced
|
||||
- it will `Complete` sequence on control being deallocated
|
||||
- it never errors out
|
||||
- it delivers events on `MainScheduler.instance`
|
||||
|
||||
**The implementation of `ControlProperty` will ensure that sequence of values is being subscribed on main scheduler
|
||||
(`subscribe(on: ConcurrentMainScheduler.instance)` behavior).**
|
||||
|
||||
**It is implementor's responsibility to make sure that that all other properties enumerated above are satisfied.**
|
||||
|
||||
**If they aren't, then using this trait communicates wrong properties and could potentially break someone's code.**
|
||||
|
||||
**In case `values` observable sequence that is being passed into initializer doesn't satisfy all enumerated
|
||||
properties, please don't use this trait.**
|
||||
*/
|
||||
public struct ControlProperty<PropertyType> : ControlPropertyType {
|
||||
public typealias Element = PropertyType
|
||||
|
||||
let values: Observable<PropertyType>
|
||||
let valueSink: AnyObserver<PropertyType>
|
||||
|
||||
/// Initializes control property with a observable sequence that represents property values and observer that enables
|
||||
/// binding values to property.
|
||||
///
|
||||
/// - parameter values: Observable sequence that represents property values.
|
||||
/// - parameter valueSink: Observer that enables binding values to control property.
|
||||
/// - returns: Control property created with a observable sequence of values and an observer that enables binding values
|
||||
/// to property.
|
||||
public init<Values: ObservableType, Sink: ObserverType>(values: Values, valueSink: Sink) where Element == Values.Element, Element == Sink.Element {
|
||||
self.values = values.subscribe(on: ConcurrentMainScheduler.instance)
|
||||
self.valueSink = valueSink.asObserver()
|
||||
}
|
||||
|
||||
/// Subscribes an observer to control property values.
|
||||
///
|
||||
/// - parameter observer: Observer to subscribe to property values.
|
||||
/// - returns: Disposable object that can be used to unsubscribe the observer from receiving control property values.
|
||||
public func subscribe<Observer: ObserverType>(_ observer: Observer) -> Disposable where Observer.Element == Element {
|
||||
self.values.subscribe(observer)
|
||||
}
|
||||
|
||||
/// `ControlEvent` of user initiated value changes. Every time user updates control value change event
|
||||
/// will be emitted from `changed` event.
|
||||
///
|
||||
/// Programmatic changes to control value won't be reported.
|
||||
///
|
||||
/// It contains all control property values except for first one.
|
||||
///
|
||||
/// The name only implies that sequence element will be generated once user changes a value and not that
|
||||
/// adjacent sequence values need to be different (e.g. because of interaction between programmatic and user updates,
|
||||
/// or for any other reason).
|
||||
public var changed: ControlEvent<PropertyType> {
|
||||
ControlEvent(events: self.values.skip(1))
|
||||
}
|
||||
|
||||
/// - returns: `Observable` interface.
|
||||
public func asObservable() -> Observable<Element> {
|
||||
self.values
|
||||
}
|
||||
|
||||
/// - returns: `ControlProperty` interface.
|
||||
public func asControlProperty() -> ControlProperty<Element> {
|
||||
self
|
||||
}
|
||||
|
||||
/// Binds event to user interface.
|
||||
///
|
||||
/// - In case next element is received, it is being set to control value.
|
||||
/// - In case error is received, DEBUG builds raise fatal error, RELEASE builds log event to standard output.
|
||||
/// - In case sequence completes, nothing happens.
|
||||
public func on(_ event: Event<Element>) {
|
||||
switch event {
|
||||
case .error(let error):
|
||||
bindingError(error)
|
||||
case .next:
|
||||
self.valueSink.on(event)
|
||||
case .completed:
|
||||
self.valueSink.on(event)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension ControlPropertyType where Element == String? {
|
||||
/// Transforms control property of type `String?` into control property of type `String`.
|
||||
public var orEmpty: ControlProperty<String> {
|
||||
let original: ControlProperty<String?> = self.asControlProperty()
|
||||
|
||||
let values: Observable<String> = original.values.map { $0 ?? "" }
|
||||
let valueSink: AnyObserver<String> = original.valueSink.mapObserver { $0 }
|
||||
return ControlProperty<String>(values: values, valueSink: valueSink)
|
||||
}
|
||||
}
|
||||
21
Pods/RxCocoa/RxCocoa/Traits/Driver/BehaviorRelay+Driver.swift
generated
Normal file
21
Pods/RxCocoa/RxCocoa/Traits/Driver/BehaviorRelay+Driver.swift
generated
Normal file
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// BehaviorRelay+Driver.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 10/7/17.
|
||||
// Copyright © 2017 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
import RxSwift
|
||||
import RxRelay
|
||||
|
||||
extension BehaviorRelay {
|
||||
/// Converts `BehaviorRelay` to `Driver`.
|
||||
///
|
||||
/// - returns: Observable sequence.
|
||||
public func asDriver() -> Driver<Element> {
|
||||
let source = self.asObservable()
|
||||
.observe(on:DriverSharingStrategy.scheduler)
|
||||
return SharedSequence(source)
|
||||
}
|
||||
}
|
||||
24
Pods/RxCocoa/RxCocoa/Traits/Driver/ControlEvent+Driver.swift
generated
Normal file
24
Pods/RxCocoa/RxCocoa/Traits/Driver/ControlEvent+Driver.swift
generated
Normal file
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// ControlEvent+Driver.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 9/19/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
import RxSwift
|
||||
|
||||
extension ControlEvent {
|
||||
/// Converts `ControlEvent` to `Driver` trait.
|
||||
///
|
||||
/// `ControlEvent` already can't fail, so no special case needs to be handled.
|
||||
public func asDriver() -> Driver<Element> {
|
||||
return self.asDriver { _ -> Driver<Element> in
|
||||
#if DEBUG
|
||||
rxFatalError("Somehow driver received error from a source that shouldn't fail.")
|
||||
#else
|
||||
return Driver.empty()
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
24
Pods/RxCocoa/RxCocoa/Traits/Driver/ControlProperty+Driver.swift
generated
Normal file
24
Pods/RxCocoa/RxCocoa/Traits/Driver/ControlProperty+Driver.swift
generated
Normal file
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// ControlProperty+Driver.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 9/19/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
import RxSwift
|
||||
|
||||
extension ControlProperty {
|
||||
/// Converts `ControlProperty` to `Driver` trait.
|
||||
///
|
||||
/// `ControlProperty` already can't fail, so no special case needs to be handled.
|
||||
public func asDriver() -> Driver<Element> {
|
||||
return self.asDriver { _ -> Driver<Element> in
|
||||
#if DEBUG
|
||||
rxFatalError("Somehow driver received error from a source that shouldn't fail.")
|
||||
#else
|
||||
return Driver.empty()
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
203
Pods/RxCocoa/RxCocoa/Traits/Driver/Driver+Subscription.swift
generated
Normal file
203
Pods/RxCocoa/RxCocoa/Traits/Driver/Driver+Subscription.swift
generated
Normal file
@@ -0,0 +1,203 @@
|
||||
//
|
||||
// Driver+Subscription.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 9/19/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
import RxSwift
|
||||
import RxRelay
|
||||
|
||||
private let errorMessage = "`drive*` family of methods can be only called from `MainThread`.\n" +
|
||||
"This is required to ensure that the last replayed `Driver` element is delivered on `MainThread`.\n"
|
||||
|
||||
extension SharedSequenceConvertibleType where SharingStrategy == DriverSharingStrategy {
|
||||
/**
|
||||
Creates new subscription and sends elements to observer.
|
||||
This method can be only called from `MainThread`.
|
||||
|
||||
In this form it's equivalent to `subscribe` method, but it communicates intent better.
|
||||
|
||||
- parameter observers: Observers that receives events.
|
||||
- returns: Disposable object that can be used to unsubscribe the observer from the subject.
|
||||
*/
|
||||
public func drive<Observer: ObserverType>(_ observers: Observer...) -> Disposable where Observer.Element == Element {
|
||||
MainScheduler.ensureRunningOnMainThread(errorMessage: errorMessage)
|
||||
return self.asSharedSequence()
|
||||
.asObservable()
|
||||
.subscribe { e in
|
||||
observers.forEach { $0.on(e) }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Creates new subscription and sends elements to observer.
|
||||
This method can be only called from `MainThread`.
|
||||
|
||||
In this form it's equivalent to `subscribe` method, but it communicates intent better.
|
||||
|
||||
- parameter observers: Observers that receives events.
|
||||
- returns: Disposable object that can be used to unsubscribe the observer from the subject.
|
||||
*/
|
||||
public func drive<Observer: ObserverType>(_ observers: Observer...) -> Disposable where Observer.Element == Element? {
|
||||
MainScheduler.ensureRunningOnMainThread(errorMessage: errorMessage)
|
||||
return self.asSharedSequence()
|
||||
.asObservable()
|
||||
.map { $0 as Element? }
|
||||
.subscribe { e in
|
||||
observers.forEach { $0.on(e) }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Creates new subscription and sends elements to `BehaviorRelay`.
|
||||
This method can be only called from `MainThread`.
|
||||
|
||||
- parameter relays: Target relays for sequence elements.
|
||||
- returns: Disposable object that can be used to unsubscribe the observer from the relay.
|
||||
*/
|
||||
public func drive(_ relays: BehaviorRelay<Element>...) -> Disposable {
|
||||
MainScheduler.ensureRunningOnMainThread(errorMessage: errorMessage)
|
||||
return self.drive(onNext: { e in
|
||||
relays.forEach { $0.accept(e) }
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
Creates new subscription and sends elements to `BehaviorRelay`.
|
||||
This method can be only called from `MainThread`.
|
||||
|
||||
- parameter relays: Target relays for sequence elements.
|
||||
- returns: Disposable object that can be used to unsubscribe the observer from the relay.
|
||||
*/
|
||||
public func drive(_ relays: BehaviorRelay<Element?>...) -> Disposable {
|
||||
MainScheduler.ensureRunningOnMainThread(errorMessage: errorMessage)
|
||||
return self.drive(onNext: { e in
|
||||
relays.forEach { $0.accept(e) }
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
Creates new subscription and sends elements to `ReplayRelay`.
|
||||
This method can be only called from `MainThread`.
|
||||
|
||||
- parameter relays: Target relays for sequence elements.
|
||||
- returns: Disposable object that can be used to unsubscribe the observer from the relay.
|
||||
*/
|
||||
public func drive(_ relays: ReplayRelay<Element>...) -> Disposable {
|
||||
MainScheduler.ensureRunningOnMainThread(errorMessage: errorMessage)
|
||||
return self.drive(onNext: { e in
|
||||
relays.forEach { $0.accept(e) }
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
Creates new subscription and sends elements to `ReplayRelay`.
|
||||
This method can be only called from `MainThread`.
|
||||
|
||||
- parameter relays: Target relays for sequence elements.
|
||||
- returns: Disposable object that can be used to unsubscribe the observer from the relay.
|
||||
*/
|
||||
public func drive(_ relays: ReplayRelay<Element?>...) -> Disposable {
|
||||
MainScheduler.ensureRunningOnMainThread(errorMessage: errorMessage)
|
||||
return self.drive(onNext: { e in
|
||||
relays.forEach { $0.accept(e) }
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
Subscribes to observable sequence using custom binder function.
|
||||
This method can be only called from `MainThread`.
|
||||
|
||||
- parameter transformation: Function used to bind elements from `self`.
|
||||
- returns: Object representing subscription.
|
||||
*/
|
||||
public func drive<Result>(_ transformation: (Observable<Element>) -> Result) -> Result {
|
||||
MainScheduler.ensureRunningOnMainThread(errorMessage: errorMessage)
|
||||
return transformation(self.asObservable())
|
||||
}
|
||||
|
||||
/**
|
||||
Subscribes to observable sequence using custom binder function and final parameter passed to binder function
|
||||
after `self` is passed.
|
||||
|
||||
public func drive<R1, R2>(with: Self -> R1 -> R2, curriedArgument: R1) -> R2 {
|
||||
return with(self)(curriedArgument)
|
||||
}
|
||||
|
||||
This method can be only called from `MainThread`.
|
||||
|
||||
- parameter with: Function used to bind elements from `self`.
|
||||
- parameter curriedArgument: Final argument passed to `binder` to finish binding process.
|
||||
- returns: Object representing subscription.
|
||||
*/
|
||||
public func drive<R1, R2>(_ with: (Observable<Element>) -> (R1) -> R2, curriedArgument: R1) -> R2 {
|
||||
MainScheduler.ensureRunningOnMainThread(errorMessage: errorMessage)
|
||||
return with(self.asObservable())(curriedArgument)
|
||||
}
|
||||
|
||||
/**
|
||||
Subscribes an element handler, a completion handler and disposed handler to an observable sequence.
|
||||
This method can be only called from `MainThread`.
|
||||
|
||||
Also, take in an object and provide an unretained, safe to use (i.e. not implicitly unwrapped), reference to it along with the events emitted by the sequence.
|
||||
|
||||
Error callback is not exposed because `Driver` can't error out.
|
||||
|
||||
- Note: If `object` can't be retained, none of the other closures will be invoked.
|
||||
|
||||
- parameter object: The object to provide an unretained reference on.
|
||||
- parameter onNext: Action to invoke for each element in the observable sequence.
|
||||
- parameter onCompleted: Action to invoke upon graceful termination of the observable sequence.
|
||||
gracefully completed, errored, or if the generation is canceled by disposing subscription)
|
||||
- parameter onDisposed: Action to invoke upon any type of termination of sequence (if the sequence has
|
||||
gracefully completed, errored, or if the generation is canceled by disposing subscription)
|
||||
- returns: Subscription object used to unsubscribe from the observable sequence.
|
||||
*/
|
||||
public func drive<Object: AnyObject>(
|
||||
with object: Object,
|
||||
onNext: ((Object, Element) -> Void)? = nil,
|
||||
onCompleted: ((Object) -> Void)? = nil,
|
||||
onDisposed: ((Object) -> Void)? = nil
|
||||
) -> Disposable {
|
||||
MainScheduler.ensureRunningOnMainThread(errorMessage: errorMessage)
|
||||
return self.asObservable().subscribe(with: object, onNext: onNext, onCompleted: onCompleted, onDisposed: onDisposed)
|
||||
}
|
||||
|
||||
/**
|
||||
Subscribes an element handler, a completion handler and disposed handler to an observable sequence.
|
||||
This method can be only called from `MainThread`.
|
||||
|
||||
Error callback is not exposed because `Driver` can't error out.
|
||||
|
||||
- parameter onNext: Action to invoke for each element in the observable sequence.
|
||||
- parameter onCompleted: Action to invoke upon graceful termination of the observable sequence.
|
||||
gracefully completed, errored, or if the generation is canceled by disposing subscription)
|
||||
- parameter onDisposed: Action to invoke upon any type of termination of sequence (if the sequence has
|
||||
gracefully completed, errored, or if the generation is canceled by disposing subscription)
|
||||
- returns: Subscription object used to unsubscribe from the observable sequence.
|
||||
*/
|
||||
public func drive(
|
||||
onNext: ((Element) -> Void)? = nil,
|
||||
onCompleted: (() -> Void)? = nil,
|
||||
onDisposed: (() -> Void)? = nil
|
||||
) -> Disposable {
|
||||
MainScheduler.ensureRunningOnMainThread(errorMessage: errorMessage)
|
||||
return self.asObservable().subscribe(onNext: onNext, onCompleted: onCompleted, onDisposed: onDisposed)
|
||||
}
|
||||
|
||||
/**
|
||||
Subscribes to this `Driver` with a no-op.
|
||||
This method can be only called from `MainThread`.
|
||||
|
||||
- note: This is an alias of `drive(onNext: nil, onCompleted: nil, onDisposed: nil)` used to fix an ambiguity bug in Swift: https://bugs.swift.org/browse/SR-13657
|
||||
|
||||
- returns: Subscription object used to unsubscribe from the observable sequence.
|
||||
*/
|
||||
public func drive() -> Disposable {
|
||||
drive(onNext: nil, onCompleted: nil, onDisposed: nil)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
53
Pods/RxCocoa/RxCocoa/Traits/Driver/Driver.swift
generated
Normal file
53
Pods/RxCocoa/RxCocoa/Traits/Driver/Driver.swift
generated
Normal file
@@ -0,0 +1,53 @@
|
||||
//
|
||||
// Driver.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 9/26/16.
|
||||
// Copyright © 2016 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
import RxSwift
|
||||
|
||||
/**
|
||||
Trait that represents observable sequence with following properties:
|
||||
|
||||
- it never fails
|
||||
- it delivers events on `MainScheduler.instance`
|
||||
- `share(replay: 1, scope: .whileConnected)` sharing strategy
|
||||
|
||||
Additional explanation:
|
||||
- all observers share sequence computation resources
|
||||
- it's stateful, upon subscription (calling subscribe) last element is immediately replayed if it was produced
|
||||
- computation of elements is reference counted with respect to the number of observers
|
||||
- if there are no subscribers, it will release sequence computation resources
|
||||
|
||||
In case trait that models event bus is required, please check `Signal`.
|
||||
|
||||
`Driver<Element>` can be considered a builder pattern for observable sequences that drive the application.
|
||||
|
||||
If observable sequence has produced at least one element, after new subscription is made last produced element will be
|
||||
immediately replayed on the same thread on which the subscription was made.
|
||||
|
||||
When using `drive*`, `subscribe*` and `bind*` family of methods, they should always be called from main thread.
|
||||
|
||||
If `drive*`, `subscribe*` and `bind*` are called from background thread, it is possible that initial replay
|
||||
will happen on background thread, and subsequent events will arrive on main thread.
|
||||
|
||||
To find out more about traits and how to use them, please visit `Documentation/Traits.md`.
|
||||
*/
|
||||
public typealias Driver<Element> = SharedSequence<DriverSharingStrategy, Element>
|
||||
|
||||
public struct DriverSharingStrategy: SharingStrategyProtocol {
|
||||
public static var scheduler: SchedulerType { SharingScheduler.make() }
|
||||
public static func share<Element>(_ source: Observable<Element>) -> Observable<Element> {
|
||||
source.share(replay: 1, scope: .whileConnected)
|
||||
}
|
||||
}
|
||||
|
||||
extension SharedSequenceConvertibleType where SharingStrategy == DriverSharingStrategy {
|
||||
/// Adds `asDriver` to `SharingSequence` with `DriverSharingStrategy`.
|
||||
public func asDriver() -> Driver<Element> {
|
||||
self.asSharedSequence()
|
||||
}
|
||||
}
|
||||
|
||||
57
Pods/RxCocoa/RxCocoa/Traits/Driver/ObservableConvertibleType+Driver.swift
generated
Normal file
57
Pods/RxCocoa/RxCocoa/Traits/Driver/ObservableConvertibleType+Driver.swift
generated
Normal file
@@ -0,0 +1,57 @@
|
||||
//
|
||||
// ObservableConvertibleType+Driver.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 9/19/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
import RxSwift
|
||||
|
||||
extension ObservableConvertibleType {
|
||||
/**
|
||||
Converts observable sequence to `Driver` trait.
|
||||
|
||||
- parameter onErrorJustReturn: Element to return in case of error and after that complete the sequence.
|
||||
- returns: Driver trait.
|
||||
*/
|
||||
public func asDriver(onErrorJustReturn: Element) -> Driver<Element> {
|
||||
let source = self
|
||||
.asObservable()
|
||||
.observe(on:DriverSharingStrategy.scheduler)
|
||||
.catchAndReturn(onErrorJustReturn)
|
||||
return Driver(source)
|
||||
}
|
||||
|
||||
/**
|
||||
Converts observable sequence to `Driver` trait.
|
||||
|
||||
- parameter onErrorDriveWith: Driver that continues to drive the sequence in case of error.
|
||||
- returns: Driver trait.
|
||||
*/
|
||||
public func asDriver(onErrorDriveWith: Driver<Element>) -> Driver<Element> {
|
||||
let source = self
|
||||
.asObservable()
|
||||
.observe(on:DriverSharingStrategy.scheduler)
|
||||
.catch { _ in
|
||||
onErrorDriveWith.asObservable()
|
||||
}
|
||||
return Driver(source)
|
||||
}
|
||||
|
||||
/**
|
||||
Converts observable sequence to `Driver` trait.
|
||||
|
||||
- parameter onErrorRecover: Calculates driver that continues to drive the sequence in case of error.
|
||||
- returns: Driver trait.
|
||||
*/
|
||||
public func asDriver(onErrorRecover: @escaping (_ error: Swift.Error) -> Driver<Element>) -> Driver<Element> {
|
||||
let source = self
|
||||
.asObservable()
|
||||
.observe(on:DriverSharingStrategy.scheduler)
|
||||
.catch { error in
|
||||
onErrorRecover(error).asObservable()
|
||||
}
|
||||
return Driver(source)
|
||||
}
|
||||
}
|
||||
57
Pods/RxCocoa/RxCocoa/Traits/SharedSequence/ObservableConvertibleType+SharedSequence.swift
generated
Normal file
57
Pods/RxCocoa/RxCocoa/Traits/SharedSequence/ObservableConvertibleType+SharedSequence.swift
generated
Normal file
@@ -0,0 +1,57 @@
|
||||
//
|
||||
// ObservableConvertibleType+SharedSequence.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 11/1/17.
|
||||
// Copyright © 2017 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
import RxSwift
|
||||
|
||||
extension ObservableConvertibleType {
|
||||
/**
|
||||
Converts anything convertible to `Observable` to `SharedSequence` unit.
|
||||
|
||||
- parameter onErrorJustReturn: Element to return in case of error and after that complete the sequence.
|
||||
- returns: Driving observable sequence.
|
||||
*/
|
||||
public func asSharedSequence<S>(sharingStrategy: S.Type = S.self, onErrorJustReturn: Element) -> SharedSequence<S, Element> {
|
||||
let source = self
|
||||
.asObservable()
|
||||
.observe(on:S.scheduler)
|
||||
.catchAndReturn(onErrorJustReturn)
|
||||
return SharedSequence(source)
|
||||
}
|
||||
|
||||
/**
|
||||
Converts anything convertible to `Observable` to `SharedSequence` unit.
|
||||
|
||||
- parameter onErrorDriveWith: SharedSequence that provides elements of the sequence in case of error.
|
||||
- returns: Driving observable sequence.
|
||||
*/
|
||||
public func asSharedSequence<S>(sharingStrategy: S.Type = S.self, onErrorDriveWith: SharedSequence<S, Element>) -> SharedSequence<S, Element> {
|
||||
let source = self
|
||||
.asObservable()
|
||||
.observe(on:S.scheduler)
|
||||
.catch { _ in
|
||||
onErrorDriveWith.asObservable()
|
||||
}
|
||||
return SharedSequence(source)
|
||||
}
|
||||
|
||||
/**
|
||||
Converts anything convertible to `Observable` to `SharedSequence` unit.
|
||||
|
||||
- parameter onErrorRecover: Calculates driver that continues to drive the sequence in case of error.
|
||||
- returns: Driving observable sequence.
|
||||
*/
|
||||
public func asSharedSequence<S>(sharingStrategy: S.Type = S.self, onErrorRecover: @escaping (_ error: Swift.Error) -> SharedSequence<S, Element>) -> SharedSequence<S, Element> {
|
||||
let source = self
|
||||
.asObservable()
|
||||
.observe(on:S.scheduler)
|
||||
.catch { error in
|
||||
onErrorRecover(error).asObservable()
|
||||
}
|
||||
return SharedSequence(source)
|
||||
}
|
||||
}
|
||||
62
Pods/RxCocoa/RxCocoa/Traits/SharedSequence/SchedulerType+SharedSequence.swift
generated
Normal file
62
Pods/RxCocoa/RxCocoa/Traits/SharedSequence/SchedulerType+SharedSequence.swift
generated
Normal file
@@ -0,0 +1,62 @@
|
||||
//
|
||||
// SchedulerType+SharedSequence.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 8/27/17.
|
||||
// Copyright © 2017 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
import RxSwift
|
||||
|
||||
public enum SharingScheduler {
|
||||
/// Default scheduler used in SharedSequence based traits.
|
||||
public private(set) static var make: () -> SchedulerType = { MainScheduler() }
|
||||
|
||||
/**
|
||||
This method can be used in unit tests to ensure that built in shared sequences are using mock schedulers instead
|
||||
of main schedulers.
|
||||
|
||||
**This shouldn't be used in normal release builds.**
|
||||
*/
|
||||
static public func mock(scheduler: SchedulerType, action: () throws -> Void) rethrows {
|
||||
return try mock(makeScheduler: { scheduler }, action: action)
|
||||
}
|
||||
|
||||
/**
|
||||
This method can be used in unit tests to ensure that built in shared sequences are using mock schedulers instead
|
||||
of main schedulers.
|
||||
|
||||
**This shouldn't be used in normal release builds.**
|
||||
*/
|
||||
static public func mock(makeScheduler: @escaping () -> SchedulerType, action: () throws -> Void) rethrows {
|
||||
let originalMake = make
|
||||
make = makeScheduler
|
||||
defer {
|
||||
make = originalMake
|
||||
}
|
||||
|
||||
try action()
|
||||
|
||||
// If you remove this line , compiler buggy optimizations will change behavior of this code
|
||||
_forceCompilerToStopDoingInsaneOptimizationsThatBreakCode(makeScheduler)
|
||||
// Scary, I know
|
||||
}
|
||||
}
|
||||
|
||||
#if os(Linux)
|
||||
import Glibc
|
||||
#else
|
||||
import Foundation
|
||||
#endif
|
||||
|
||||
func _forceCompilerToStopDoingInsaneOptimizationsThatBreakCode(_ scheduler: () -> SchedulerType) {
|
||||
let a: Int32 = 1
|
||||
#if os(Linux)
|
||||
let b = 314 + Int32(Glibc.random() & 1)
|
||||
#else
|
||||
let b = 314 + Int32(arc4random() & 1)
|
||||
#endif
|
||||
if a == b {
|
||||
print(scheduler())
|
||||
}
|
||||
}
|
||||
42
Pods/RxCocoa/RxCocoa/Traits/SharedSequence/SharedSequence+Concurrency.swift
generated
Normal file
42
Pods/RxCocoa/RxCocoa/Traits/SharedSequence/SharedSequence+Concurrency.swift
generated
Normal file
@@ -0,0 +1,42 @@
|
||||
//
|
||||
// SharedSequence+Concurrency.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Shai Mishali on 22/09/2021.
|
||||
// Copyright © 2021 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if swift(>=5.5.2) && canImport(_Concurrency) && !os(Linux)
|
||||
import Foundation
|
||||
|
||||
// MARK: - Shared Sequence
|
||||
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
|
||||
public extension SharedSequence {
|
||||
/// Allows iterating over the values of this Shared Sequence
|
||||
/// asynchronously via Swift's concurrency features (`async/await`)
|
||||
///
|
||||
/// A sample usage would look like so:
|
||||
///
|
||||
/// ```swift
|
||||
/// for await value in driver.values {
|
||||
/// // Handle emitted values
|
||||
/// }
|
||||
/// ```
|
||||
@MainActor var values: AsyncStream<Element> {
|
||||
AsyncStream { continuation in
|
||||
// It is safe to ignore the `onError` closure here since
|
||||
// Shared Sequences (`Driver` and `Signal`) cannot fail
|
||||
let disposable = self.asObservable()
|
||||
.subscribe(
|
||||
onNext: { value in continuation.yield(value) },
|
||||
onCompleted: { continuation.finish() },
|
||||
onDisposed: { continuation.onTermination?(.cancelled) }
|
||||
)
|
||||
|
||||
continuation.onTermination = { @Sendable _ in
|
||||
disposable.dispose()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
656
Pods/RxCocoa/RxCocoa/Traits/SharedSequence/SharedSequence+Operators+arity.swift
generated
Normal file
656
Pods/RxCocoa/RxCocoa/Traits/SharedSequence/SharedSequence+Operators+arity.swift
generated
Normal file
@@ -0,0 +1,656 @@
|
||||
// This file is autogenerated. Take a look at `Preprocessor` target in RxSwift project
|
||||
//
|
||||
// SharedSequence+Operators+arity.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 10/14/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
import RxSwift
|
||||
|
||||
|
||||
|
||||
// 2
|
||||
|
||||
extension SharedSequence {
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index.
|
||||
|
||||
- parameter resultSelector: Function to invoke for each series of elements at corresponding indexes in the sources.
|
||||
- returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function.
|
||||
*/
|
||||
public static func zip<O1: SharedSequenceConvertibleType, O2: SharedSequenceConvertibleType>
|
||||
(_ source1: O1, _ source2: O2, resultSelector: @escaping (O1.Element, O2.Element) throws -> Element)
|
||||
-> SharedSequence<O1.SharingStrategy, Element> where SharingStrategy == O1.SharingStrategy,
|
||||
SharingStrategy == O2.SharingStrategy {
|
||||
let source = Observable.zip(
|
||||
source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(),
|
||||
resultSelector: resultSelector
|
||||
)
|
||||
|
||||
return SharedSequence<SharingStrategy, Element>(source)
|
||||
}
|
||||
}
|
||||
|
||||
extension SharedSequenceConvertibleType where Element == Any {
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence of element tuples whenever all of the observable sequences have produced an element at a corresponding index.
|
||||
|
||||
- returns: An observable sequence containing the result of combining elements of the sources.
|
||||
*/
|
||||
public static func zip<O1: SharedSequenceConvertibleType, O2: SharedSequenceConvertibleType>
|
||||
(_ source1: O1, _ source2: O2)
|
||||
-> SharedSequence<O1.SharingStrategy, (O1.Element, O2.Element)> where SharingStrategy == O1.SharingStrategy,
|
||||
SharingStrategy == O2.SharingStrategy {
|
||||
let source = Observable.zip(
|
||||
source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable()
|
||||
)
|
||||
|
||||
return SharedSequence<SharingStrategy, (O1.Element, O2.Element)>(source)
|
||||
}
|
||||
}
|
||||
|
||||
extension SharedSequence {
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element.
|
||||
|
||||
- parameter resultSelector: Function to invoke whenever any of the sources produces an element.
|
||||
- returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function.
|
||||
*/
|
||||
public static func combineLatest<O1: SharedSequenceConvertibleType, O2: SharedSequenceConvertibleType>
|
||||
(_ source1: O1, _ source2: O2, resultSelector: @escaping (O1.Element, O2.Element) throws -> Element)
|
||||
-> SharedSequence<SharingStrategy, Element> where SharingStrategy == O1.SharingStrategy,
|
||||
SharingStrategy == O2.SharingStrategy {
|
||||
let source = Observable.combineLatest(
|
||||
source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(),
|
||||
resultSelector: resultSelector
|
||||
)
|
||||
|
||||
return SharedSequence<O1.SharingStrategy, Element>(source)
|
||||
}
|
||||
}
|
||||
|
||||
extension SharedSequenceConvertibleType where Element == Any {
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence of element tuples whenever any of the observable sequences produces an element.
|
||||
|
||||
- returns: An observable sequence containing the result of combining elements of the sources.
|
||||
*/
|
||||
public static func combineLatest<O1: SharedSequenceConvertibleType, O2: SharedSequenceConvertibleType>
|
||||
(_ source1: O1, _ source2: O2)
|
||||
-> SharedSequence<SharingStrategy, (O1.Element, O2.Element)> where SharingStrategy == O1.SharingStrategy,
|
||||
SharingStrategy == O2.SharingStrategy {
|
||||
let source = Observable.combineLatest(
|
||||
source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable()
|
||||
)
|
||||
|
||||
return SharedSequence<O1.SharingStrategy, (O1.Element, O2.Element)>(source)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 3
|
||||
|
||||
extension SharedSequence {
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index.
|
||||
|
||||
- parameter resultSelector: Function to invoke for each series of elements at corresponding indexes in the sources.
|
||||
- returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function.
|
||||
*/
|
||||
public static func zip<O1: SharedSequenceConvertibleType, O2: SharedSequenceConvertibleType, O3: SharedSequenceConvertibleType>
|
||||
(_ source1: O1, _ source2: O2, _ source3: O3, resultSelector: @escaping (O1.Element, O2.Element, O3.Element) throws -> Element)
|
||||
-> SharedSequence<O1.SharingStrategy, Element> where SharingStrategy == O1.SharingStrategy,
|
||||
SharingStrategy == O2.SharingStrategy,
|
||||
SharingStrategy == O3.SharingStrategy {
|
||||
let source = Observable.zip(
|
||||
source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(),
|
||||
resultSelector: resultSelector
|
||||
)
|
||||
|
||||
return SharedSequence<SharingStrategy, Element>(source)
|
||||
}
|
||||
}
|
||||
|
||||
extension SharedSequenceConvertibleType where Element == Any {
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence of element tuples whenever all of the observable sequences have produced an element at a corresponding index.
|
||||
|
||||
- returns: An observable sequence containing the result of combining elements of the sources.
|
||||
*/
|
||||
public static func zip<O1: SharedSequenceConvertibleType, O2: SharedSequenceConvertibleType, O3: SharedSequenceConvertibleType>
|
||||
(_ source1: O1, _ source2: O2, _ source3: O3)
|
||||
-> SharedSequence<O1.SharingStrategy, (O1.Element, O2.Element, O3.Element)> where SharingStrategy == O1.SharingStrategy,
|
||||
SharingStrategy == O2.SharingStrategy,
|
||||
SharingStrategy == O3.SharingStrategy {
|
||||
let source = Observable.zip(
|
||||
source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable()
|
||||
)
|
||||
|
||||
return SharedSequence<SharingStrategy, (O1.Element, O2.Element, O3.Element)>(source)
|
||||
}
|
||||
}
|
||||
|
||||
extension SharedSequence {
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element.
|
||||
|
||||
- parameter resultSelector: Function to invoke whenever any of the sources produces an element.
|
||||
- returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function.
|
||||
*/
|
||||
public static func combineLatest<O1: SharedSequenceConvertibleType, O2: SharedSequenceConvertibleType, O3: SharedSequenceConvertibleType>
|
||||
(_ source1: O1, _ source2: O2, _ source3: O3, resultSelector: @escaping (O1.Element, O2.Element, O3.Element) throws -> Element)
|
||||
-> SharedSequence<SharingStrategy, Element> where SharingStrategy == O1.SharingStrategy,
|
||||
SharingStrategy == O2.SharingStrategy,
|
||||
SharingStrategy == O3.SharingStrategy {
|
||||
let source = Observable.combineLatest(
|
||||
source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(),
|
||||
resultSelector: resultSelector
|
||||
)
|
||||
|
||||
return SharedSequence<O1.SharingStrategy, Element>(source)
|
||||
}
|
||||
}
|
||||
|
||||
extension SharedSequenceConvertibleType where Element == Any {
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence of element tuples whenever any of the observable sequences produces an element.
|
||||
|
||||
- returns: An observable sequence containing the result of combining elements of the sources.
|
||||
*/
|
||||
public static func combineLatest<O1: SharedSequenceConvertibleType, O2: SharedSequenceConvertibleType, O3: SharedSequenceConvertibleType>
|
||||
(_ source1: O1, _ source2: O2, _ source3: O3)
|
||||
-> SharedSequence<SharingStrategy, (O1.Element, O2.Element, O3.Element)> where SharingStrategy == O1.SharingStrategy,
|
||||
SharingStrategy == O2.SharingStrategy,
|
||||
SharingStrategy == O3.SharingStrategy {
|
||||
let source = Observable.combineLatest(
|
||||
source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable()
|
||||
)
|
||||
|
||||
return SharedSequence<O1.SharingStrategy, (O1.Element, O2.Element, O3.Element)>(source)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 4
|
||||
|
||||
extension SharedSequence {
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index.
|
||||
|
||||
- parameter resultSelector: Function to invoke for each series of elements at corresponding indexes in the sources.
|
||||
- returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function.
|
||||
*/
|
||||
public static func zip<O1: SharedSequenceConvertibleType, O2: SharedSequenceConvertibleType, O3: SharedSequenceConvertibleType, O4: SharedSequenceConvertibleType>
|
||||
(_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element) throws -> Element)
|
||||
-> SharedSequence<O1.SharingStrategy, Element> where SharingStrategy == O1.SharingStrategy,
|
||||
SharingStrategy == O2.SharingStrategy,
|
||||
SharingStrategy == O3.SharingStrategy,
|
||||
SharingStrategy == O4.SharingStrategy {
|
||||
let source = Observable.zip(
|
||||
source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable(),
|
||||
resultSelector: resultSelector
|
||||
)
|
||||
|
||||
return SharedSequence<SharingStrategy, Element>(source)
|
||||
}
|
||||
}
|
||||
|
||||
extension SharedSequenceConvertibleType where Element == Any {
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence of element tuples whenever all of the observable sequences have produced an element at a corresponding index.
|
||||
|
||||
- returns: An observable sequence containing the result of combining elements of the sources.
|
||||
*/
|
||||
public static func zip<O1: SharedSequenceConvertibleType, O2: SharedSequenceConvertibleType, O3: SharedSequenceConvertibleType, O4: SharedSequenceConvertibleType>
|
||||
(_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4)
|
||||
-> SharedSequence<O1.SharingStrategy, (O1.Element, O2.Element, O3.Element, O4.Element)> where SharingStrategy == O1.SharingStrategy,
|
||||
SharingStrategy == O2.SharingStrategy,
|
||||
SharingStrategy == O3.SharingStrategy,
|
||||
SharingStrategy == O4.SharingStrategy {
|
||||
let source = Observable.zip(
|
||||
source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable()
|
||||
)
|
||||
|
||||
return SharedSequence<SharingStrategy, (O1.Element, O2.Element, O3.Element, O4.Element)>(source)
|
||||
}
|
||||
}
|
||||
|
||||
extension SharedSequence {
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element.
|
||||
|
||||
- parameter resultSelector: Function to invoke whenever any of the sources produces an element.
|
||||
- returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function.
|
||||
*/
|
||||
public static func combineLatest<O1: SharedSequenceConvertibleType, O2: SharedSequenceConvertibleType, O3: SharedSequenceConvertibleType, O4: SharedSequenceConvertibleType>
|
||||
(_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element) throws -> Element)
|
||||
-> SharedSequence<SharingStrategy, Element> where SharingStrategy == O1.SharingStrategy,
|
||||
SharingStrategy == O2.SharingStrategy,
|
||||
SharingStrategy == O3.SharingStrategy,
|
||||
SharingStrategy == O4.SharingStrategy {
|
||||
let source = Observable.combineLatest(
|
||||
source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable(),
|
||||
resultSelector: resultSelector
|
||||
)
|
||||
|
||||
return SharedSequence<O1.SharingStrategy, Element>(source)
|
||||
}
|
||||
}
|
||||
|
||||
extension SharedSequenceConvertibleType where Element == Any {
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence of element tuples whenever any of the observable sequences produces an element.
|
||||
|
||||
- returns: An observable sequence containing the result of combining elements of the sources.
|
||||
*/
|
||||
public static func combineLatest<O1: SharedSequenceConvertibleType, O2: SharedSequenceConvertibleType, O3: SharedSequenceConvertibleType, O4: SharedSequenceConvertibleType>
|
||||
(_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4)
|
||||
-> SharedSequence<SharingStrategy, (O1.Element, O2.Element, O3.Element, O4.Element)> where SharingStrategy == O1.SharingStrategy,
|
||||
SharingStrategy == O2.SharingStrategy,
|
||||
SharingStrategy == O3.SharingStrategy,
|
||||
SharingStrategy == O4.SharingStrategy {
|
||||
let source = Observable.combineLatest(
|
||||
source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable()
|
||||
)
|
||||
|
||||
return SharedSequence<O1.SharingStrategy, (O1.Element, O2.Element, O3.Element, O4.Element)>(source)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 5
|
||||
|
||||
extension SharedSequence {
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index.
|
||||
|
||||
- parameter resultSelector: Function to invoke for each series of elements at corresponding indexes in the sources.
|
||||
- returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function.
|
||||
*/
|
||||
public static func zip<O1: SharedSequenceConvertibleType, O2: SharedSequenceConvertibleType, O3: SharedSequenceConvertibleType, O4: SharedSequenceConvertibleType, O5: SharedSequenceConvertibleType>
|
||||
(_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element) throws -> Element)
|
||||
-> SharedSequence<O1.SharingStrategy, Element> where SharingStrategy == O1.SharingStrategy,
|
||||
SharingStrategy == O2.SharingStrategy,
|
||||
SharingStrategy == O3.SharingStrategy,
|
||||
SharingStrategy == O4.SharingStrategy,
|
||||
SharingStrategy == O5.SharingStrategy {
|
||||
let source = Observable.zip(
|
||||
source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable(), source5.asSharedSequence().asObservable(),
|
||||
resultSelector: resultSelector
|
||||
)
|
||||
|
||||
return SharedSequence<SharingStrategy, Element>(source)
|
||||
}
|
||||
}
|
||||
|
||||
extension SharedSequenceConvertibleType where Element == Any {
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence of element tuples whenever all of the observable sequences have produced an element at a corresponding index.
|
||||
|
||||
- returns: An observable sequence containing the result of combining elements of the sources.
|
||||
*/
|
||||
public static func zip<O1: SharedSequenceConvertibleType, O2: SharedSequenceConvertibleType, O3: SharedSequenceConvertibleType, O4: SharedSequenceConvertibleType, O5: SharedSequenceConvertibleType>
|
||||
(_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5)
|
||||
-> SharedSequence<O1.SharingStrategy, (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element)> where SharingStrategy == O1.SharingStrategy,
|
||||
SharingStrategy == O2.SharingStrategy,
|
||||
SharingStrategy == O3.SharingStrategy,
|
||||
SharingStrategy == O4.SharingStrategy,
|
||||
SharingStrategy == O5.SharingStrategy {
|
||||
let source = Observable.zip(
|
||||
source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable(), source5.asSharedSequence().asObservable()
|
||||
)
|
||||
|
||||
return SharedSequence<SharingStrategy, (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element)>(source)
|
||||
}
|
||||
}
|
||||
|
||||
extension SharedSequence {
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element.
|
||||
|
||||
- parameter resultSelector: Function to invoke whenever any of the sources produces an element.
|
||||
- returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function.
|
||||
*/
|
||||
public static func combineLatest<O1: SharedSequenceConvertibleType, O2: SharedSequenceConvertibleType, O3: SharedSequenceConvertibleType, O4: SharedSequenceConvertibleType, O5: SharedSequenceConvertibleType>
|
||||
(_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element) throws -> Element)
|
||||
-> SharedSequence<SharingStrategy, Element> where SharingStrategy == O1.SharingStrategy,
|
||||
SharingStrategy == O2.SharingStrategy,
|
||||
SharingStrategy == O3.SharingStrategy,
|
||||
SharingStrategy == O4.SharingStrategy,
|
||||
SharingStrategy == O5.SharingStrategy {
|
||||
let source = Observable.combineLatest(
|
||||
source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable(), source5.asSharedSequence().asObservable(),
|
||||
resultSelector: resultSelector
|
||||
)
|
||||
|
||||
return SharedSequence<O1.SharingStrategy, Element>(source)
|
||||
}
|
||||
}
|
||||
|
||||
extension SharedSequenceConvertibleType where Element == Any {
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence of element tuples whenever any of the observable sequences produces an element.
|
||||
|
||||
- returns: An observable sequence containing the result of combining elements of the sources.
|
||||
*/
|
||||
public static func combineLatest<O1: SharedSequenceConvertibleType, O2: SharedSequenceConvertibleType, O3: SharedSequenceConvertibleType, O4: SharedSequenceConvertibleType, O5: SharedSequenceConvertibleType>
|
||||
(_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5)
|
||||
-> SharedSequence<SharingStrategy, (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element)> where SharingStrategy == O1.SharingStrategy,
|
||||
SharingStrategy == O2.SharingStrategy,
|
||||
SharingStrategy == O3.SharingStrategy,
|
||||
SharingStrategy == O4.SharingStrategy,
|
||||
SharingStrategy == O5.SharingStrategy {
|
||||
let source = Observable.combineLatest(
|
||||
source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable(), source5.asSharedSequence().asObservable()
|
||||
)
|
||||
|
||||
return SharedSequence<O1.SharingStrategy, (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element)>(source)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 6
|
||||
|
||||
extension SharedSequence {
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index.
|
||||
|
||||
- parameter resultSelector: Function to invoke for each series of elements at corresponding indexes in the sources.
|
||||
- returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function.
|
||||
*/
|
||||
public static func zip<O1: SharedSequenceConvertibleType, O2: SharedSequenceConvertibleType, O3: SharedSequenceConvertibleType, O4: SharedSequenceConvertibleType, O5: SharedSequenceConvertibleType, O6: SharedSequenceConvertibleType>
|
||||
(_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element) throws -> Element)
|
||||
-> SharedSequence<O1.SharingStrategy, Element> where SharingStrategy == O1.SharingStrategy,
|
||||
SharingStrategy == O2.SharingStrategy,
|
||||
SharingStrategy == O3.SharingStrategy,
|
||||
SharingStrategy == O4.SharingStrategy,
|
||||
SharingStrategy == O5.SharingStrategy,
|
||||
SharingStrategy == O6.SharingStrategy {
|
||||
let source = Observable.zip(
|
||||
source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable(), source5.asSharedSequence().asObservable(), source6.asSharedSequence().asObservable(),
|
||||
resultSelector: resultSelector
|
||||
)
|
||||
|
||||
return SharedSequence<SharingStrategy, Element>(source)
|
||||
}
|
||||
}
|
||||
|
||||
extension SharedSequenceConvertibleType where Element == Any {
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence of element tuples whenever all of the observable sequences have produced an element at a corresponding index.
|
||||
|
||||
- returns: An observable sequence containing the result of combining elements of the sources.
|
||||
*/
|
||||
public static func zip<O1: SharedSequenceConvertibleType, O2: SharedSequenceConvertibleType, O3: SharedSequenceConvertibleType, O4: SharedSequenceConvertibleType, O5: SharedSequenceConvertibleType, O6: SharedSequenceConvertibleType>
|
||||
(_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6)
|
||||
-> SharedSequence<O1.SharingStrategy, (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element)> where SharingStrategy == O1.SharingStrategy,
|
||||
SharingStrategy == O2.SharingStrategy,
|
||||
SharingStrategy == O3.SharingStrategy,
|
||||
SharingStrategy == O4.SharingStrategy,
|
||||
SharingStrategy == O5.SharingStrategy,
|
||||
SharingStrategy == O6.SharingStrategy {
|
||||
let source = Observable.zip(
|
||||
source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable(), source5.asSharedSequence().asObservable(), source6.asSharedSequence().asObservable()
|
||||
)
|
||||
|
||||
return SharedSequence<SharingStrategy, (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element)>(source)
|
||||
}
|
||||
}
|
||||
|
||||
extension SharedSequence {
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element.
|
||||
|
||||
- parameter resultSelector: Function to invoke whenever any of the sources produces an element.
|
||||
- returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function.
|
||||
*/
|
||||
public static func combineLatest<O1: SharedSequenceConvertibleType, O2: SharedSequenceConvertibleType, O3: SharedSequenceConvertibleType, O4: SharedSequenceConvertibleType, O5: SharedSequenceConvertibleType, O6: SharedSequenceConvertibleType>
|
||||
(_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element) throws -> Element)
|
||||
-> SharedSequence<SharingStrategy, Element> where SharingStrategy == O1.SharingStrategy,
|
||||
SharingStrategy == O2.SharingStrategy,
|
||||
SharingStrategy == O3.SharingStrategy,
|
||||
SharingStrategy == O4.SharingStrategy,
|
||||
SharingStrategy == O5.SharingStrategy,
|
||||
SharingStrategy == O6.SharingStrategy {
|
||||
let source = Observable.combineLatest(
|
||||
source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable(), source5.asSharedSequence().asObservable(), source6.asSharedSequence().asObservable(),
|
||||
resultSelector: resultSelector
|
||||
)
|
||||
|
||||
return SharedSequence<O1.SharingStrategy, Element>(source)
|
||||
}
|
||||
}
|
||||
|
||||
extension SharedSequenceConvertibleType where Element == Any {
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence of element tuples whenever any of the observable sequences produces an element.
|
||||
|
||||
- returns: An observable sequence containing the result of combining elements of the sources.
|
||||
*/
|
||||
public static func combineLatest<O1: SharedSequenceConvertibleType, O2: SharedSequenceConvertibleType, O3: SharedSequenceConvertibleType, O4: SharedSequenceConvertibleType, O5: SharedSequenceConvertibleType, O6: SharedSequenceConvertibleType>
|
||||
(_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6)
|
||||
-> SharedSequence<SharingStrategy, (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element)> where SharingStrategy == O1.SharingStrategy,
|
||||
SharingStrategy == O2.SharingStrategy,
|
||||
SharingStrategy == O3.SharingStrategy,
|
||||
SharingStrategy == O4.SharingStrategy,
|
||||
SharingStrategy == O5.SharingStrategy,
|
||||
SharingStrategy == O6.SharingStrategy {
|
||||
let source = Observable.combineLatest(
|
||||
source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable(), source5.asSharedSequence().asObservable(), source6.asSharedSequence().asObservable()
|
||||
)
|
||||
|
||||
return SharedSequence<O1.SharingStrategy, (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element)>(source)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 7
|
||||
|
||||
extension SharedSequence {
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index.
|
||||
|
||||
- parameter resultSelector: Function to invoke for each series of elements at corresponding indexes in the sources.
|
||||
- returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function.
|
||||
*/
|
||||
public static func zip<O1: SharedSequenceConvertibleType, O2: SharedSequenceConvertibleType, O3: SharedSequenceConvertibleType, O4: SharedSequenceConvertibleType, O5: SharedSequenceConvertibleType, O6: SharedSequenceConvertibleType, O7: SharedSequenceConvertibleType>
|
||||
(_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, _ source7: O7, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element, O7.Element) throws -> Element)
|
||||
-> SharedSequence<O1.SharingStrategy, Element> where SharingStrategy == O1.SharingStrategy,
|
||||
SharingStrategy == O2.SharingStrategy,
|
||||
SharingStrategy == O3.SharingStrategy,
|
||||
SharingStrategy == O4.SharingStrategy,
|
||||
SharingStrategy == O5.SharingStrategy,
|
||||
SharingStrategy == O6.SharingStrategy,
|
||||
SharingStrategy == O7.SharingStrategy {
|
||||
let source = Observable.zip(
|
||||
source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable(), source5.asSharedSequence().asObservable(), source6.asSharedSequence().asObservable(), source7.asSharedSequence().asObservable(),
|
||||
resultSelector: resultSelector
|
||||
)
|
||||
|
||||
return SharedSequence<SharingStrategy, Element>(source)
|
||||
}
|
||||
}
|
||||
|
||||
extension SharedSequenceConvertibleType where Element == Any {
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence of element tuples whenever all of the observable sequences have produced an element at a corresponding index.
|
||||
|
||||
- returns: An observable sequence containing the result of combining elements of the sources.
|
||||
*/
|
||||
public static func zip<O1: SharedSequenceConvertibleType, O2: SharedSequenceConvertibleType, O3: SharedSequenceConvertibleType, O4: SharedSequenceConvertibleType, O5: SharedSequenceConvertibleType, O6: SharedSequenceConvertibleType, O7: SharedSequenceConvertibleType>
|
||||
(_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, _ source7: O7)
|
||||
-> SharedSequence<O1.SharingStrategy, (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element, O7.Element)> where SharingStrategy == O1.SharingStrategy,
|
||||
SharingStrategy == O2.SharingStrategy,
|
||||
SharingStrategy == O3.SharingStrategy,
|
||||
SharingStrategy == O4.SharingStrategy,
|
||||
SharingStrategy == O5.SharingStrategy,
|
||||
SharingStrategy == O6.SharingStrategy,
|
||||
SharingStrategy == O7.SharingStrategy {
|
||||
let source = Observable.zip(
|
||||
source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable(), source5.asSharedSequence().asObservable(), source6.asSharedSequence().asObservable(), source7.asSharedSequence().asObservable()
|
||||
)
|
||||
|
||||
return SharedSequence<SharingStrategy, (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element, O7.Element)>(source)
|
||||
}
|
||||
}
|
||||
|
||||
extension SharedSequence {
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element.
|
||||
|
||||
- parameter resultSelector: Function to invoke whenever any of the sources produces an element.
|
||||
- returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function.
|
||||
*/
|
||||
public static func combineLatest<O1: SharedSequenceConvertibleType, O2: SharedSequenceConvertibleType, O3: SharedSequenceConvertibleType, O4: SharedSequenceConvertibleType, O5: SharedSequenceConvertibleType, O6: SharedSequenceConvertibleType, O7: SharedSequenceConvertibleType>
|
||||
(_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, _ source7: O7, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element, O7.Element) throws -> Element)
|
||||
-> SharedSequence<SharingStrategy, Element> where SharingStrategy == O1.SharingStrategy,
|
||||
SharingStrategy == O2.SharingStrategy,
|
||||
SharingStrategy == O3.SharingStrategy,
|
||||
SharingStrategy == O4.SharingStrategy,
|
||||
SharingStrategy == O5.SharingStrategy,
|
||||
SharingStrategy == O6.SharingStrategy,
|
||||
SharingStrategy == O7.SharingStrategy {
|
||||
let source = Observable.combineLatest(
|
||||
source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable(), source5.asSharedSequence().asObservable(), source6.asSharedSequence().asObservable(), source7.asSharedSequence().asObservable(),
|
||||
resultSelector: resultSelector
|
||||
)
|
||||
|
||||
return SharedSequence<O1.SharingStrategy, Element>(source)
|
||||
}
|
||||
}
|
||||
|
||||
extension SharedSequenceConvertibleType where Element == Any {
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence of element tuples whenever any of the observable sequences produces an element.
|
||||
|
||||
- returns: An observable sequence containing the result of combining elements of the sources.
|
||||
*/
|
||||
public static func combineLatest<O1: SharedSequenceConvertibleType, O2: SharedSequenceConvertibleType, O3: SharedSequenceConvertibleType, O4: SharedSequenceConvertibleType, O5: SharedSequenceConvertibleType, O6: SharedSequenceConvertibleType, O7: SharedSequenceConvertibleType>
|
||||
(_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, _ source7: O7)
|
||||
-> SharedSequence<SharingStrategy, (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element, O7.Element)> where SharingStrategy == O1.SharingStrategy,
|
||||
SharingStrategy == O2.SharingStrategy,
|
||||
SharingStrategy == O3.SharingStrategy,
|
||||
SharingStrategy == O4.SharingStrategy,
|
||||
SharingStrategy == O5.SharingStrategy,
|
||||
SharingStrategy == O6.SharingStrategy,
|
||||
SharingStrategy == O7.SharingStrategy {
|
||||
let source = Observable.combineLatest(
|
||||
source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable(), source5.asSharedSequence().asObservable(), source6.asSharedSequence().asObservable(), source7.asSharedSequence().asObservable()
|
||||
)
|
||||
|
||||
return SharedSequence<O1.SharingStrategy, (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element, O7.Element)>(source)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 8
|
||||
|
||||
extension SharedSequence {
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index.
|
||||
|
||||
- parameter resultSelector: Function to invoke for each series of elements at corresponding indexes in the sources.
|
||||
- returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function.
|
||||
*/
|
||||
public static func zip<O1: SharedSequenceConvertibleType, O2: SharedSequenceConvertibleType, O3: SharedSequenceConvertibleType, O4: SharedSequenceConvertibleType, O5: SharedSequenceConvertibleType, O6: SharedSequenceConvertibleType, O7: SharedSequenceConvertibleType, O8: SharedSequenceConvertibleType>
|
||||
(_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, _ source7: O7, _ source8: O8, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element, O7.Element, O8.Element) throws -> Element)
|
||||
-> SharedSequence<O1.SharingStrategy, Element> where SharingStrategy == O1.SharingStrategy,
|
||||
SharingStrategy == O2.SharingStrategy,
|
||||
SharingStrategy == O3.SharingStrategy,
|
||||
SharingStrategy == O4.SharingStrategy,
|
||||
SharingStrategy == O5.SharingStrategy,
|
||||
SharingStrategy == O6.SharingStrategy,
|
||||
SharingStrategy == O7.SharingStrategy,
|
||||
SharingStrategy == O8.SharingStrategy {
|
||||
let source = Observable.zip(
|
||||
source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable(), source5.asSharedSequence().asObservable(), source6.asSharedSequence().asObservable(), source7.asSharedSequence().asObservable(), source8.asSharedSequence().asObservable(),
|
||||
resultSelector: resultSelector
|
||||
)
|
||||
|
||||
return SharedSequence<SharingStrategy, Element>(source)
|
||||
}
|
||||
}
|
||||
|
||||
extension SharedSequenceConvertibleType where Element == Any {
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence of element tuples whenever all of the observable sequences have produced an element at a corresponding index.
|
||||
|
||||
- returns: An observable sequence containing the result of combining elements of the sources.
|
||||
*/
|
||||
public static func zip<O1: SharedSequenceConvertibleType, O2: SharedSequenceConvertibleType, O3: SharedSequenceConvertibleType, O4: SharedSequenceConvertibleType, O5: SharedSequenceConvertibleType, O6: SharedSequenceConvertibleType, O7: SharedSequenceConvertibleType, O8: SharedSequenceConvertibleType>
|
||||
(_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, _ source7: O7, _ source8: O8)
|
||||
-> SharedSequence<O1.SharingStrategy, (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element, O7.Element, O8.Element)> where SharingStrategy == O1.SharingStrategy,
|
||||
SharingStrategy == O2.SharingStrategy,
|
||||
SharingStrategy == O3.SharingStrategy,
|
||||
SharingStrategy == O4.SharingStrategy,
|
||||
SharingStrategy == O5.SharingStrategy,
|
||||
SharingStrategy == O6.SharingStrategy,
|
||||
SharingStrategy == O7.SharingStrategy,
|
||||
SharingStrategy == O8.SharingStrategy {
|
||||
let source = Observable.zip(
|
||||
source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable(), source5.asSharedSequence().asObservable(), source6.asSharedSequence().asObservable(), source7.asSharedSequence().asObservable(), source8.asSharedSequence().asObservable()
|
||||
)
|
||||
|
||||
return SharedSequence<SharingStrategy, (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element, O7.Element, O8.Element)>(source)
|
||||
}
|
||||
}
|
||||
|
||||
extension SharedSequence {
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element.
|
||||
|
||||
- parameter resultSelector: Function to invoke whenever any of the sources produces an element.
|
||||
- returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function.
|
||||
*/
|
||||
public static func combineLatest<O1: SharedSequenceConvertibleType, O2: SharedSequenceConvertibleType, O3: SharedSequenceConvertibleType, O4: SharedSequenceConvertibleType, O5: SharedSequenceConvertibleType, O6: SharedSequenceConvertibleType, O7: SharedSequenceConvertibleType, O8: SharedSequenceConvertibleType>
|
||||
(_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, _ source7: O7, _ source8: O8, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element, O7.Element, O8.Element) throws -> Element)
|
||||
-> SharedSequence<SharingStrategy, Element> where SharingStrategy == O1.SharingStrategy,
|
||||
SharingStrategy == O2.SharingStrategy,
|
||||
SharingStrategy == O3.SharingStrategy,
|
||||
SharingStrategy == O4.SharingStrategy,
|
||||
SharingStrategy == O5.SharingStrategy,
|
||||
SharingStrategy == O6.SharingStrategy,
|
||||
SharingStrategy == O7.SharingStrategy,
|
||||
SharingStrategy == O8.SharingStrategy {
|
||||
let source = Observable.combineLatest(
|
||||
source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable(), source5.asSharedSequence().asObservable(), source6.asSharedSequence().asObservable(), source7.asSharedSequence().asObservable(), source8.asSharedSequence().asObservable(),
|
||||
resultSelector: resultSelector
|
||||
)
|
||||
|
||||
return SharedSequence<O1.SharingStrategy, Element>(source)
|
||||
}
|
||||
}
|
||||
|
||||
extension SharedSequenceConvertibleType where Element == Any {
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence of element tuples whenever any of the observable sequences produces an element.
|
||||
|
||||
- returns: An observable sequence containing the result of combining elements of the sources.
|
||||
*/
|
||||
public static func combineLatest<O1: SharedSequenceConvertibleType, O2: SharedSequenceConvertibleType, O3: SharedSequenceConvertibleType, O4: SharedSequenceConvertibleType, O5: SharedSequenceConvertibleType, O6: SharedSequenceConvertibleType, O7: SharedSequenceConvertibleType, O8: SharedSequenceConvertibleType>
|
||||
(_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, _ source7: O7, _ source8: O8)
|
||||
-> SharedSequence<SharingStrategy, (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element, O7.Element, O8.Element)> where SharingStrategy == O1.SharingStrategy,
|
||||
SharingStrategy == O2.SharingStrategy,
|
||||
SharingStrategy == O3.SharingStrategy,
|
||||
SharingStrategy == O4.SharingStrategy,
|
||||
SharingStrategy == O5.SharingStrategy,
|
||||
SharingStrategy == O6.SharingStrategy,
|
||||
SharingStrategy == O7.SharingStrategy,
|
||||
SharingStrategy == O8.SharingStrategy {
|
||||
let source = Observable.combineLatest(
|
||||
source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable(), source5.asSharedSequence().asObservable(), source6.asSharedSequence().asObservable(), source7.asSharedSequence().asObservable(), source8.asSharedSequence().asObservable()
|
||||
)
|
||||
|
||||
return SharedSequence<O1.SharingStrategy, (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element, O7.Element, O8.Element)>(source)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
584
Pods/RxCocoa/RxCocoa/Traits/SharedSequence/SharedSequence+Operators.swift
generated
Normal file
584
Pods/RxCocoa/RxCocoa/Traits/SharedSequence/SharedSequence+Operators.swift
generated
Normal file
@@ -0,0 +1,584 @@
|
||||
//
|
||||
// SharedSequence+Operators.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 9/19/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
import RxSwift
|
||||
|
||||
// MARK: map
|
||||
extension SharedSequenceConvertibleType {
|
||||
|
||||
/**
|
||||
Projects each element of an observable sequence into a new form.
|
||||
|
||||
- parameter selector: A transform function to apply to each source element.
|
||||
- returns: An observable sequence whose elements are the result of invoking the transform function on each element of source.
|
||||
*/
|
||||
public func map<Result>(_ selector: @escaping (Element) -> Result) -> SharedSequence<SharingStrategy, Result> {
|
||||
let source = self
|
||||
.asObservable()
|
||||
.map(selector)
|
||||
return SharedSequence<SharingStrategy, Result>(source)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: compactMap
|
||||
extension SharedSequenceConvertibleType {
|
||||
|
||||
/**
|
||||
Projects each element of an observable sequence into an optional form and filters all optional results.
|
||||
|
||||
- parameter selector: A transform function to apply to each source element and which returns an element or nil.
|
||||
- returns: An observable sequence whose elements are the result of filtering the transform function for each element of the source.
|
||||
|
||||
*/
|
||||
public func compactMap<Result>(_ selector: @escaping (Element) -> Result?) -> SharedSequence<SharingStrategy, Result> {
|
||||
let source = self
|
||||
.asObservable()
|
||||
.compactMap(selector)
|
||||
return SharedSequence<SharingStrategy, Result>(source)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: filter
|
||||
extension SharedSequenceConvertibleType {
|
||||
/**
|
||||
Filters the elements of an observable sequence based on a predicate.
|
||||
|
||||
- parameter predicate: A function to test each source element for a condition.
|
||||
- returns: An observable sequence that contains elements from the input sequence that satisfy the condition.
|
||||
*/
|
||||
public func filter(_ predicate: @escaping (Element) -> Bool) -> SharedSequence<SharingStrategy, Element> {
|
||||
let source = self
|
||||
.asObservable()
|
||||
.filter(predicate)
|
||||
return SharedSequence(source)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: switchLatest
|
||||
extension SharedSequenceConvertibleType where Element: SharedSequenceConvertibleType {
|
||||
|
||||
/**
|
||||
Transforms an observable sequence of observable sequences into an observable sequence
|
||||
producing values only from the most recent observable sequence.
|
||||
|
||||
Each time a new inner observable sequence is received, unsubscribe from the
|
||||
previous inner observable sequence.
|
||||
|
||||
- returns: The observable sequence that at any point in time produces the elements of the most recent inner observable sequence that has been received.
|
||||
*/
|
||||
public func switchLatest() -> SharedSequence<Element.SharingStrategy, Element.Element> {
|
||||
let source: Observable<Element.Element> = self
|
||||
.asObservable()
|
||||
.map { $0.asSharedSequence() }
|
||||
.switchLatest()
|
||||
return SharedSequence<Element.SharingStrategy, Element.Element>(source)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: flatMapLatest
|
||||
extension SharedSequenceConvertibleType {
|
||||
/**
|
||||
Projects each element of an observable sequence into a new sequence of observable sequences and then
|
||||
transforms an observable sequence of observable sequences into an observable sequence producing values only from the most recent observable sequence.
|
||||
|
||||
It is a combination of `map` + `switchLatest` operator
|
||||
|
||||
- parameter selector: A transform function to apply to each element.
|
||||
- returns: An observable sequence whose elements are the result of invoking the transform function on each element of source producing an
|
||||
Observable of Observable sequences and that at any point in time produces the elements of the most recent inner observable sequence that has been received.
|
||||
*/
|
||||
public func flatMapLatest<Sharing, Result>(_ selector: @escaping (Element) -> SharedSequence<Sharing, Result>)
|
||||
-> SharedSequence<Sharing, Result> {
|
||||
let source: Observable<Result> = self
|
||||
.asObservable()
|
||||
.flatMapLatest(selector)
|
||||
return SharedSequence<Sharing, Result>(source)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: flatMapFirst
|
||||
extension SharedSequenceConvertibleType {
|
||||
|
||||
/**
|
||||
Projects each element of an observable sequence to an observable sequence and merges the resulting observable sequences into one observable sequence.
|
||||
If element is received while there is some projected observable sequence being merged it will simply be ignored.
|
||||
|
||||
- parameter selector: A transform function to apply to element that was observed while no observable is executing in parallel.
|
||||
- returns: An observable sequence whose elements are the result of invoking the one-to-many transform function on each element of the input sequence that was received while no other sequence was being calculated.
|
||||
*/
|
||||
public func flatMapFirst<Sharing, Result>(_ selector: @escaping (Element) -> SharedSequence<Sharing, Result>)
|
||||
-> SharedSequence<Sharing, Result> {
|
||||
let source: Observable<Result> = self
|
||||
.asObservable()
|
||||
.flatMapFirst(selector)
|
||||
return SharedSequence<Sharing, Result>(source)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: do
|
||||
extension SharedSequenceConvertibleType {
|
||||
/**
|
||||
Invokes an action for each event in the observable sequence, and propagates all observer messages through the result sequence.
|
||||
|
||||
- parameter onNext: Action to invoke for each element in the observable sequence.
|
||||
- parameter afterNext: Action to invoke for each element after the observable has passed an onNext event along to its downstream.
|
||||
- parameter onCompleted: Action to invoke upon graceful termination of the observable sequence.
|
||||
- parameter afterCompleted: Action to invoke after graceful termination of the observable sequence.
|
||||
- parameter onSubscribe: Action to invoke before subscribing to source observable sequence.
|
||||
- parameter onSubscribed: Action to invoke after subscribing to source observable sequence.
|
||||
- parameter onDispose: Action to invoke after subscription to source observable has been disposed for any reason. It can be either because sequence terminates for some reason or observer subscription being disposed.
|
||||
- returns: The source sequence with the side-effecting behavior applied.
|
||||
*/
|
||||
public func `do`(onNext: ((Element) -> Void)? = nil, afterNext: ((Element) -> Void)? = nil, onCompleted: (() -> Void)? = nil, afterCompleted: (() -> Void)? = nil, onSubscribe: (() -> Void)? = nil, onSubscribed: (() -> Void)? = nil, onDispose: (() -> Void)? = nil)
|
||||
-> SharedSequence<SharingStrategy, Element> {
|
||||
let source = self.asObservable()
|
||||
.do(onNext: onNext, afterNext: afterNext, onCompleted: onCompleted, afterCompleted: afterCompleted, onSubscribe: onSubscribe, onSubscribed: onSubscribed, onDispose: onDispose)
|
||||
|
||||
return SharedSequence(source)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: debug
|
||||
extension SharedSequenceConvertibleType {
|
||||
|
||||
/**
|
||||
Prints received events for all observers on standard output.
|
||||
|
||||
- parameter identifier: Identifier that is printed together with event description to standard output.
|
||||
- returns: An observable sequence whose events are printed to standard output.
|
||||
*/
|
||||
public func debug(_ identifier: String? = nil, trimOutput: Bool = false, file: String = #file, line: UInt = #line, function: String = #function) -> SharedSequence<SharingStrategy, Element> {
|
||||
let source = self.asObservable()
|
||||
.debug(identifier, trimOutput: trimOutput, file: file, line: line, function: function)
|
||||
return SharedSequence(source)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: distinctUntilChanged
|
||||
extension SharedSequenceConvertibleType where Element: Equatable {
|
||||
|
||||
/**
|
||||
Returns an observable sequence that contains only distinct contiguous elements according to equality operator.
|
||||
|
||||
- returns: An observable sequence only containing the distinct contiguous elements, based on equality operator, from the source sequence.
|
||||
*/
|
||||
public func distinctUntilChanged()
|
||||
-> SharedSequence<SharingStrategy, Element> {
|
||||
let source = self.asObservable()
|
||||
.distinctUntilChanged({ $0 }, comparer: { ($0 == $1) })
|
||||
|
||||
return SharedSequence(source)
|
||||
}
|
||||
}
|
||||
|
||||
extension SharedSequenceConvertibleType {
|
||||
|
||||
/**
|
||||
Returns an observable sequence that contains only distinct contiguous elements according to the `keySelector`.
|
||||
|
||||
- parameter keySelector: A function to compute the comparison key for each element.
|
||||
- returns: An observable sequence only containing the distinct contiguous elements, based on a computed key value, from the source sequence.
|
||||
*/
|
||||
public func distinctUntilChanged<Key: Equatable>(_ keySelector: @escaping (Element) -> Key) -> SharedSequence<SharingStrategy, Element> {
|
||||
let source = self.asObservable()
|
||||
.distinctUntilChanged(keySelector, comparer: { $0 == $1 })
|
||||
return SharedSequence(source)
|
||||
}
|
||||
|
||||
/**
|
||||
Returns an observable sequence that contains only distinct contiguous elements according to the `comparer`.
|
||||
|
||||
- parameter comparer: Equality comparer for computed key values.
|
||||
- returns: An observable sequence only containing the distinct contiguous elements, based on `comparer`, from the source sequence.
|
||||
*/
|
||||
public func distinctUntilChanged(_ comparer: @escaping (Element, Element) -> Bool) -> SharedSequence<SharingStrategy, Element> {
|
||||
let source = self.asObservable()
|
||||
.distinctUntilChanged({ $0 }, comparer: comparer)
|
||||
return SharedSequence<SharingStrategy, Element>(source)
|
||||
}
|
||||
|
||||
/**
|
||||
Returns an observable sequence that contains only distinct contiguous elements according to the keySelector and the comparer.
|
||||
|
||||
- parameter keySelector: A function to compute the comparison key for each element.
|
||||
- parameter comparer: Equality comparer for computed key values.
|
||||
- returns: An observable sequence only containing the distinct contiguous elements, based on a computed key value and the comparer, from the source sequence.
|
||||
*/
|
||||
public func distinctUntilChanged<K>(_ keySelector: @escaping (Element) -> K, comparer: @escaping (K, K) -> Bool) -> SharedSequence<SharingStrategy, Element> {
|
||||
let source = self.asObservable()
|
||||
.distinctUntilChanged(keySelector, comparer: comparer)
|
||||
return SharedSequence<SharingStrategy, Element>(source)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: flatMap
|
||||
extension SharedSequenceConvertibleType {
|
||||
|
||||
/**
|
||||
Projects each element of an observable sequence to an observable sequence and merges the resulting observable sequences into one observable sequence.
|
||||
|
||||
- parameter selector: A transform function to apply to each element.
|
||||
- returns: An observable sequence whose elements are the result of invoking the one-to-many transform function on each element of the input sequence.
|
||||
*/
|
||||
public func flatMap<Sharing, Result>(_ selector: @escaping (Element) -> SharedSequence<Sharing, Result>) -> SharedSequence<Sharing, Result> {
|
||||
let source = self.asObservable()
|
||||
.flatMap(selector)
|
||||
|
||||
return SharedSequence(source)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: merge
|
||||
extension SharedSequenceConvertibleType {
|
||||
/**
|
||||
Merges elements from all observable sequences from collection into a single observable sequence.
|
||||
|
||||
- seealso: [merge operator on reactivex.io](http://reactivex.io/documentation/operators/merge.html)
|
||||
|
||||
- parameter sources: Collection of observable sequences to merge.
|
||||
- returns: The observable sequence that merges the elements of the observable sequences.
|
||||
*/
|
||||
public static func merge<Collection: Swift.Collection>(_ sources: Collection) -> SharedSequence<SharingStrategy, Element>
|
||||
where Collection.Element == SharedSequence<SharingStrategy, Element> {
|
||||
let source = Observable.merge(sources.map { $0.asObservable() })
|
||||
return SharedSequence<SharingStrategy, Element>(source)
|
||||
}
|
||||
|
||||
/**
|
||||
Merges elements from all observable sequences from array into a single observable sequence.
|
||||
|
||||
- seealso: [merge operator on reactivex.io](http://reactivex.io/documentation/operators/merge.html)
|
||||
|
||||
- parameter sources: Array of observable sequences to merge.
|
||||
- returns: The observable sequence that merges the elements of the observable sequences.
|
||||
*/
|
||||
public static func merge(_ sources: [SharedSequence<SharingStrategy, Element>]) -> SharedSequence<SharingStrategy, Element> {
|
||||
let source = Observable.merge(sources.map { $0.asObservable() })
|
||||
return SharedSequence<SharingStrategy, Element>(source)
|
||||
}
|
||||
|
||||
/**
|
||||
Merges elements from all observable sequences into a single observable sequence.
|
||||
|
||||
- seealso: [merge operator on reactivex.io](http://reactivex.io/documentation/operators/merge.html)
|
||||
|
||||
- parameter sources: Collection of observable sequences to merge.
|
||||
- returns: The observable sequence that merges the elements of the observable sequences.
|
||||
*/
|
||||
public static func merge(_ sources: SharedSequence<SharingStrategy, Element>...) -> SharedSequence<SharingStrategy, Element> {
|
||||
let source = Observable.merge(sources.map { $0.asObservable() })
|
||||
return SharedSequence<SharingStrategy, Element>(source)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: merge
|
||||
extension SharedSequenceConvertibleType where Element: SharedSequenceConvertibleType {
|
||||
/**
|
||||
Merges elements from all observable sequences in the given enumerable sequence into a single observable sequence.
|
||||
|
||||
- returns: The observable sequence that merges the elements of the observable sequences.
|
||||
*/
|
||||
public func merge() -> SharedSequence<Element.SharingStrategy, Element.Element> {
|
||||
let source = self.asObservable()
|
||||
.map { $0.asSharedSequence() }
|
||||
.merge()
|
||||
return SharedSequence<Element.SharingStrategy, Element.Element>(source)
|
||||
}
|
||||
|
||||
/**
|
||||
Merges elements from all inner observable sequences into a single observable sequence, limiting the number of concurrent subscriptions to inner sequences.
|
||||
|
||||
- parameter maxConcurrent: Maximum number of inner observable sequences being subscribed to concurrently.
|
||||
- returns: The observable sequence that merges the elements of the inner sequences.
|
||||
*/
|
||||
public func merge(maxConcurrent: Int)
|
||||
-> SharedSequence<Element.SharingStrategy, Element.Element> {
|
||||
let source = self.asObservable()
|
||||
.map { $0.asSharedSequence() }
|
||||
.merge(maxConcurrent: maxConcurrent)
|
||||
return SharedSequence<Element.SharingStrategy, Element.Element>(source)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: throttle
|
||||
extension SharedSequenceConvertibleType {
|
||||
|
||||
/**
|
||||
Returns an Observable that emits the first and the latest item emitted by the source Observable during sequential time windows of a specified duration.
|
||||
|
||||
This operator makes sure that no two elements are emitted in less then dueTime.
|
||||
|
||||
- seealso: [debounce operator on reactivex.io](http://reactivex.io/documentation/operators/debounce.html)
|
||||
|
||||
- parameter dueTime: Throttling duration for each element.
|
||||
- parameter latest: Should latest element received in a dueTime wide time window since last element emission be emitted.
|
||||
- returns: The throttled sequence.
|
||||
*/
|
||||
public func throttle(_ dueTime: RxTimeInterval, latest: Bool = true)
|
||||
-> SharedSequence<SharingStrategy, Element> {
|
||||
let source = self.asObservable()
|
||||
.throttle(dueTime, latest: latest, scheduler: SharingStrategy.scheduler)
|
||||
|
||||
return SharedSequence(source)
|
||||
}
|
||||
|
||||
/**
|
||||
Ignores elements from an observable sequence which are followed by another element within a specified relative time duration, using the specified scheduler to run throttling timers.
|
||||
|
||||
- parameter dueTime: Throttling duration for each element.
|
||||
- returns: The throttled sequence.
|
||||
*/
|
||||
public func debounce(_ dueTime: RxTimeInterval)
|
||||
-> SharedSequence<SharingStrategy, Element> {
|
||||
let source = self.asObservable()
|
||||
.debounce(dueTime, scheduler: SharingStrategy.scheduler)
|
||||
|
||||
return SharedSequence(source)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: scan
|
||||
extension SharedSequenceConvertibleType {
|
||||
/**
|
||||
Applies an accumulator function over an observable sequence and returns each intermediate result. The specified seed value is used as the initial accumulator value.
|
||||
|
||||
For aggregation behavior with no intermediate results, see `reduce`.
|
||||
|
||||
- parameter seed: The initial accumulator value.
|
||||
- parameter accumulator: An accumulator function to be invoked on each element.
|
||||
- returns: An observable sequence containing the accumulated values.
|
||||
*/
|
||||
public func scan<A>(_ seed: A, accumulator: @escaping (A, Element) -> A)
|
||||
-> SharedSequence<SharingStrategy, A> {
|
||||
let source = self.asObservable()
|
||||
.scan(seed, accumulator: accumulator)
|
||||
return SharedSequence<SharingStrategy, A>(source)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: concat
|
||||
|
||||
extension SharedSequence {
|
||||
/**
|
||||
Concatenates all observable sequences in the given sequence, as long as the previous observable sequence terminated successfully.
|
||||
|
||||
- returns: An observable sequence that contains the elements of each given sequence, in sequential order.
|
||||
*/
|
||||
public static func concat<Sequence: Swift.Sequence>(_ sequence: Sequence) -> SharedSequence<SharingStrategy, Element>
|
||||
where Sequence.Element == SharedSequence<SharingStrategy, Element> {
|
||||
let source = Observable.concat(sequence.lazy.map { $0.asObservable() })
|
||||
return SharedSequence<SharingStrategy, Element>(source)
|
||||
}
|
||||
|
||||
/**
|
||||
Concatenates all observable sequences in the given sequence, as long as the previous observable sequence terminated successfully.
|
||||
|
||||
- returns: An observable sequence that contains the elements of each given sequence, in sequential order.
|
||||
*/
|
||||
public static func concat<Collection: Swift.Collection>(_ collection: Collection) -> SharedSequence<SharingStrategy, Element>
|
||||
where Collection.Element == SharedSequence<SharingStrategy, Element> {
|
||||
let source = Observable.concat(collection.map { $0.asObservable() })
|
||||
return SharedSequence<SharingStrategy, Element>(source)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: zip
|
||||
|
||||
extension SharedSequence {
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index.
|
||||
|
||||
- parameter resultSelector: Function to invoke for each series of elements at corresponding indexes in the sources.
|
||||
- returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function.
|
||||
*/
|
||||
public static func zip<Collection: Swift.Collection, Result>(_ collection: Collection, resultSelector: @escaping ([Element]) throws -> Result) -> SharedSequence<SharingStrategy, Result>
|
||||
where Collection.Element == SharedSequence<SharingStrategy, Element> {
|
||||
let source = Observable.zip(collection.map { $0.asSharedSequence().asObservable() }, resultSelector: resultSelector)
|
||||
return SharedSequence<SharingStrategy, Result>(source)
|
||||
}
|
||||
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence all of the observable sequences have produced an element at a corresponding index.
|
||||
|
||||
- returns: An observable sequence containing the result of combining elements of the sources.
|
||||
*/
|
||||
public static func zip<Collection: Swift.Collection>(_ collection: Collection) -> SharedSequence<SharingStrategy, [Element]>
|
||||
where Collection.Element == SharedSequence<SharingStrategy, Element> {
|
||||
let source = Observable.zip(collection.map { $0.asSharedSequence().asObservable() })
|
||||
return SharedSequence<SharingStrategy, [Element]>(source)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: combineLatest
|
||||
|
||||
extension SharedSequence {
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element.
|
||||
|
||||
- parameter resultSelector: Function to invoke whenever any of the sources produces an element.
|
||||
- returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function.
|
||||
*/
|
||||
public static func combineLatest<Collection: Swift.Collection, Result>(_ collection: Collection, resultSelector: @escaping ([Element]) throws -> Result) -> SharedSequence<SharingStrategy, Result>
|
||||
where Collection.Element == SharedSequence<SharingStrategy, Element> {
|
||||
let source = Observable.combineLatest(collection.map { $0.asObservable() }, resultSelector: resultSelector)
|
||||
return SharedSequence<SharingStrategy, Result>(source)
|
||||
}
|
||||
|
||||
/**
|
||||
Merges the specified observable sequences into one observable sequence whenever any of the observable sequences produces an element.
|
||||
|
||||
- returns: An observable sequence containing the result of combining elements of the sources.
|
||||
*/
|
||||
public static func combineLatest<Collection: Swift.Collection>(_ collection: Collection) -> SharedSequence<SharingStrategy, [Element]>
|
||||
where Collection.Element == SharedSequence<SharingStrategy, Element> {
|
||||
let source = Observable.combineLatest(collection.map { $0.asObservable() })
|
||||
return SharedSequence<SharingStrategy, [Element]>(source)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - withUnretained
|
||||
extension SharedSequenceConvertibleType where SharingStrategy == SignalSharingStrategy {
|
||||
/**
|
||||
Provides an unretained, safe to use (i.e. not implicitly unwrapped), reference to an object along with the events emitted by the sequence.
|
||||
|
||||
In the case the provided object cannot be retained successfully, the sequence will complete.
|
||||
|
||||
- note: Be careful when using this operator in a sequence that has a buffer or replay, for example `share(replay: 1)`, as the sharing buffer will also include the provided object, which could potentially cause a retain cycle.
|
||||
|
||||
- parameter obj: The object to provide an unretained reference on.
|
||||
- parameter resultSelector: A function to combine the unretained referenced on `obj` and the value of the observable sequence.
|
||||
- returns: An observable sequence that contains the result of `resultSelector` being called with an unretained reference on `obj` and the values of the original sequence.
|
||||
*/
|
||||
public func withUnretained<Object: AnyObject, Out>(
|
||||
_ obj: Object,
|
||||
resultSelector: @escaping (Object, Element) -> Out
|
||||
) -> SharedSequence<SharingStrategy, Out> {
|
||||
SharedSequence(self.asObservable().withUnretained(obj, resultSelector: resultSelector))
|
||||
}
|
||||
|
||||
/**
|
||||
Provides an unretained, safe to use (i.e. not implicitly unwrapped), reference to an object along with the events emitted by the sequence.
|
||||
|
||||
In the case the provided object cannot be retained successfully, the sequence will complete.
|
||||
|
||||
- note: Be careful when using this operator in a sequence that has a buffer or replay, for example `share(replay: 1)`, as the sharing buffer will also include the provided object, which could potentially cause a retain cycle.
|
||||
|
||||
- parameter obj: The object to provide an unretained reference on.
|
||||
- returns: An observable sequence of tuples that contains both an unretained reference on `obj` and the values of the original sequence.
|
||||
*/
|
||||
public func withUnretained<Object: AnyObject>(_ obj: Object) -> SharedSequence<SharingStrategy, (Object, Element)> {
|
||||
withUnretained(obj) { ($0, $1) }
|
||||
}
|
||||
}
|
||||
|
||||
extension SharedSequenceConvertibleType where SharingStrategy == DriverSharingStrategy {
|
||||
@available(*, message: "withUnretained has been deprecated for Driver. Consider using `drive(with:onNext:onCompleted:onDisposed:)`, instead", unavailable)
|
||||
public func withUnretained<Object: AnyObject, Out>(
|
||||
_ obj: Object,
|
||||
resultSelector: @escaping (Object, Element) -> Out
|
||||
) -> SharedSequence<SharingStrategy, Out> {
|
||||
SharedSequence(self.asObservable().withUnretained(obj, resultSelector: resultSelector))
|
||||
}
|
||||
|
||||
@available(*, message: "withUnretained has been deprecated for Driver. Consider using `drive(with:onNext:onCompleted:onDisposed:)`, instead", unavailable)
|
||||
public func withUnretained<Object: AnyObject>(_ obj: Object) -> SharedSequence<SharingStrategy, (Object, Element)> {
|
||||
SharedSequence(self.asObservable().withUnretained(obj) { ($0, $1) })
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: withLatestFrom
|
||||
extension SharedSequenceConvertibleType {
|
||||
|
||||
/**
|
||||
Merges two observable sequences into one observable sequence by combining each element from self with the latest element from the second source, if any.
|
||||
|
||||
- parameter second: Second observable source.
|
||||
- parameter resultSelector: Function to invoke for each element from the self combined with the latest element from the second source, if any.
|
||||
- returns: An observable sequence containing the result of combining each element of the self with the latest element from the second source, if any, using the specified result selector function.
|
||||
*/
|
||||
public func withLatestFrom<SecondO: SharedSequenceConvertibleType, ResultType>(_ second: SecondO, resultSelector: @escaping (Element, SecondO.Element) -> ResultType) -> SharedSequence<SharingStrategy, ResultType> where SecondO.SharingStrategy == SharingStrategy {
|
||||
let source = self.asObservable()
|
||||
.withLatestFrom(second.asSharedSequence(), resultSelector: resultSelector)
|
||||
|
||||
return SharedSequence<SharingStrategy, ResultType>(source)
|
||||
}
|
||||
|
||||
/**
|
||||
Merges two observable sequences into one observable sequence by using latest element from the second sequence every time when `self` emits an element.
|
||||
|
||||
- parameter second: Second observable source.
|
||||
- returns: An observable sequence containing the result of combining each element of the self with the latest element from the second source, if any, using the specified result selector function.
|
||||
*/
|
||||
public func withLatestFrom<SecondO: SharedSequenceConvertibleType>(_ second: SecondO) -> SharedSequence<SharingStrategy, SecondO.Element> {
|
||||
let source = self.asObservable()
|
||||
.withLatestFrom(second.asSharedSequence())
|
||||
|
||||
return SharedSequence<SharingStrategy, SecondO.Element>(source)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: skip
|
||||
extension SharedSequenceConvertibleType {
|
||||
|
||||
/**
|
||||
Bypasses a specified number of elements in an observable sequence and then returns the remaining elements.
|
||||
|
||||
- seealso: [skip operator on reactivex.io](http://reactivex.io/documentation/operators/skip.html)
|
||||
|
||||
- parameter count: The number of elements to skip before returning the remaining elements.
|
||||
- returns: An observable sequence that contains the elements that occur after the specified index in the input sequence.
|
||||
*/
|
||||
public func skip(_ count: Int)
|
||||
-> SharedSequence<SharingStrategy, Element> {
|
||||
let source = self.asObservable()
|
||||
.skip(count)
|
||||
return SharedSequence(source)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: startWith
|
||||
extension SharedSequenceConvertibleType {
|
||||
|
||||
/**
|
||||
Prepends a value to an observable sequence.
|
||||
|
||||
- seealso: [startWith operator on reactivex.io](http://reactivex.io/documentation/operators/startwith.html)
|
||||
|
||||
- parameter element: Element to prepend to the specified sequence.
|
||||
- returns: The source sequence prepended with the specified values.
|
||||
*/
|
||||
public func startWith(_ element: Element)
|
||||
-> SharedSequence<SharingStrategy, Element> {
|
||||
let source = self.asObservable()
|
||||
.startWith(element)
|
||||
|
||||
return SharedSequence(source)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: delay
|
||||
extension SharedSequenceConvertibleType {
|
||||
|
||||
/**
|
||||
Returns an observable sequence by the source observable sequence shifted forward in time by a specified delay. Error events from the source observable sequence are not delayed.
|
||||
|
||||
- seealso: [delay operator on reactivex.io](http://reactivex.io/documentation/operators/delay.html)
|
||||
|
||||
- parameter dueTime: Relative time shift of the source by.
|
||||
- returns: the source Observable shifted in time by the specified delay.
|
||||
*/
|
||||
public func delay(_ dueTime: RxTimeInterval)
|
||||
-> SharedSequence<SharingStrategy, Element> {
|
||||
let source = self.asObservable()
|
||||
.delay(dueTime, scheduler: SharingStrategy.scheduler)
|
||||
|
||||
return SharedSequence(source)
|
||||
}
|
||||
}
|
||||
226
Pods/RxCocoa/RxCocoa/Traits/SharedSequence/SharedSequence.swift
generated
Normal file
226
Pods/RxCocoa/RxCocoa/Traits/SharedSequence/SharedSequence.swift
generated
Normal file
@@ -0,0 +1,226 @@
|
||||
//
|
||||
// SharedSequence.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 8/27/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
import RxSwift
|
||||
|
||||
/**
|
||||
Trait that represents observable sequence that shares computation resources with following properties:
|
||||
|
||||
- it never fails
|
||||
- it delivers events on `SharingStrategy.scheduler`
|
||||
- sharing strategy is customizable using `SharingStrategy.share` behavior
|
||||
|
||||
`SharedSequence<Element>` can be considered a builder pattern for observable sequences that share computation resources.
|
||||
|
||||
To find out more about units and how to use them, please visit `Documentation/Traits.md`.
|
||||
*/
|
||||
public struct SharedSequence<SharingStrategy: SharingStrategyProtocol, Element> : SharedSequenceConvertibleType, ObservableConvertibleType {
|
||||
let source: Observable<Element>
|
||||
|
||||
init(_ source: Observable<Element>) {
|
||||
self.source = SharingStrategy.share(source)
|
||||
}
|
||||
|
||||
init(raw: Observable<Element>) {
|
||||
self.source = raw
|
||||
}
|
||||
|
||||
#if EXPANDABLE_SHARED_SEQUENCE
|
||||
/**
|
||||
This method is extension hook in case this unit needs to extended from outside the library.
|
||||
|
||||
By defining `EXPANDABLE_SHARED_SEQUENCE` one agrees that it's up to them to ensure shared sequence
|
||||
properties are preserved after extension.
|
||||
*/
|
||||
public static func createUnsafe<Source: ObservableType>(source: Source) -> SharedSequence<SharingStrategy, Source.Element> {
|
||||
SharedSequence<SharingStrategy, Source.Element>(raw: source.asObservable())
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
- returns: Built observable sequence.
|
||||
*/
|
||||
public func asObservable() -> Observable<Element> {
|
||||
self.source
|
||||
}
|
||||
|
||||
/**
|
||||
- returns: `self`
|
||||
*/
|
||||
public func asSharedSequence() -> SharedSequence<SharingStrategy, Element> {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Different `SharedSequence` sharing strategies must conform to this protocol.
|
||||
*/
|
||||
public protocol SharingStrategyProtocol {
|
||||
/**
|
||||
Scheduled on which all sequence events will be delivered.
|
||||
*/
|
||||
static var scheduler: SchedulerType { get }
|
||||
|
||||
/**
|
||||
Computation resources sharing strategy for multiple sequence observers.
|
||||
|
||||
E.g. One can choose `share(replay:scope:)`
|
||||
as sequence event sharing strategies, but also do something more exotic, like
|
||||
implementing promises or lazy loading chains.
|
||||
*/
|
||||
static func share<Element>(_ source: Observable<Element>) -> Observable<Element>
|
||||
}
|
||||
|
||||
/**
|
||||
A type that can be converted to `SharedSequence`.
|
||||
*/
|
||||
public protocol SharedSequenceConvertibleType : ObservableConvertibleType {
|
||||
associatedtype SharingStrategy: SharingStrategyProtocol
|
||||
|
||||
/**
|
||||
Converts self to `SharedSequence`.
|
||||
*/
|
||||
func asSharedSequence() -> SharedSequence<SharingStrategy, Element>
|
||||
}
|
||||
|
||||
extension SharedSequenceConvertibleType {
|
||||
public func asObservable() -> Observable<Element> {
|
||||
self.asSharedSequence().asObservable()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extension SharedSequence {
|
||||
|
||||
/**
|
||||
Returns an empty observable sequence, using the specified scheduler to send out the single `Completed` message.
|
||||
|
||||
- returns: An observable sequence with no elements.
|
||||
*/
|
||||
public static func empty() -> SharedSequence<SharingStrategy, Element> {
|
||||
SharedSequence(raw: Observable.empty().subscribe(on: SharingStrategy.scheduler))
|
||||
}
|
||||
|
||||
/**
|
||||
Returns a non-terminating observable sequence, which can be used to denote an infinite duration.
|
||||
|
||||
- returns: An observable sequence whose observers will never get called.
|
||||
*/
|
||||
public static func never() -> SharedSequence<SharingStrategy, Element> {
|
||||
SharedSequence(raw: Observable.never())
|
||||
}
|
||||
|
||||
/**
|
||||
Returns an observable sequence that contains a single element.
|
||||
|
||||
- parameter element: Single element in the resulting observable sequence.
|
||||
- returns: An observable sequence containing the single specified element.
|
||||
*/
|
||||
public static func just(_ element: Element) -> SharedSequence<SharingStrategy, Element> {
|
||||
SharedSequence(raw: Observable.just(element).subscribe(on: SharingStrategy.scheduler))
|
||||
}
|
||||
|
||||
/**
|
||||
Returns an observable sequence that invokes the specified factory function whenever a new observer subscribes.
|
||||
|
||||
- parameter observableFactory: Observable factory function to invoke for each observer that subscribes to the resulting sequence.
|
||||
- returns: An observable sequence whose observers trigger an invocation of the given observable factory function.
|
||||
*/
|
||||
public static func deferred(_ observableFactory: @escaping () -> SharedSequence<SharingStrategy, Element>)
|
||||
-> SharedSequence<SharingStrategy, Element> {
|
||||
SharedSequence(Observable.deferred { observableFactory().asObservable() })
|
||||
}
|
||||
|
||||
/**
|
||||
This method creates a new Observable instance with a variable number of elements.
|
||||
|
||||
- seealso: [from operator on reactivex.io](http://reactivex.io/documentation/operators/from.html)
|
||||
|
||||
- parameter elements: Elements to generate.
|
||||
- returns: The observable sequence whose elements are pulled from the given arguments.
|
||||
*/
|
||||
public static func of(_ elements: Element ...) -> SharedSequence<SharingStrategy, Element> {
|
||||
let source = Observable.from(elements, scheduler: SharingStrategy.scheduler)
|
||||
return SharedSequence(raw: source)
|
||||
}
|
||||
}
|
||||
|
||||
extension SharedSequence {
|
||||
|
||||
/**
|
||||
This method converts an array to an observable sequence.
|
||||
|
||||
- seealso: [from operator on reactivex.io](http://reactivex.io/documentation/operators/from.html)
|
||||
|
||||
- returns: The observable sequence whose elements are pulled from the given enumerable sequence.
|
||||
*/
|
||||
public static func from(_ array: [Element]) -> SharedSequence<SharingStrategy, Element> {
|
||||
let source = Observable.from(array, scheduler: SharingStrategy.scheduler)
|
||||
return SharedSequence(raw: source)
|
||||
}
|
||||
|
||||
/**
|
||||
This method converts a sequence to an observable sequence.
|
||||
|
||||
- seealso: [from operator on reactivex.io](http://reactivex.io/documentation/operators/from.html)
|
||||
|
||||
- returns: The observable sequence whose elements are pulled from the given enumerable sequence.
|
||||
*/
|
||||
public static func from<Sequence: Swift.Sequence>(_ sequence: Sequence) -> SharedSequence<SharingStrategy, Element> where Sequence.Element == Element {
|
||||
let source = Observable.from(sequence, scheduler: SharingStrategy.scheduler)
|
||||
return SharedSequence(raw: source)
|
||||
}
|
||||
|
||||
/**
|
||||
This method converts a optional to an observable sequence.
|
||||
|
||||
- seealso: [from operator on reactivex.io](http://reactivex.io/documentation/operators/from.html)
|
||||
|
||||
- parameter optional: Optional element in the resulting observable sequence.
|
||||
|
||||
- returns: An observable sequence containing the wrapped value or not from given optional.
|
||||
*/
|
||||
public static func from(optional: Element?) -> SharedSequence<SharingStrategy, Element> {
|
||||
let source = Observable.from(optional: optional, scheduler: SharingStrategy.scheduler)
|
||||
return SharedSequence(raw: source)
|
||||
}
|
||||
}
|
||||
|
||||
extension SharedSequence where Element: RxAbstractInteger {
|
||||
/**
|
||||
Returns an observable sequence that produces a value after each period, using the specified scheduler to run timers and to send out observer messages.
|
||||
|
||||
- seealso: [interval operator on reactivex.io](http://reactivex.io/documentation/operators/interval.html)
|
||||
|
||||
- parameter period: Period for producing the values in the resulting sequence.
|
||||
- returns: An observable sequence that produces a value after each period.
|
||||
*/
|
||||
public static func interval(_ period: RxTimeInterval)
|
||||
-> SharedSequence<SharingStrategy, Element> {
|
||||
SharedSequence(Observable.interval(period, scheduler: SharingStrategy.scheduler))
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: timer
|
||||
|
||||
extension SharedSequence where Element: RxAbstractInteger {
|
||||
/**
|
||||
Returns an observable sequence that periodically produces a value after the specified initial relative due time has elapsed, using the specified scheduler to run timers.
|
||||
|
||||
- seealso: [timer operator on reactivex.io](http://reactivex.io/documentation/operators/timer.html)
|
||||
|
||||
- parameter dueTime: Relative time at which to produce the first value.
|
||||
- parameter period: Period to produce subsequent values.
|
||||
- returns: An observable sequence that produces a value after due time has elapsed and then each period.
|
||||
*/
|
||||
public static func timer(_ dueTime: RxTimeInterval, period: RxTimeInterval)
|
||||
-> SharedSequence<SharingStrategy, Element> {
|
||||
SharedSequence(Observable.timer(dueTime, period: period, scheduler: SharingStrategy.scheduler))
|
||||
}
|
||||
}
|
||||
|
||||
25
Pods/RxCocoa/RxCocoa/Traits/Signal/ControlEvent+Signal.swift
generated
Normal file
25
Pods/RxCocoa/RxCocoa/Traits/Signal/ControlEvent+Signal.swift
generated
Normal file
@@ -0,0 +1,25 @@
|
||||
//
|
||||
// ControlEvent+Signal.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 11/1/17.
|
||||
// Copyright © 2017 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
import RxSwift
|
||||
|
||||
extension ControlEvent {
|
||||
/// Converts `ControlEvent` to `Signal` trait.
|
||||
///
|
||||
/// `ControlEvent` already can't fail, so no special case needs to be handled.
|
||||
public func asSignal() -> Signal<Element> {
|
||||
return self.asSignal { _ -> Signal<Element> in
|
||||
#if DEBUG
|
||||
rxFatalError("Somehow signal received error from a source that shouldn't fail.")
|
||||
#else
|
||||
return Signal.empty()
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
57
Pods/RxCocoa/RxCocoa/Traits/Signal/ObservableConvertibleType+Signal.swift
generated
Normal file
57
Pods/RxCocoa/RxCocoa/Traits/Signal/ObservableConvertibleType+Signal.swift
generated
Normal file
@@ -0,0 +1,57 @@
|
||||
//
|
||||
// ObservableConvertibleType+Signal.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 9/19/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
import RxSwift
|
||||
|
||||
extension ObservableConvertibleType {
|
||||
/**
|
||||
Converts observable sequence to `Signal` trait.
|
||||
|
||||
- parameter onErrorJustReturn: Element to return in case of error and after that complete the sequence.
|
||||
- returns: Signal trait.
|
||||
*/
|
||||
public func asSignal(onErrorJustReturn: Element) -> Signal<Element> {
|
||||
let source = self
|
||||
.asObservable()
|
||||
.observe(on: SignalSharingStrategy.scheduler)
|
||||
.catchAndReturn(onErrorJustReturn)
|
||||
return Signal(source)
|
||||
}
|
||||
|
||||
/**
|
||||
Converts observable sequence to `Signal` trait.
|
||||
|
||||
- parameter onErrorSignalWith: Signal that continues to emit the sequence in case of error.
|
||||
- returns: Signal trait.
|
||||
*/
|
||||
public func asSignal(onErrorSignalWith: Signal<Element>) -> Signal<Element> {
|
||||
let source = self
|
||||
.asObservable()
|
||||
.observe(on: SignalSharingStrategy.scheduler)
|
||||
.catch { _ in
|
||||
onErrorSignalWith.asObservable()
|
||||
}
|
||||
return Signal(source)
|
||||
}
|
||||
|
||||
/**
|
||||
Converts observable sequence to `Signal` trait.
|
||||
|
||||
- parameter onErrorRecover: Calculates signal that continues to emit the sequence in case of error.
|
||||
- returns: Signal trait.
|
||||
*/
|
||||
public func asSignal(onErrorRecover: @escaping (_ error: Swift.Error) -> Signal<Element>) -> Signal<Element> {
|
||||
let source = self
|
||||
.asObservable()
|
||||
.observe(on: SignalSharingStrategy.scheduler)
|
||||
.catch { error in
|
||||
onErrorRecover(error).asObservable()
|
||||
}
|
||||
return Signal(source)
|
||||
}
|
||||
}
|
||||
21
Pods/RxCocoa/RxCocoa/Traits/Signal/PublishRelay+Signal.swift
generated
Normal file
21
Pods/RxCocoa/RxCocoa/Traits/Signal/PublishRelay+Signal.swift
generated
Normal file
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// PublishRelay+Signal.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 12/28/15.
|
||||
// Copyright © 2017 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
import RxSwift
|
||||
import RxRelay
|
||||
|
||||
extension PublishRelay {
|
||||
/// Converts `PublishRelay` to `Signal`.
|
||||
///
|
||||
/// - returns: Observable sequence.
|
||||
public func asSignal() -> Signal<Element> {
|
||||
let source = self.asObservable()
|
||||
.observe(on:SignalSharingStrategy.scheduler)
|
||||
return SharedSequence(source)
|
||||
}
|
||||
}
|
||||
178
Pods/RxCocoa/RxCocoa/Traits/Signal/Signal+Subscription.swift
generated
Normal file
178
Pods/RxCocoa/RxCocoa/Traits/Signal/Signal+Subscription.swift
generated
Normal file
@@ -0,0 +1,178 @@
|
||||
//
|
||||
// Signal+Subscription.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 9/19/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
import RxSwift
|
||||
import RxRelay
|
||||
|
||||
extension SharedSequenceConvertibleType where SharingStrategy == SignalSharingStrategy {
|
||||
/**
|
||||
Creates new subscription and sends elements to observer.
|
||||
|
||||
In this form it's equivalent to `subscribe` method, but it communicates intent better.
|
||||
|
||||
- parameter observers: Observers that receives events.
|
||||
- returns: Disposable object that can be used to unsubscribe the observer from the subject.
|
||||
*/
|
||||
public func emit<Observer: ObserverType>(to observers: Observer...) -> Disposable where Observer.Element == Element {
|
||||
return self.asSharedSequence()
|
||||
.asObservable()
|
||||
.subscribe { event in
|
||||
observers.forEach { $0.on(event) }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Creates new subscription and sends elements to observer.
|
||||
|
||||
In this form it's equivalent to `subscribe` method, but it communicates intent better.
|
||||
|
||||
- parameter observers: Observers that receives events.
|
||||
- returns: Disposable object that can be used to unsubscribe the observer from the subject.
|
||||
*/
|
||||
public func emit<Observer: ObserverType>(to observers: Observer...) -> Disposable where Observer.Element == Element? {
|
||||
return self.asSharedSequence()
|
||||
.asObservable()
|
||||
.map { $0 as Element? }
|
||||
.subscribe { event in
|
||||
observers.forEach { $0.on(event) }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Creates new subscription and sends elements to `BehaviorRelay`.
|
||||
- parameter relays: Target relays for sequence elements.
|
||||
- returns: Disposable object that can be used to unsubscribe the observer from the relay.
|
||||
*/
|
||||
public func emit(to relays: BehaviorRelay<Element>...) -> Disposable {
|
||||
return self.emit(onNext: { e in
|
||||
relays.forEach { $0.accept(e) }
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
Creates new subscription and sends elements to `BehaviorRelay`.
|
||||
- parameter relays: Target relays for sequence elements.
|
||||
- returns: Disposable object that can be used to unsubscribe the observer from the relay.
|
||||
*/
|
||||
public func emit(to relays: BehaviorRelay<Element?>...) -> Disposable {
|
||||
return self.emit(onNext: { e in
|
||||
relays.forEach { $0.accept(e) }
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
Creates new subscription and sends elements to `PublishRelay`.
|
||||
|
||||
- parameter relays: Target relays for sequence elements.
|
||||
- returns: Disposable object that can be used to unsubscribe the observer from the relay.
|
||||
*/
|
||||
public func emit(to relays: PublishRelay<Element>...) -> Disposable {
|
||||
return self.emit(onNext: { e in
|
||||
relays.forEach { $0.accept(e) }
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
Creates new subscription and sends elements to `PublishRelay`.
|
||||
|
||||
- parameter relays: Target relay for sequence elements.
|
||||
- returns: Disposable object that can be used to unsubscribe the observer from the relay.
|
||||
*/
|
||||
public func emit(to relays: PublishRelay<Element?>...) -> Disposable {
|
||||
return self.emit(onNext: { e in
|
||||
relays.forEach { $0.accept(e) }
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
Creates new subscription and sends elements to `ReplayRelay`.
|
||||
|
||||
- parameter relays: Target relays for sequence elements.
|
||||
- returns: Disposable object that can be used to unsubscribe the observer from the relay.
|
||||
*/
|
||||
public func emit(to relays: ReplayRelay<Element>...) -> Disposable {
|
||||
return self.emit(onNext: { e in
|
||||
relays.forEach { $0.accept(e) }
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
Creates new subscription and sends elements to `ReplayRelay`.
|
||||
|
||||
- parameter relays: Target relay for sequence elements.
|
||||
- returns: Disposable object that can be used to unsubscribe the observer from the relay.
|
||||
*/
|
||||
public func emit(to relays: ReplayRelay<Element?>...) -> Disposable {
|
||||
return self.emit(onNext: { e in
|
||||
relays.forEach { $0.accept(e) }
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
Subscribes an element handler, a completion handler and disposed handler to an observable sequence.
|
||||
|
||||
Also, take in an object and provide an unretained, safe to use (i.e. not implicitly unwrapped), reference to it along with the events emitted by the sequence.
|
||||
|
||||
Error callback is not exposed because `Signal` can't error out.
|
||||
|
||||
- Note: If `object` can't be retained, none of the other closures will be invoked.
|
||||
|
||||
- parameter object: The object to provide an unretained reference on.
|
||||
- parameter onNext: Action to invoke for each element in the observable sequence.
|
||||
- parameter onCompleted: Action to invoke upon graceful termination of the observable sequence.
|
||||
gracefully completed, errored, or if the generation is canceled by disposing subscription)
|
||||
- parameter onDisposed: Action to invoke upon any type of termination of sequence (if the sequence has
|
||||
gracefully completed, errored, or if the generation is canceled by disposing subscription)
|
||||
- returns: Subscription object used to unsubscribe from the observable sequence.
|
||||
*/
|
||||
public func emit<Object: AnyObject>(
|
||||
with object: Object,
|
||||
onNext: ((Object, Element) -> Void)? = nil,
|
||||
onCompleted: ((Object) -> Void)? = nil,
|
||||
onDisposed: ((Object) -> Void)? = nil
|
||||
) -> Disposable {
|
||||
self.asObservable().subscribe(
|
||||
with: object,
|
||||
onNext: onNext,
|
||||
onCompleted: onCompleted,
|
||||
onDisposed: onDisposed
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
Subscribes an element handler, a completion handler and disposed handler to an observable sequence.
|
||||
|
||||
Error callback is not exposed because `Signal` can't error out.
|
||||
|
||||
- parameter onNext: Action to invoke for each element in the observable sequence.
|
||||
- parameter onCompleted: Action to invoke upon graceful termination of the observable sequence.
|
||||
gracefully completed, errored, or if the generation is canceled by disposing subscription)
|
||||
- parameter onDisposed: Action to invoke upon any type of termination of sequence (if the sequence has
|
||||
gracefully completed, errored, or if the generation is canceled by disposing subscription)
|
||||
- returns: Subscription object used to unsubscribe from the observable sequence.
|
||||
*/
|
||||
public func emit(
|
||||
onNext: ((Element) -> Void)? = nil,
|
||||
onCompleted: (() -> Void)? = nil,
|
||||
onDisposed: (() -> Void)? = nil
|
||||
) -> Disposable {
|
||||
self.asObservable().subscribe(onNext: onNext, onCompleted: onCompleted, onDisposed: onDisposed)
|
||||
}
|
||||
|
||||
/**
|
||||
Subscribes to this `Signal` with a no-op.
|
||||
This method can be only called from `MainThread`.
|
||||
|
||||
- note: This is an alias of `emit(onNext: nil, onCompleted: nil, onDisposed: nil)` used to fix an ambiguity bug in Swift: https://bugs.swift.org/browse/SR-13657
|
||||
|
||||
- returns: Subscription object used to unsubscribe from the observable sequence.
|
||||
*/
|
||||
public func emit() -> Disposable {
|
||||
emit(onNext: nil, onCompleted: nil, onDisposed: nil)
|
||||
}
|
||||
}
|
||||
45
Pods/RxCocoa/RxCocoa/Traits/Signal/Signal.swift
generated
Normal file
45
Pods/RxCocoa/RxCocoa/Traits/Signal/Signal.swift
generated
Normal file
@@ -0,0 +1,45 @@
|
||||
//
|
||||
// Signal.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 9/26/16.
|
||||
// Copyright © 2016 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
import RxSwift
|
||||
|
||||
/**
|
||||
Trait that represents observable sequence with following properties:
|
||||
|
||||
- it never fails
|
||||
- it delivers events on `MainScheduler.instance`
|
||||
- `share(scope: .whileConnected)` sharing strategy
|
||||
|
||||
Additional explanation:
|
||||
- all observers share sequence computation resources
|
||||
- there is no replaying of sequence elements on new observer subscription
|
||||
- computation of elements is reference counted with respect to the number of observers
|
||||
- if there are no subscribers, it will release sequence computation resources
|
||||
|
||||
In case trait that models state propagation is required, please check `Driver`.
|
||||
|
||||
`Signal<Element>` can be considered a builder pattern for observable sequences that model imperative events part of the application.
|
||||
|
||||
To find out more about units and how to use them, please visit `Documentation/Traits.md`.
|
||||
*/
|
||||
public typealias Signal<Element> = SharedSequence<SignalSharingStrategy, Element>
|
||||
|
||||
public struct SignalSharingStrategy: SharingStrategyProtocol {
|
||||
public static var scheduler: SchedulerType { SharingScheduler.make() }
|
||||
|
||||
public static func share<Element>(_ source: Observable<Element>) -> Observable<Element> {
|
||||
source.share(scope: .whileConnected)
|
||||
}
|
||||
}
|
||||
|
||||
extension SharedSequenceConvertibleType where SharingStrategy == SignalSharingStrategy {
|
||||
/// Adds `asPublisher` to `SharingSequence` with `PublishSharingStrategy`.
|
||||
public func asSignal() -> Signal<Element> {
|
||||
self.asSharedSequence()
|
||||
}
|
||||
}
|
||||
108
Pods/RxCocoa/RxCocoa/iOS/DataSources/RxCollectionViewReactiveArrayDataSource.swift
generated
Normal file
108
Pods/RxCocoa/RxCocoa/iOS/DataSources/RxCollectionViewReactiveArrayDataSource.swift
generated
Normal file
@@ -0,0 +1,108 @@
|
||||
//
|
||||
// RxCollectionViewReactiveArrayDataSource.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 6/29/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
|
||||
import UIKit
|
||||
import RxSwift
|
||||
|
||||
// objc monkey business
|
||||
class _RxCollectionViewReactiveArrayDataSource
|
||||
: NSObject
|
||||
, UICollectionViewDataSource {
|
||||
|
||||
@objc(numberOfSectionsInCollectionView:)
|
||||
func numberOfSections(in: UICollectionView) -> Int {
|
||||
1
|
||||
}
|
||||
|
||||
func _collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
||||
0
|
||||
}
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
||||
_collectionView(collectionView, numberOfItemsInSection: section)
|
||||
}
|
||||
|
||||
fileprivate func _collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
||||
rxAbstractMethod()
|
||||
}
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
||||
_collectionView(collectionView, cellForItemAt: indexPath)
|
||||
}
|
||||
}
|
||||
|
||||
class RxCollectionViewReactiveArrayDataSourceSequenceWrapper<Sequence: Swift.Sequence>
|
||||
: RxCollectionViewReactiveArrayDataSource<Sequence.Element>
|
||||
, RxCollectionViewDataSourceType {
|
||||
typealias Element = Sequence
|
||||
|
||||
override init(cellFactory: @escaping CellFactory) {
|
||||
super.init(cellFactory: cellFactory)
|
||||
}
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView, observedEvent: Event<Sequence>) {
|
||||
Binder(self) { collectionViewDataSource, sectionModels in
|
||||
let sections = Array(sectionModels)
|
||||
collectionViewDataSource.collectionView(collectionView, observedElements: sections)
|
||||
}.on(observedEvent)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Please take a look at `DelegateProxyType.swift`
|
||||
class RxCollectionViewReactiveArrayDataSource<Element>
|
||||
: _RxCollectionViewReactiveArrayDataSource
|
||||
, SectionedViewDataSourceType {
|
||||
|
||||
typealias CellFactory = (UICollectionView, Int, Element) -> UICollectionViewCell
|
||||
|
||||
var itemModels: [Element]?
|
||||
|
||||
func modelAtIndex(_ index: Int) -> Element? {
|
||||
itemModels?[index]
|
||||
}
|
||||
|
||||
func model(at indexPath: IndexPath) throws -> Any {
|
||||
precondition(indexPath.section == 0)
|
||||
guard let item = itemModels?[indexPath.item] else {
|
||||
throw RxCocoaError.itemsNotYetBound(object: self)
|
||||
}
|
||||
return item
|
||||
}
|
||||
|
||||
var cellFactory: CellFactory
|
||||
|
||||
init(cellFactory: @escaping CellFactory) {
|
||||
self.cellFactory = cellFactory
|
||||
}
|
||||
|
||||
// data source
|
||||
|
||||
override func _collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
||||
itemModels?.count ?? 0
|
||||
}
|
||||
|
||||
override func _collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
||||
cellFactory(collectionView, indexPath.item, itemModels![indexPath.item])
|
||||
}
|
||||
|
||||
// reactive
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView, observedElements: [Element]) {
|
||||
self.itemModels = observedElements
|
||||
|
||||
collectionView.reloadData()
|
||||
|
||||
// workaround for http://stackoverflow.com/questions/39867325/ios-10-bug-uicollectionview-received-layout-attributes-for-a-cell-with-an-index
|
||||
collectionView.collectionViewLayout.invalidateLayout()
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
92
Pods/RxCocoa/RxCocoa/iOS/DataSources/RxPickerViewAdapter.swift
generated
Normal file
92
Pods/RxCocoa/RxCocoa/iOS/DataSources/RxPickerViewAdapter.swift
generated
Normal file
@@ -0,0 +1,92 @@
|
||||
//
|
||||
// RxPickerViewAdapter.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Sergey Shulga on 12/07/2017.
|
||||
// Copyright © 2017 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS)
|
||||
|
||||
import UIKit
|
||||
import RxSwift
|
||||
|
||||
class RxPickerViewArrayDataSource<T>: NSObject, UIPickerViewDataSource, SectionedViewDataSourceType {
|
||||
fileprivate var items: [T] = []
|
||||
|
||||
func model(at indexPath: IndexPath) throws -> Any {
|
||||
guard items.indices ~= indexPath.row else {
|
||||
throw RxCocoaError.itemsNotYetBound(object: self)
|
||||
}
|
||||
return items[indexPath.row]
|
||||
}
|
||||
|
||||
func numberOfComponents(in pickerView: UIPickerView) -> Int {
|
||||
1
|
||||
}
|
||||
|
||||
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
|
||||
items.count
|
||||
}
|
||||
}
|
||||
|
||||
class RxPickerViewSequenceDataSource<Sequence: Swift.Sequence>
|
||||
: RxPickerViewArrayDataSource<Sequence.Element>
|
||||
, RxPickerViewDataSourceType {
|
||||
typealias Element = Sequence
|
||||
|
||||
func pickerView(_ pickerView: UIPickerView, observedEvent: Event<Sequence>) {
|
||||
Binder(self) { dataSource, items in
|
||||
dataSource.items = items
|
||||
pickerView.reloadAllComponents()
|
||||
}
|
||||
.on(observedEvent.map(Array.init))
|
||||
}
|
||||
}
|
||||
|
||||
final class RxStringPickerViewAdapter<Sequence: Swift.Sequence>
|
||||
: RxPickerViewSequenceDataSource<Sequence>
|
||||
, UIPickerViewDelegate {
|
||||
|
||||
typealias TitleForRow = (Int, Sequence.Element) -> String?
|
||||
private let titleForRow: TitleForRow
|
||||
|
||||
init(titleForRow: @escaping TitleForRow) {
|
||||
self.titleForRow = titleForRow
|
||||
super.init()
|
||||
}
|
||||
|
||||
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
|
||||
titleForRow(row, items[row])
|
||||
}
|
||||
}
|
||||
|
||||
final class RxAttributedStringPickerViewAdapter<Sequence: Swift.Sequence>: RxPickerViewSequenceDataSource<Sequence>, UIPickerViewDelegate {
|
||||
typealias AttributedTitleForRow = (Int, Sequence.Element) -> NSAttributedString?
|
||||
private let attributedTitleForRow: AttributedTitleForRow
|
||||
|
||||
init(attributedTitleForRow: @escaping AttributedTitleForRow) {
|
||||
self.attributedTitleForRow = attributedTitleForRow
|
||||
super.init()
|
||||
}
|
||||
|
||||
func pickerView(_ pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? {
|
||||
attributedTitleForRow(row, items[row])
|
||||
}
|
||||
}
|
||||
|
||||
final class RxPickerViewAdapter<Sequence: Swift.Sequence>: RxPickerViewSequenceDataSource<Sequence>, UIPickerViewDelegate {
|
||||
typealias ViewForRow = (Int, Sequence.Element, UIView?) -> UIView
|
||||
private let viewForRow: ViewForRow
|
||||
|
||||
init(viewForRow: @escaping ViewForRow) {
|
||||
self.viewForRow = viewForRow
|
||||
super.init()
|
||||
}
|
||||
|
||||
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
|
||||
viewForRow(row, items[row], view)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
101
Pods/RxCocoa/RxCocoa/iOS/DataSources/RxTableViewReactiveArrayDataSource.swift
generated
Normal file
101
Pods/RxCocoa/RxCocoa/iOS/DataSources/RxTableViewReactiveArrayDataSource.swift
generated
Normal file
@@ -0,0 +1,101 @@
|
||||
//
|
||||
// RxTableViewReactiveArrayDataSource.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 6/26/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
|
||||
import UIKit
|
||||
import RxSwift
|
||||
|
||||
// objc monkey business
|
||||
class _RxTableViewReactiveArrayDataSource
|
||||
: NSObject
|
||||
, UITableViewDataSource {
|
||||
|
||||
func numberOfSections(in tableView: UITableView) -> Int {
|
||||
1
|
||||
}
|
||||
|
||||
func _tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
0
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
_tableView(tableView, numberOfRowsInSection: section)
|
||||
}
|
||||
|
||||
fileprivate func _tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
rxAbstractMethod()
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
_tableView(tableView, cellForRowAt: indexPath)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class RxTableViewReactiveArrayDataSourceSequenceWrapper<Sequence: Swift.Sequence>
|
||||
: RxTableViewReactiveArrayDataSource<Sequence.Element>
|
||||
, RxTableViewDataSourceType {
|
||||
typealias Element = Sequence
|
||||
|
||||
override init(cellFactory: @escaping CellFactory) {
|
||||
super.init(cellFactory: cellFactory)
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, observedEvent: Event<Sequence>) {
|
||||
Binder(self) { tableViewDataSource, sectionModels in
|
||||
let sections = Array(sectionModels)
|
||||
tableViewDataSource.tableView(tableView, observedElements: sections)
|
||||
}.on(observedEvent)
|
||||
}
|
||||
}
|
||||
|
||||
// Please take a look at `DelegateProxyType.swift`
|
||||
class RxTableViewReactiveArrayDataSource<Element>
|
||||
: _RxTableViewReactiveArrayDataSource
|
||||
, SectionedViewDataSourceType {
|
||||
typealias CellFactory = (UITableView, Int, Element) -> UITableViewCell
|
||||
|
||||
var itemModels: [Element]?
|
||||
|
||||
func modelAtIndex(_ index: Int) -> Element? {
|
||||
itemModels?[index]
|
||||
}
|
||||
|
||||
func model(at indexPath: IndexPath) throws -> Any {
|
||||
precondition(indexPath.section == 0)
|
||||
guard let item = itemModels?[indexPath.item] else {
|
||||
throw RxCocoaError.itemsNotYetBound(object: self)
|
||||
}
|
||||
return item
|
||||
}
|
||||
|
||||
let cellFactory: CellFactory
|
||||
|
||||
init(cellFactory: @escaping CellFactory) {
|
||||
self.cellFactory = cellFactory
|
||||
}
|
||||
|
||||
override func _tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
itemModels?.count ?? 0
|
||||
}
|
||||
|
||||
override func _tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
cellFactory(tableView, indexPath.item, itemModels![indexPath.row])
|
||||
}
|
||||
|
||||
// reactive
|
||||
|
||||
func tableView(_ tableView: UITableView, observedElements: [Element]) {
|
||||
self.itemModels = observedElements
|
||||
|
||||
tableView.reloadData()
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
15
Pods/RxCocoa/RxCocoa/iOS/Events/ItemEvents.swift
generated
Normal file
15
Pods/RxCocoa/RxCocoa/iOS/Events/ItemEvents.swift
generated
Normal file
@@ -0,0 +1,15 @@
|
||||
//
|
||||
// ItemEvents.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 6/20/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
import UIKit
|
||||
|
||||
public typealias ItemMovedEvent = (sourceIndex: IndexPath, destinationIndex: IndexPath)
|
||||
public typealias WillDisplayCellEvent = (cell: UITableViewCell, indexPath: IndexPath)
|
||||
public typealias DidEndDisplayingCellEvent = (cell: UITableViewCell, indexPath: IndexPath)
|
||||
#endif
|
||||
35
Pods/RxCocoa/RxCocoa/iOS/NSTextStorage+Rx.swift
generated
Normal file
35
Pods/RxCocoa/RxCocoa/iOS/NSTextStorage+Rx.swift
generated
Normal file
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// NSTextStorage+Rx.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Segii Shulga on 12/30/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
import RxSwift
|
||||
import UIKit
|
||||
|
||||
extension Reactive where Base: NSTextStorage {
|
||||
|
||||
/// Reactive wrapper for `delegate`.
|
||||
///
|
||||
/// For more information take a look at `DelegateProxyType` protocol documentation.
|
||||
public var delegate: DelegateProxy<NSTextStorage, NSTextStorageDelegate> {
|
||||
return RxTextStorageDelegateProxy.proxy(for: base)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `delegate` message.
|
||||
public var didProcessEditingRangeChangeInLength: Observable<(editedMask: NSTextStorage.EditActions, editedRange: NSRange, delta: Int)> {
|
||||
return delegate
|
||||
.methodInvoked(#selector(NSTextStorageDelegate.textStorage(_:didProcessEditing:range:changeInLength:)))
|
||||
.map { a in
|
||||
let editedMask = NSTextStorage.EditActions(rawValue: try castOrThrow(UInt.self, a[1]) )
|
||||
let editedRange = try castOrThrow(NSValue.self, a[2]).rangeValue
|
||||
let delta = try castOrThrow(Int.self, a[3])
|
||||
|
||||
return (editedMask, editedRange, delta)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
27
Pods/RxCocoa/RxCocoa/iOS/Protocols/RxCollectionViewDataSourceType.swift
generated
Normal file
27
Pods/RxCocoa/RxCocoa/iOS/Protocols/RxCollectionViewDataSourceType.swift
generated
Normal file
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// RxCollectionViewDataSourceType.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 6/29/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
|
||||
import UIKit
|
||||
import RxSwift
|
||||
|
||||
/// Marks data source as `UICollectionView` reactive data source enabling it to be used with one of the `bindTo` methods.
|
||||
public protocol RxCollectionViewDataSourceType /*: UICollectionViewDataSource*/ {
|
||||
|
||||
/// Type of elements that can be bound to collection view.
|
||||
associatedtype Element
|
||||
|
||||
/// New observable sequence event observed.
|
||||
///
|
||||
/// - parameter collectionView: Bound collection view.
|
||||
/// - parameter observedEvent: Event
|
||||
func collectionView(_ collectionView: UICollectionView, observedEvent: Event<Element>)
|
||||
}
|
||||
|
||||
#endif
|
||||
26
Pods/RxCocoa/RxCocoa/iOS/Protocols/RxPickerViewDataSourceType.swift
generated
Normal file
26
Pods/RxCocoa/RxCocoa/iOS/Protocols/RxPickerViewDataSourceType.swift
generated
Normal file
@@ -0,0 +1,26 @@
|
||||
//
|
||||
// RxPickerViewDataSourceType.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Sergey Shulga on 05/07/2017.
|
||||
// Copyright © 2017 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS)
|
||||
|
||||
import UIKit
|
||||
import RxSwift
|
||||
|
||||
/// Marks data source as `UIPickerView` reactive data source enabling it to be used with one of the `bindTo` methods.
|
||||
public protocol RxPickerViewDataSourceType {
|
||||
/// Type of elements that can be bound to picker view.
|
||||
associatedtype Element
|
||||
|
||||
/// New observable sequence event observed.
|
||||
///
|
||||
/// - parameter pickerView: Bound picker view.
|
||||
/// - parameter observedEvent: Event
|
||||
func pickerView(_ pickerView: UIPickerView, observedEvent: Event<Element>)
|
||||
}
|
||||
|
||||
#endif
|
||||
27
Pods/RxCocoa/RxCocoa/iOS/Protocols/RxTableViewDataSourceType.swift
generated
Normal file
27
Pods/RxCocoa/RxCocoa/iOS/Protocols/RxTableViewDataSourceType.swift
generated
Normal file
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// RxTableViewDataSourceType.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 6/26/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
|
||||
import UIKit
|
||||
import RxSwift
|
||||
|
||||
/// Marks data source as `UITableView` reactive data source enabling it to be used with one of the `bindTo` methods.
|
||||
public protocol RxTableViewDataSourceType /*: UITableViewDataSource*/ {
|
||||
|
||||
/// Type of elements that can be bound to table view.
|
||||
associatedtype Element
|
||||
|
||||
/// New observable sequence event observed.
|
||||
///
|
||||
/// - parameter tableView: Bound table view.
|
||||
/// - parameter observedEvent: Event
|
||||
func tableView(_ tableView: UITableView, observedEvent: Event<Element>)
|
||||
}
|
||||
|
||||
#endif
|
||||
92
Pods/RxCocoa/RxCocoa/iOS/Proxies/RxCollectionViewDataSourcePrefetchingProxy.swift
generated
Normal file
92
Pods/RxCocoa/RxCocoa/iOS/Proxies/RxCollectionViewDataSourcePrefetchingProxy.swift
generated
Normal file
@@ -0,0 +1,92 @@
|
||||
//
|
||||
// RxCollectionViewDataSourcePrefetchingProxy.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Rowan Livingstone on 2/15/18.
|
||||
// Copyright © 2018 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
|
||||
import UIKit
|
||||
import RxSwift
|
||||
|
||||
@available(iOS 10.0, tvOS 10.0, *)
|
||||
extension UICollectionView: HasPrefetchDataSource {
|
||||
public typealias PrefetchDataSource = UICollectionViewDataSourcePrefetching
|
||||
}
|
||||
|
||||
@available(iOS 10.0, tvOS 10.0, *)
|
||||
private let collectionViewPrefetchDataSourceNotSet = CollectionViewPrefetchDataSourceNotSet()
|
||||
|
||||
@available(iOS 10.0, tvOS 10.0, *)
|
||||
private final class CollectionViewPrefetchDataSourceNotSet
|
||||
: NSObject
|
||||
, UICollectionViewDataSourcePrefetching {
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView, prefetchItemsAt indexPaths: [IndexPath]) {}
|
||||
|
||||
}
|
||||
|
||||
@available(iOS 10.0, tvOS 10.0, *)
|
||||
open class RxCollectionViewDataSourcePrefetchingProxy
|
||||
: DelegateProxy<UICollectionView, UICollectionViewDataSourcePrefetching>
|
||||
, DelegateProxyType {
|
||||
|
||||
/// Typed parent object.
|
||||
public weak private(set) var collectionView: UICollectionView?
|
||||
|
||||
/// - parameter collectionView: Parent object for delegate proxy.
|
||||
public init(collectionView: ParentObject) {
|
||||
self.collectionView = collectionView
|
||||
super.init(parentObject: collectionView, delegateProxy: RxCollectionViewDataSourcePrefetchingProxy.self)
|
||||
}
|
||||
|
||||
// Register known implementations
|
||||
public static func registerKnownImplementations() {
|
||||
self.register { RxCollectionViewDataSourcePrefetchingProxy(collectionView: $0) }
|
||||
}
|
||||
|
||||
private var _prefetchItemsPublishSubject: PublishSubject<[IndexPath]>?
|
||||
|
||||
/// Optimized version used for observing prefetch items callbacks.
|
||||
internal var prefetchItemsPublishSubject: PublishSubject<[IndexPath]> {
|
||||
if let subject = _prefetchItemsPublishSubject {
|
||||
return subject
|
||||
}
|
||||
|
||||
let subject = PublishSubject<[IndexPath]>()
|
||||
_prefetchItemsPublishSubject = subject
|
||||
|
||||
return subject
|
||||
}
|
||||
|
||||
private weak var _requiredMethodsPrefetchDataSource: UICollectionViewDataSourcePrefetching? = collectionViewPrefetchDataSourceNotSet
|
||||
|
||||
/// For more information take a look at `DelegateProxyType`.
|
||||
open override func setForwardToDelegate(_ forwardToDelegate: UICollectionViewDataSourcePrefetching?, retainDelegate: Bool) {
|
||||
_requiredMethodsPrefetchDataSource = forwardToDelegate ?? collectionViewPrefetchDataSourceNotSet
|
||||
super.setForwardToDelegate(forwardToDelegate, retainDelegate: retainDelegate)
|
||||
}
|
||||
|
||||
deinit {
|
||||
if let subject = _prefetchItemsPublishSubject {
|
||||
subject.on(.completed)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@available(iOS 10.0, tvOS 10.0, *)
|
||||
extension RxCollectionViewDataSourcePrefetchingProxy: UICollectionViewDataSourcePrefetching {
|
||||
/// Required delegate method implementation.
|
||||
public func collectionView(_ collectionView: UICollectionView, prefetchItemsAt indexPaths: [IndexPath]) {
|
||||
if let subject = _prefetchItemsPublishSubject {
|
||||
subject.on(.next(indexPaths))
|
||||
}
|
||||
|
||||
(_requiredMethodsPrefetchDataSource ?? collectionViewPrefetchDataSourceNotSet).collectionView(collectionView, prefetchItemsAt: indexPaths)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
75
Pods/RxCocoa/RxCocoa/iOS/Proxies/RxCollectionViewDataSourceProxy.swift
generated
Normal file
75
Pods/RxCocoa/RxCocoa/iOS/Proxies/RxCollectionViewDataSourceProxy.swift
generated
Normal file
@@ -0,0 +1,75 @@
|
||||
//
|
||||
// RxCollectionViewDataSourceProxy.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 6/29/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
|
||||
import UIKit
|
||||
import RxSwift
|
||||
|
||||
extension UICollectionView: HasDataSource {
|
||||
public typealias DataSource = UICollectionViewDataSource
|
||||
}
|
||||
|
||||
private let collectionViewDataSourceNotSet = CollectionViewDataSourceNotSet()
|
||||
|
||||
private final class CollectionViewDataSourceNotSet
|
||||
: NSObject
|
||||
, UICollectionViewDataSource {
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
||||
0
|
||||
}
|
||||
|
||||
// The cell that is returned must be retrieved from a call to -dequeueReusableCellWithReuseIdentifier:forIndexPath:
|
||||
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
||||
rxAbstractMethod(message: dataSourceNotSet)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// For more information take a look at `DelegateProxyType`.
|
||||
open class RxCollectionViewDataSourceProxy
|
||||
: DelegateProxy<UICollectionView, UICollectionViewDataSource>
|
||||
, DelegateProxyType {
|
||||
|
||||
/// Typed parent object.
|
||||
public weak private(set) var collectionView: UICollectionView?
|
||||
|
||||
/// - parameter collectionView: Parent object for delegate proxy.
|
||||
public init(collectionView: ParentObject) {
|
||||
self.collectionView = collectionView
|
||||
super.init(parentObject: collectionView, delegateProxy: RxCollectionViewDataSourceProxy.self)
|
||||
}
|
||||
|
||||
// Register known implementations
|
||||
public static func registerKnownImplementations() {
|
||||
self.register { RxCollectionViewDataSourceProxy(collectionView: $0) }
|
||||
}
|
||||
|
||||
private weak var _requiredMethodsDataSource: UICollectionViewDataSource? = collectionViewDataSourceNotSet
|
||||
|
||||
/// For more information take a look at `DelegateProxyType`.
|
||||
open override func setForwardToDelegate(_ forwardToDelegate: UICollectionViewDataSource?, retainDelegate: Bool) {
|
||||
_requiredMethodsDataSource = forwardToDelegate ?? collectionViewDataSourceNotSet
|
||||
super.setForwardToDelegate(forwardToDelegate, retainDelegate: retainDelegate)
|
||||
}
|
||||
}
|
||||
|
||||
extension RxCollectionViewDataSourceProxy: UICollectionViewDataSource {
|
||||
/// Required delegate method implementation.
|
||||
public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
||||
(_requiredMethodsDataSource ?? collectionViewDataSourceNotSet).collectionView(collectionView, numberOfItemsInSection: section)
|
||||
}
|
||||
|
||||
/// Required delegate method implementation.
|
||||
public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
||||
(_requiredMethodsDataSource ?? collectionViewDataSourceNotSet).collectionView(collectionView, cellForItemAt: indexPath)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
32
Pods/RxCocoa/RxCocoa/iOS/Proxies/RxCollectionViewDelegateProxy.swift
generated
Normal file
32
Pods/RxCocoa/RxCocoa/iOS/Proxies/RxCollectionViewDelegateProxy.swift
generated
Normal file
@@ -0,0 +1,32 @@
|
||||
//
|
||||
// RxCollectionViewDelegateProxy.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 6/29/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
|
||||
import UIKit
|
||||
import RxSwift
|
||||
|
||||
/// For more information take a look at `DelegateProxyType`.
|
||||
open class RxCollectionViewDelegateProxy
|
||||
: RxScrollViewDelegateProxy {
|
||||
|
||||
/// Typed parent object.
|
||||
public weak private(set) var collectionView: UICollectionView?
|
||||
|
||||
/// Initializes `RxCollectionViewDelegateProxy`
|
||||
///
|
||||
/// - parameter collectionView: Parent object for delegate proxy.
|
||||
public init(collectionView: UICollectionView) {
|
||||
self.collectionView = collectionView
|
||||
super.init(scrollView: collectionView)
|
||||
}
|
||||
}
|
||||
|
||||
extension RxCollectionViewDelegateProxy: UICollectionViewDelegateFlowLayout {}
|
||||
|
||||
#endif
|
||||
39
Pods/RxCocoa/RxCocoa/iOS/Proxies/RxNavigationControllerDelegateProxy.swift
generated
Normal file
39
Pods/RxCocoa/RxCocoa/iOS/Proxies/RxNavigationControllerDelegateProxy.swift
generated
Normal file
@@ -0,0 +1,39 @@
|
||||
//
|
||||
// RxNavigationControllerDelegateProxy.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Diogo on 13/04/17.
|
||||
// Copyright © 2017 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
|
||||
import UIKit
|
||||
import RxSwift
|
||||
|
||||
extension UINavigationController: HasDelegate {
|
||||
public typealias Delegate = UINavigationControllerDelegate
|
||||
}
|
||||
|
||||
/// For more information take a look at `DelegateProxyType`.
|
||||
open class RxNavigationControllerDelegateProxy
|
||||
: DelegateProxy<UINavigationController, UINavigationControllerDelegate>
|
||||
, DelegateProxyType {
|
||||
|
||||
/// Typed parent object.
|
||||
public weak private(set) var navigationController: UINavigationController?
|
||||
|
||||
/// - parameter navigationController: Parent object for delegate proxy.
|
||||
public init(navigationController: ParentObject) {
|
||||
self.navigationController = navigationController
|
||||
super.init(parentObject: navigationController, delegateProxy: RxNavigationControllerDelegateProxy.self)
|
||||
}
|
||||
|
||||
// Register known implementations
|
||||
public static func registerKnownImplementations() {
|
||||
self.register { RxNavigationControllerDelegateProxy(navigationController: $0) }
|
||||
}
|
||||
}
|
||||
|
||||
extension RxNavigationControllerDelegateProxy: UINavigationControllerDelegate {}
|
||||
#endif
|
||||
72
Pods/RxCocoa/RxCocoa/iOS/Proxies/RxPickerViewDataSourceProxy.swift
generated
Normal file
72
Pods/RxCocoa/RxCocoa/iOS/Proxies/RxPickerViewDataSourceProxy.swift
generated
Normal file
@@ -0,0 +1,72 @@
|
||||
//
|
||||
// RxPickerViewDataSourceProxy.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Sergey Shulga on 05/07/2017.
|
||||
// Copyright © 2017 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS)
|
||||
|
||||
import UIKit
|
||||
import RxSwift
|
||||
|
||||
extension UIPickerView: HasDataSource {
|
||||
public typealias DataSource = UIPickerViewDataSource
|
||||
}
|
||||
|
||||
private let pickerViewDataSourceNotSet = PickerViewDataSourceNotSet()
|
||||
|
||||
final private class PickerViewDataSourceNotSet: NSObject, UIPickerViewDataSource {
|
||||
func numberOfComponents(in pickerView: UIPickerView) -> Int {
|
||||
0
|
||||
}
|
||||
|
||||
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
/// For more information take a look at `DelegateProxyType`.
|
||||
public class RxPickerViewDataSourceProxy
|
||||
: DelegateProxy<UIPickerView, UIPickerViewDataSource>
|
||||
, DelegateProxyType {
|
||||
|
||||
/// Typed parent object.
|
||||
public weak private(set) var pickerView: UIPickerView?
|
||||
|
||||
/// - parameter pickerView: Parent object for delegate proxy.
|
||||
public init(pickerView: ParentObject) {
|
||||
self.pickerView = pickerView
|
||||
super.init(parentObject: pickerView, delegateProxy: RxPickerViewDataSourceProxy.self)
|
||||
}
|
||||
|
||||
// Register known implementations
|
||||
public static func registerKnownImplementations() {
|
||||
self.register { RxPickerViewDataSourceProxy(pickerView: $0) }
|
||||
}
|
||||
|
||||
private weak var _requiredMethodsDataSource: UIPickerViewDataSource? = pickerViewDataSourceNotSet
|
||||
|
||||
/// For more information take a look at `DelegateProxyType`.
|
||||
public override func setForwardToDelegate(_ forwardToDelegate: UIPickerViewDataSource?, retainDelegate: Bool) {
|
||||
_requiredMethodsDataSource = forwardToDelegate ?? pickerViewDataSourceNotSet
|
||||
super.setForwardToDelegate(forwardToDelegate, retainDelegate: retainDelegate)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: UIPickerViewDataSource
|
||||
|
||||
extension RxPickerViewDataSourceProxy: UIPickerViewDataSource {
|
||||
/// Required delegate method implementation.
|
||||
public func numberOfComponents(in pickerView: UIPickerView) -> Int {
|
||||
(_requiredMethodsDataSource ?? pickerViewDataSourceNotSet).numberOfComponents(in: pickerView)
|
||||
}
|
||||
|
||||
/// Required delegate method implementation.
|
||||
public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
|
||||
(_requiredMethodsDataSource ?? pickerViewDataSourceNotSet).pickerView(pickerView, numberOfRowsInComponent: component)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
38
Pods/RxCocoa/RxCocoa/iOS/Proxies/RxPickerViewDelegateProxy.swift
generated
Normal file
38
Pods/RxCocoa/RxCocoa/iOS/Proxies/RxPickerViewDelegateProxy.swift
generated
Normal file
@@ -0,0 +1,38 @@
|
||||
//
|
||||
// RxPickerViewDelegateProxy.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Segii Shulga on 5/12/16.
|
||||
// Copyright © 2016 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS)
|
||||
|
||||
import RxSwift
|
||||
import UIKit
|
||||
|
||||
extension UIPickerView: HasDelegate {
|
||||
public typealias Delegate = UIPickerViewDelegate
|
||||
}
|
||||
|
||||
open class RxPickerViewDelegateProxy
|
||||
: DelegateProxy<UIPickerView, UIPickerViewDelegate>
|
||||
, DelegateProxyType {
|
||||
|
||||
/// Typed parent object.
|
||||
public weak private(set) var pickerView: UIPickerView?
|
||||
|
||||
/// - parameter pickerView: Parent object for delegate proxy.
|
||||
public init(pickerView: ParentObject) {
|
||||
self.pickerView = pickerView
|
||||
super.init(parentObject: pickerView, delegateProxy: RxPickerViewDelegateProxy.self)
|
||||
}
|
||||
|
||||
// Register known implementations
|
||||
public static func registerKnownImplementations() {
|
||||
self.register { RxPickerViewDelegateProxy(pickerView: $0) }
|
||||
}
|
||||
}
|
||||
|
||||
extension RxPickerViewDelegateProxy: UIPickerViewDelegate {}
|
||||
#endif
|
||||
91
Pods/RxCocoa/RxCocoa/iOS/Proxies/RxScrollViewDelegateProxy.swift
generated
Normal file
91
Pods/RxCocoa/RxCocoa/iOS/Proxies/RxScrollViewDelegateProxy.swift
generated
Normal file
@@ -0,0 +1,91 @@
|
||||
//
|
||||
// RxScrollViewDelegateProxy.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 6/19/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
|
||||
import RxSwift
|
||||
import UIKit
|
||||
|
||||
extension UIScrollView: HasDelegate {
|
||||
public typealias Delegate = UIScrollViewDelegate
|
||||
}
|
||||
|
||||
/// For more information take a look at `DelegateProxyType`.
|
||||
open class RxScrollViewDelegateProxy
|
||||
: DelegateProxy<UIScrollView, UIScrollViewDelegate>
|
||||
, DelegateProxyType {
|
||||
|
||||
/// Typed parent object.
|
||||
public weak private(set) var scrollView: UIScrollView?
|
||||
|
||||
/// - parameter scrollView: Parent object for delegate proxy.
|
||||
public init(scrollView: ParentObject) {
|
||||
self.scrollView = scrollView
|
||||
super.init(parentObject: scrollView, delegateProxy: RxScrollViewDelegateProxy.self)
|
||||
}
|
||||
|
||||
// Register known implementations
|
||||
public static func registerKnownImplementations() {
|
||||
self.register { RxScrollViewDelegateProxy(scrollView: $0) }
|
||||
self.register { RxTableViewDelegateProxy(tableView: $0) }
|
||||
self.register { RxCollectionViewDelegateProxy(collectionView: $0) }
|
||||
self.register { RxTextViewDelegateProxy(textView: $0) }
|
||||
}
|
||||
|
||||
private var _contentOffsetBehaviorSubject: BehaviorSubject<CGPoint>?
|
||||
private var _contentOffsetPublishSubject: PublishSubject<()>?
|
||||
|
||||
/// Optimized version used for observing content offset changes.
|
||||
internal var contentOffsetBehaviorSubject: BehaviorSubject<CGPoint> {
|
||||
if let subject = _contentOffsetBehaviorSubject {
|
||||
return subject
|
||||
}
|
||||
|
||||
let subject = BehaviorSubject<CGPoint>(value: self.scrollView?.contentOffset ?? CGPoint.zero)
|
||||
_contentOffsetBehaviorSubject = subject
|
||||
|
||||
return subject
|
||||
}
|
||||
|
||||
/// Optimized version used for observing content offset changes.
|
||||
internal var contentOffsetPublishSubject: PublishSubject<()> {
|
||||
if let subject = _contentOffsetPublishSubject {
|
||||
return subject
|
||||
}
|
||||
|
||||
let subject = PublishSubject<()>()
|
||||
_contentOffsetPublishSubject = subject
|
||||
|
||||
return subject
|
||||
}
|
||||
|
||||
deinit {
|
||||
if let subject = _contentOffsetBehaviorSubject {
|
||||
subject.on(.completed)
|
||||
}
|
||||
|
||||
if let subject = _contentOffsetPublishSubject {
|
||||
subject.on(.completed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension RxScrollViewDelegateProxy: UIScrollViewDelegate {
|
||||
/// For more information take a look at `DelegateProxyType`.
|
||||
public func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
||||
if let subject = _contentOffsetBehaviorSubject {
|
||||
subject.on(.next(scrollView.contentOffset))
|
||||
}
|
||||
if let subject = _contentOffsetPublishSubject {
|
||||
subject.on(.next(()))
|
||||
}
|
||||
self._forwardToDelegate?.scrollViewDidScroll?(scrollView)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
40
Pods/RxCocoa/RxCocoa/iOS/Proxies/RxSearchBarDelegateProxy.swift
generated
Normal file
40
Pods/RxCocoa/RxCocoa/iOS/Proxies/RxSearchBarDelegateProxy.swift
generated
Normal file
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// RxSearchBarDelegateProxy.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 7/4/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
|
||||
import UIKit
|
||||
import RxSwift
|
||||
|
||||
extension UISearchBar: HasDelegate {
|
||||
public typealias Delegate = UISearchBarDelegate
|
||||
}
|
||||
|
||||
/// For more information take a look at `DelegateProxyType`.
|
||||
open class RxSearchBarDelegateProxy
|
||||
: DelegateProxy<UISearchBar, UISearchBarDelegate>
|
||||
, DelegateProxyType {
|
||||
|
||||
/// Typed parent object.
|
||||
public weak private(set) var searchBar: UISearchBar?
|
||||
|
||||
/// - parameter searchBar: Parent object for delegate proxy.
|
||||
public init(searchBar: ParentObject) {
|
||||
self.searchBar = searchBar
|
||||
super.init(parentObject: searchBar, delegateProxy: RxSearchBarDelegateProxy.self)
|
||||
}
|
||||
|
||||
// Register known implementations
|
||||
public static func registerKnownImplementations() {
|
||||
self.register { RxSearchBarDelegateProxy(searchBar: $0) }
|
||||
}
|
||||
}
|
||||
|
||||
extension RxSearchBarDelegateProxy: UISearchBarDelegate {}
|
||||
|
||||
#endif
|
||||
40
Pods/RxCocoa/RxCocoa/iOS/Proxies/RxSearchControllerDelegateProxy.swift
generated
Normal file
40
Pods/RxCocoa/RxCocoa/iOS/Proxies/RxSearchControllerDelegateProxy.swift
generated
Normal file
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// RxSearchControllerDelegateProxy.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Segii Shulga on 3/17/16.
|
||||
// Copyright © 2016 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS)
|
||||
|
||||
import RxSwift
|
||||
import UIKit
|
||||
|
||||
extension UISearchController: HasDelegate {
|
||||
public typealias Delegate = UISearchControllerDelegate
|
||||
}
|
||||
|
||||
/// For more information take a look at `DelegateProxyType`.
|
||||
open class RxSearchControllerDelegateProxy
|
||||
: DelegateProxy<UISearchController, UISearchControllerDelegate>
|
||||
, DelegateProxyType {
|
||||
|
||||
/// Typed parent object.
|
||||
public weak private(set) var searchController: UISearchController?
|
||||
|
||||
/// - parameter searchController: Parent object for delegate proxy.
|
||||
public init(searchController: UISearchController) {
|
||||
self.searchController = searchController
|
||||
super.init(parentObject: searchController, delegateProxy: RxSearchControllerDelegateProxy.self)
|
||||
}
|
||||
|
||||
// Register known implementations
|
||||
public static func registerKnownImplementations() {
|
||||
self.register { RxSearchControllerDelegateProxy(searchController: $0) }
|
||||
}
|
||||
}
|
||||
|
||||
extension RxSearchControllerDelegateProxy: UISearchControllerDelegate {}
|
||||
|
||||
#endif
|
||||
40
Pods/RxCocoa/RxCocoa/iOS/Proxies/RxTabBarControllerDelegateProxy.swift
generated
Normal file
40
Pods/RxCocoa/RxCocoa/iOS/Proxies/RxTabBarControllerDelegateProxy.swift
generated
Normal file
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// RxTabBarControllerDelegateProxy.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Yusuke Kita on 2016/12/07.
|
||||
// Copyright © 2016 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
|
||||
import UIKit
|
||||
import RxSwift
|
||||
|
||||
extension UITabBarController: HasDelegate {
|
||||
public typealias Delegate = UITabBarControllerDelegate
|
||||
}
|
||||
|
||||
/// For more information take a look at `DelegateProxyType`.
|
||||
open class RxTabBarControllerDelegateProxy
|
||||
: DelegateProxy<UITabBarController, UITabBarControllerDelegate>
|
||||
, DelegateProxyType {
|
||||
|
||||
/// Typed parent object.
|
||||
public weak private(set) var tabBar: UITabBarController?
|
||||
|
||||
/// - parameter tabBar: Parent object for delegate proxy.
|
||||
public init(tabBar: ParentObject) {
|
||||
self.tabBar = tabBar
|
||||
super.init(parentObject: tabBar, delegateProxy: RxTabBarControllerDelegateProxy.self)
|
||||
}
|
||||
|
||||
// Register known implementations
|
||||
public static func registerKnownImplementations() {
|
||||
self.register { RxTabBarControllerDelegateProxy(tabBar: $0) }
|
||||
}
|
||||
}
|
||||
|
||||
extension RxTabBarControllerDelegateProxy: UITabBarControllerDelegate {}
|
||||
|
||||
#endif
|
||||
50
Pods/RxCocoa/RxCocoa/iOS/Proxies/RxTabBarDelegateProxy.swift
generated
Normal file
50
Pods/RxCocoa/RxCocoa/iOS/Proxies/RxTabBarDelegateProxy.swift
generated
Normal file
@@ -0,0 +1,50 @@
|
||||
//
|
||||
// RxTabBarDelegateProxy.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Jesse Farless on 5/14/16.
|
||||
// Copyright © 2016 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
|
||||
import UIKit
|
||||
import RxSwift
|
||||
|
||||
extension UITabBar: HasDelegate {
|
||||
public typealias Delegate = UITabBarDelegate
|
||||
}
|
||||
|
||||
/// For more information take a look at `DelegateProxyType`.
|
||||
open class RxTabBarDelegateProxy
|
||||
: DelegateProxy<UITabBar, UITabBarDelegate>
|
||||
, DelegateProxyType {
|
||||
|
||||
/// Typed parent object.
|
||||
public weak private(set) var tabBar: UITabBar?
|
||||
|
||||
/// - parameter tabBar: Parent object for delegate proxy.
|
||||
public init(tabBar: ParentObject) {
|
||||
self.tabBar = tabBar
|
||||
super.init(parentObject: tabBar, delegateProxy: RxTabBarDelegateProxy.self)
|
||||
}
|
||||
|
||||
// Register known implementations
|
||||
public static func registerKnownImplementations() {
|
||||
self.register { RxTabBarDelegateProxy(tabBar: $0) }
|
||||
}
|
||||
|
||||
/// For more information take a look at `DelegateProxyType`.
|
||||
open class func currentDelegate(for object: ParentObject) -> UITabBarDelegate? {
|
||||
object.delegate
|
||||
}
|
||||
|
||||
/// For more information take a look at `DelegateProxyType`.
|
||||
open class func setCurrentDelegate(_ delegate: UITabBarDelegate?, to object: ParentObject) {
|
||||
object.delegate = delegate
|
||||
}
|
||||
}
|
||||
|
||||
extension RxTabBarDelegateProxy: UITabBarDelegate {}
|
||||
|
||||
#endif
|
||||
93
Pods/RxCocoa/RxCocoa/iOS/Proxies/RxTableViewDataSourcePrefetchingProxy.swift
generated
Normal file
93
Pods/RxCocoa/RxCocoa/iOS/Proxies/RxTableViewDataSourcePrefetchingProxy.swift
generated
Normal file
@@ -0,0 +1,93 @@
|
||||
//
|
||||
// RxTableViewDataSourcePrefetchingProxy.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Rowan Livingstone on 2/15/18.
|
||||
// Copyright © 2018 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
|
||||
import UIKit
|
||||
import RxSwift
|
||||
|
||||
@available(iOS 10.0, tvOS 10.0, *)
|
||||
extension UITableView: HasPrefetchDataSource {
|
||||
public typealias PrefetchDataSource = UITableViewDataSourcePrefetching
|
||||
}
|
||||
|
||||
@available(iOS 10.0, tvOS 10.0, *)
|
||||
private let tableViewPrefetchDataSourceNotSet = TableViewPrefetchDataSourceNotSet()
|
||||
|
||||
@available(iOS 10.0, tvOS 10.0, *)
|
||||
private final class TableViewPrefetchDataSourceNotSet
|
||||
: NSObject
|
||||
, UITableViewDataSourcePrefetching {
|
||||
|
||||
func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) {}
|
||||
|
||||
}
|
||||
|
||||
@available(iOS 10.0, tvOS 10.0, *)
|
||||
open class RxTableViewDataSourcePrefetchingProxy
|
||||
: DelegateProxy<UITableView, UITableViewDataSourcePrefetching>
|
||||
, DelegateProxyType {
|
||||
|
||||
/// Typed parent object.
|
||||
public weak private(set) var tableView: UITableView?
|
||||
|
||||
/// - parameter tableView: Parent object for delegate proxy.
|
||||
public init(tableView: ParentObject) {
|
||||
self.tableView = tableView
|
||||
super.init(parentObject: tableView, delegateProxy: RxTableViewDataSourcePrefetchingProxy.self)
|
||||
}
|
||||
|
||||
// Register known implementations
|
||||
public static func registerKnownImplementations() {
|
||||
self.register { RxTableViewDataSourcePrefetchingProxy(tableView: $0) }
|
||||
}
|
||||
|
||||
private var _prefetchRowsPublishSubject: PublishSubject<[IndexPath]>?
|
||||
|
||||
/// Optimized version used for observing prefetch rows callbacks.
|
||||
internal var prefetchRowsPublishSubject: PublishSubject<[IndexPath]> {
|
||||
if let subject = _prefetchRowsPublishSubject {
|
||||
return subject
|
||||
}
|
||||
|
||||
let subject = PublishSubject<[IndexPath]>()
|
||||
_prefetchRowsPublishSubject = subject
|
||||
|
||||
return subject
|
||||
}
|
||||
|
||||
private weak var _requiredMethodsPrefetchDataSource: UITableViewDataSourcePrefetching? = tableViewPrefetchDataSourceNotSet
|
||||
|
||||
/// For more information take a look at `DelegateProxyType`.
|
||||
open override func setForwardToDelegate(_ forwardToDelegate: UITableViewDataSourcePrefetching?, retainDelegate: Bool) {
|
||||
_requiredMethodsPrefetchDataSource = forwardToDelegate ?? tableViewPrefetchDataSourceNotSet
|
||||
super.setForwardToDelegate(forwardToDelegate, retainDelegate: retainDelegate)
|
||||
}
|
||||
|
||||
deinit {
|
||||
if let subject = _prefetchRowsPublishSubject {
|
||||
subject.on(.completed)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@available(iOS 10.0, tvOS 10.0, *)
|
||||
extension RxTableViewDataSourcePrefetchingProxy: UITableViewDataSourcePrefetching {
|
||||
/// Required delegate method implementation.
|
||||
public func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) {
|
||||
if let subject = _prefetchRowsPublishSubject {
|
||||
subject.on(.next(indexPaths))
|
||||
}
|
||||
|
||||
(_requiredMethodsPrefetchDataSource ?? tableViewPrefetchDataSourceNotSet).tableView(tableView, prefetchRowsAt: indexPaths)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
73
Pods/RxCocoa/RxCocoa/iOS/Proxies/RxTableViewDataSourceProxy.swift
generated
Normal file
73
Pods/RxCocoa/RxCocoa/iOS/Proxies/RxTableViewDataSourceProxy.swift
generated
Normal file
@@ -0,0 +1,73 @@
|
||||
//
|
||||
// RxTableViewDataSourceProxy.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 6/15/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
|
||||
import UIKit
|
||||
import RxSwift
|
||||
|
||||
extension UITableView: HasDataSource {
|
||||
public typealias DataSource = UITableViewDataSource
|
||||
}
|
||||
|
||||
private let tableViewDataSourceNotSet = TableViewDataSourceNotSet()
|
||||
|
||||
private final class TableViewDataSourceNotSet
|
||||
: NSObject
|
||||
, UITableViewDataSource {
|
||||
|
||||
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
0
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
rxAbstractMethod(message: dataSourceNotSet)
|
||||
}
|
||||
}
|
||||
|
||||
/// For more information take a look at `DelegateProxyType`.
|
||||
open class RxTableViewDataSourceProxy
|
||||
: DelegateProxy<UITableView, UITableViewDataSource>
|
||||
, DelegateProxyType {
|
||||
|
||||
/// Typed parent object.
|
||||
public weak private(set) var tableView: UITableView?
|
||||
|
||||
/// - parameter tableView: Parent object for delegate proxy.
|
||||
public init(tableView: UITableView) {
|
||||
self.tableView = tableView
|
||||
super.init(parentObject: tableView, delegateProxy: RxTableViewDataSourceProxy.self)
|
||||
}
|
||||
|
||||
// Register known implementations
|
||||
public static func registerKnownImplementations() {
|
||||
self.register { RxTableViewDataSourceProxy(tableView: $0) }
|
||||
}
|
||||
|
||||
private weak var _requiredMethodsDataSource: UITableViewDataSource? = tableViewDataSourceNotSet
|
||||
|
||||
/// For more information take a look at `DelegateProxyType`.
|
||||
open override func setForwardToDelegate(_ forwardToDelegate: UITableViewDataSource?, retainDelegate: Bool) {
|
||||
_requiredMethodsDataSource = forwardToDelegate ?? tableViewDataSourceNotSet
|
||||
super.setForwardToDelegate(forwardToDelegate, retainDelegate: retainDelegate)
|
||||
}
|
||||
}
|
||||
|
||||
extension RxTableViewDataSourceProxy: UITableViewDataSource {
|
||||
/// Required delegate method implementation.
|
||||
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
(_requiredMethodsDataSource ?? tableViewDataSourceNotSet).tableView(tableView, numberOfRowsInSection: section)
|
||||
}
|
||||
|
||||
/// Required delegate method implementation.
|
||||
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
(_requiredMethodsDataSource ?? tableViewDataSourceNotSet).tableView(tableView, cellForRowAt: indexPath)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
31
Pods/RxCocoa/RxCocoa/iOS/Proxies/RxTableViewDelegateProxy.swift
generated
Normal file
31
Pods/RxCocoa/RxCocoa/iOS/Proxies/RxTableViewDelegateProxy.swift
generated
Normal file
@@ -0,0 +1,31 @@
|
||||
//
|
||||
// RxTableViewDelegateProxy.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 6/15/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
|
||||
import UIKit
|
||||
import RxSwift
|
||||
|
||||
/// For more information take a look at `DelegateProxyType`.
|
||||
open class RxTableViewDelegateProxy
|
||||
: RxScrollViewDelegateProxy {
|
||||
|
||||
/// Typed parent object.
|
||||
public weak private(set) var tableView: UITableView?
|
||||
|
||||
/// - parameter tableView: Parent object for delegate proxy.
|
||||
public init(tableView: UITableView) {
|
||||
self.tableView = tableView
|
||||
super.init(scrollView: tableView)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension RxTableViewDelegateProxy: UITableViewDelegate {}
|
||||
|
||||
#endif
|
||||
38
Pods/RxCocoa/RxCocoa/iOS/Proxies/RxTextStorageDelegateProxy.swift
generated
Normal file
38
Pods/RxCocoa/RxCocoa/iOS/Proxies/RxTextStorageDelegateProxy.swift
generated
Normal file
@@ -0,0 +1,38 @@
|
||||
//
|
||||
// RxTextStorageDelegateProxy.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Segii Shulga on 12/30/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
|
||||
import RxSwift
|
||||
import UIKit
|
||||
|
||||
extension NSTextStorage: HasDelegate {
|
||||
public typealias Delegate = NSTextStorageDelegate
|
||||
}
|
||||
|
||||
open class RxTextStorageDelegateProxy
|
||||
: DelegateProxy<NSTextStorage, NSTextStorageDelegate>
|
||||
, DelegateProxyType {
|
||||
|
||||
/// Typed parent object.
|
||||
public weak private(set) var textStorage: NSTextStorage?
|
||||
|
||||
/// - parameter textStorage: Parent object for delegate proxy.
|
||||
public init(textStorage: NSTextStorage) {
|
||||
self.textStorage = textStorage
|
||||
super.init(parentObject: textStorage, delegateProxy: RxTextStorageDelegateProxy.self)
|
||||
}
|
||||
|
||||
// Register known implementations
|
||||
public static func registerKnownImplementations() {
|
||||
self.register { RxTextStorageDelegateProxy(textStorage: $0) }
|
||||
}
|
||||
}
|
||||
|
||||
extension RxTextStorageDelegateProxy: NSTextStorageDelegate {}
|
||||
#endif
|
||||
42
Pods/RxCocoa/RxCocoa/iOS/Proxies/RxTextViewDelegateProxy.swift
generated
Normal file
42
Pods/RxCocoa/RxCocoa/iOS/Proxies/RxTextViewDelegateProxy.swift
generated
Normal file
@@ -0,0 +1,42 @@
|
||||
//
|
||||
// RxTextViewDelegateProxy.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Yuta ToKoRo on 7/19/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
|
||||
import UIKit
|
||||
import RxSwift
|
||||
|
||||
/// For more information take a look at `DelegateProxyType`.
|
||||
open class RxTextViewDelegateProxy
|
||||
: RxScrollViewDelegateProxy {
|
||||
|
||||
/// Typed parent object.
|
||||
public weak private(set) var textView: UITextView?
|
||||
|
||||
/// - parameter textview: Parent object for delegate proxy.
|
||||
public init(textView: UITextView) {
|
||||
self.textView = textView
|
||||
super.init(scrollView: textView)
|
||||
}
|
||||
}
|
||||
|
||||
extension RxTextViewDelegateProxy: UITextViewDelegate {
|
||||
/// For more information take a look at `DelegateProxyType`.
|
||||
@objc open func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
|
||||
/**
|
||||
We've had some issues with observing text changes. This is here just in case we need the same hack in future and that
|
||||
we wouldn't need to change the public interface.
|
||||
*/
|
||||
let forwardToDelegate = self.forwardToDelegate() as? UITextViewDelegate
|
||||
return forwardToDelegate?.textView?(textView,
|
||||
shouldChangeTextIn: range,
|
||||
replacementText: text) ?? true
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
45
Pods/RxCocoa/RxCocoa/iOS/Proxies/RxWKNavigationDelegateProxy.swift
generated
Normal file
45
Pods/RxCocoa/RxCocoa/iOS/Proxies/RxWKNavigationDelegateProxy.swift
generated
Normal file
@@ -0,0 +1,45 @@
|
||||
//
|
||||
// RxWKNavigationDelegateProxy.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Giuseppe Lanza on 14/02/2020.
|
||||
// Copyright © 2020 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS) || os(macOS)
|
||||
|
||||
import RxSwift
|
||||
import WebKit
|
||||
|
||||
@available(iOS 8.0, OSX 10.10, OSXApplicationExtension 10.10, *)
|
||||
open class RxWKNavigationDelegateProxy
|
||||
: DelegateProxy<WKWebView, WKNavigationDelegate>
|
||||
, DelegateProxyType {
|
||||
|
||||
/// Typed parent object.
|
||||
public weak private(set) var webView: WKWebView?
|
||||
|
||||
/// - parameter webView: Parent object for delegate proxy.
|
||||
public init(webView: ParentObject) {
|
||||
self.webView = webView
|
||||
super.init(parentObject: webView, delegateProxy: RxWKNavigationDelegateProxy.self)
|
||||
}
|
||||
|
||||
// Register known implementations
|
||||
public static func registerKnownImplementations() {
|
||||
self.register { RxWKNavigationDelegateProxy(webView: $0) }
|
||||
}
|
||||
|
||||
public static func currentDelegate(for object: WKWebView) -> WKNavigationDelegate? {
|
||||
object.navigationDelegate
|
||||
}
|
||||
|
||||
public static func setCurrentDelegate(_ delegate: WKNavigationDelegate?, to object: WKWebView) {
|
||||
object.navigationDelegate = delegate
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 8.0, OSX 10.10, OSXApplicationExtension 10.10, *)
|
||||
extension RxWKNavigationDelegateProxy: WKNavigationDelegate {}
|
||||
|
||||
#endif
|
||||
27
Pods/RxCocoa/RxCocoa/iOS/UIActivityIndicatorView+Rx.swift
generated
Normal file
27
Pods/RxCocoa/RxCocoa/iOS/UIActivityIndicatorView+Rx.swift
generated
Normal file
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// UIActivityIndicatorView+Rx.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Ivan Persidskiy on 02/12/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
|
||||
import UIKit
|
||||
import RxSwift
|
||||
|
||||
extension Reactive where Base: UIActivityIndicatorView {
|
||||
/// Bindable sink for `startAnimating()`, `stopAnimating()` methods.
|
||||
public var isAnimating: Binder<Bool> {
|
||||
Binder(self.base) { activityIndicator, active in
|
||||
if active {
|
||||
activityIndicator.startAnimating()
|
||||
} else {
|
||||
activityIndicator.stopAnimating()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
106
Pods/RxCocoa/RxCocoa/iOS/UIApplication+Rx.swift
generated
Normal file
106
Pods/RxCocoa/RxCocoa/iOS/UIApplication+Rx.swift
generated
Normal file
@@ -0,0 +1,106 @@
|
||||
//
|
||||
// UIApplication+Rx.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Mads Bøgeskov on 18/01/16.
|
||||
// Copyright © 2016 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS)
|
||||
|
||||
import UIKit
|
||||
import RxSwift
|
||||
|
||||
extension Reactive where Base: UIApplication {
|
||||
/// Bindable sink for `isNetworkActivityIndicatorVisible`.
|
||||
public var isNetworkActivityIndicatorVisible: Binder<Bool> {
|
||||
return Binder(self.base) { application, active in
|
||||
application.isNetworkActivityIndicatorVisible = active
|
||||
}
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `UIApplication.didEnterBackgroundNotification`
|
||||
public static var didEnterBackground: ControlEvent<Void> {
|
||||
let source = NotificationCenter.default.rx.notification(UIApplication.didEnterBackgroundNotification).map { _ in }
|
||||
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `UIApplication.willEnterForegroundNotification`
|
||||
public static var willEnterForeground: ControlEvent<Void> {
|
||||
let source = NotificationCenter.default.rx.notification(UIApplication.willEnterForegroundNotification).map { _ in }
|
||||
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `UIApplication.didFinishLaunchingNotification`
|
||||
public static var didFinishLaunching: ControlEvent<Void> {
|
||||
let source = NotificationCenter.default.rx.notification(UIApplication.didFinishLaunchingNotification).map { _ in }
|
||||
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `UIApplication.didBecomeActiveNotification`
|
||||
public static var didBecomeActive: ControlEvent<Void> {
|
||||
let source = NotificationCenter.default.rx.notification(UIApplication.didBecomeActiveNotification).map { _ in }
|
||||
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `UIApplication.willResignActiveNotification`
|
||||
public static var willResignActive: ControlEvent<Void> {
|
||||
let source = NotificationCenter.default.rx.notification(UIApplication.willResignActiveNotification).map { _ in }
|
||||
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `UIApplication.didReceiveMemoryWarningNotification`
|
||||
public static var didReceiveMemoryWarning: ControlEvent<Void> {
|
||||
let source = NotificationCenter.default.rx.notification(UIApplication.didReceiveMemoryWarningNotification).map { _ in }
|
||||
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `UIApplication.willTerminateNotification`
|
||||
public static var willTerminate: ControlEvent<Void> {
|
||||
let source = NotificationCenter.default.rx.notification(UIApplication.willTerminateNotification).map { _ in }
|
||||
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `UIApplication.significantTimeChangeNotification`
|
||||
public static var significantTimeChange: ControlEvent<Void> {
|
||||
let source = NotificationCenter.default.rx.notification(UIApplication.significantTimeChangeNotification).map { _ in }
|
||||
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `UIApplication.backgroundRefreshStatusDidChangeNotification`
|
||||
public static var backgroundRefreshStatusDidChange: ControlEvent<Void> {
|
||||
let source = NotificationCenter.default.rx.notification(UIApplication.backgroundRefreshStatusDidChangeNotification).map { _ in }
|
||||
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `UIApplication.protectedDataWillBecomeUnavailableNotification`
|
||||
public static var protectedDataWillBecomeUnavailable: ControlEvent<Void> {
|
||||
let source = NotificationCenter.default.rx.notification(UIApplication.protectedDataWillBecomeUnavailableNotification).map { _ in }
|
||||
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `UIApplication.protectedDataDidBecomeAvailableNotification`
|
||||
public static var protectedDataDidBecomeAvailable: ControlEvent<Void> {
|
||||
let source = NotificationCenter.default.rx.notification(UIApplication.protectedDataDidBecomeAvailableNotification).map { _ in }
|
||||
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `UIApplication.userDidTakeScreenshotNotification`
|
||||
public static var userDidTakeScreenshot: ControlEvent<Void> {
|
||||
let source = NotificationCenter.default.rx.notification(UIApplication.userDidTakeScreenshotNotification).map { _ in }
|
||||
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
72
Pods/RxCocoa/RxCocoa/iOS/UIBarButtonItem+Rx.swift
generated
Normal file
72
Pods/RxCocoa/RxCocoa/iOS/UIBarButtonItem+Rx.swift
generated
Normal file
@@ -0,0 +1,72 @@
|
||||
//
|
||||
// UIBarButtonItem+Rx.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Daniel Tartaglia on 5/31/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
|
||||
import UIKit
|
||||
import RxSwift
|
||||
|
||||
private var rx_tap_key: UInt8 = 0
|
||||
|
||||
extension Reactive where Base: UIBarButtonItem {
|
||||
/// Reactive wrapper for target action pattern on `self`.
|
||||
public var tap: ControlEvent<()> {
|
||||
let source = lazyInstanceObservable(&rx_tap_key) { () -> Observable<()> in
|
||||
Observable.create { [weak control = self.base] observer in
|
||||
guard let control = control else {
|
||||
observer.on(.completed)
|
||||
return Disposables.create()
|
||||
}
|
||||
let target = BarButtonItemTarget(barButtonItem: control) {
|
||||
observer.on(.next(()))
|
||||
}
|
||||
return target
|
||||
}
|
||||
.take(until: self.deallocated)
|
||||
.share()
|
||||
}
|
||||
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@objc
|
||||
final class BarButtonItemTarget: RxTarget {
|
||||
typealias Callback = () -> Void
|
||||
|
||||
weak var barButtonItem: UIBarButtonItem?
|
||||
var callback: Callback!
|
||||
|
||||
init(barButtonItem: UIBarButtonItem, callback: @escaping () -> Void) {
|
||||
self.barButtonItem = barButtonItem
|
||||
self.callback = callback
|
||||
super.init()
|
||||
barButtonItem.target = self
|
||||
barButtonItem.action = #selector(BarButtonItemTarget.action(_:))
|
||||
}
|
||||
|
||||
override func dispose() {
|
||||
super.dispose()
|
||||
#if DEBUG
|
||||
MainScheduler.ensureRunningOnMainThread()
|
||||
#endif
|
||||
|
||||
barButtonItem?.target = nil
|
||||
barButtonItem?.action = nil
|
||||
|
||||
callback = nil
|
||||
}
|
||||
|
||||
@objc func action(_ sender: AnyObject) {
|
||||
callback()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
82
Pods/RxCocoa/RxCocoa/iOS/UIButton+Rx.swift
generated
Normal file
82
Pods/RxCocoa/RxCocoa/iOS/UIButton+Rx.swift
generated
Normal file
@@ -0,0 +1,82 @@
|
||||
//
|
||||
// UIButton+Rx.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 3/28/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS)
|
||||
|
||||
import RxSwift
|
||||
import UIKit
|
||||
|
||||
extension Reactive where Base: UIButton {
|
||||
|
||||
/// Reactive wrapper for `TouchUpInside` control event.
|
||||
public var tap: ControlEvent<Void> {
|
||||
controlEvent(.touchUpInside)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if os(tvOS)
|
||||
|
||||
import RxSwift
|
||||
import UIKit
|
||||
|
||||
extension Reactive where Base: UIButton {
|
||||
|
||||
/// Reactive wrapper for `PrimaryActionTriggered` control event.
|
||||
public var primaryAction: ControlEvent<Void> {
|
||||
controlEvent(.primaryActionTriggered)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
|
||||
import RxSwift
|
||||
import UIKit
|
||||
|
||||
extension Reactive where Base: UIButton {
|
||||
/// Reactive wrapper for `setTitle(_:for:)`
|
||||
public func title(for controlState: UIControl.State = []) -> Binder<String?> {
|
||||
Binder(self.base) { button, title in
|
||||
button.setTitle(title, for: controlState)
|
||||
}
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `setImage(_:for:)`
|
||||
public func image(for controlState: UIControl.State = []) -> Binder<UIImage?> {
|
||||
Binder(self.base) { button, image in
|
||||
button.setImage(image, for: controlState)
|
||||
}
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `setBackgroundImage(_:for:)`
|
||||
public func backgroundImage(for controlState: UIControl.State = []) -> Binder<UIImage?> {
|
||||
Binder(self.base) { button, image in
|
||||
button.setBackgroundImage(image, for: controlState)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
import RxSwift
|
||||
import UIKit
|
||||
|
||||
extension Reactive where Base: UIButton {
|
||||
/// Reactive wrapper for `setAttributedTitle(_:controlState:)`
|
||||
public func attributedTitle(for controlState: UIControl.State = []) -> Binder<NSAttributedString?> {
|
||||
return Binder(self.base) { button, attributedTitle -> Void in
|
||||
button.setAttributedTitle(attributedTitle, for: controlState)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
380
Pods/RxCocoa/RxCocoa/iOS/UICollectionView+Rx.swift
generated
Normal file
380
Pods/RxCocoa/RxCocoa/iOS/UICollectionView+Rx.swift
generated
Normal file
@@ -0,0 +1,380 @@
|
||||
//
|
||||
// UICollectionView+Rx.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 4/2/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
|
||||
import RxSwift
|
||||
import UIKit
|
||||
|
||||
// Items
|
||||
|
||||
extension Reactive where Base: UICollectionView {
|
||||
|
||||
/**
|
||||
Binds sequences of elements to collection view items.
|
||||
|
||||
- parameter source: Observable sequence of items.
|
||||
- parameter cellFactory: Transform between sequence elements and view cells.
|
||||
- returns: Disposable object that can be used to unbind.
|
||||
|
||||
Example
|
||||
|
||||
let items = Observable.just([
|
||||
1,
|
||||
2,
|
||||
3
|
||||
])
|
||||
|
||||
items
|
||||
.bind(to: collectionView.rx.items) { (collectionView, row, element) in
|
||||
let indexPath = IndexPath(row: row, section: 0)
|
||||
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! NumberCell
|
||||
cell.value?.text = "\(element) @ \(row)"
|
||||
return cell
|
||||
}
|
||||
.disposed(by: disposeBag)
|
||||
*/
|
||||
public func items<Sequence: Swift.Sequence, Source: ObservableType>
|
||||
(_ source: Source)
|
||||
-> (_ cellFactory: @escaping (UICollectionView, Int, Sequence.Element) -> UICollectionViewCell)
|
||||
-> Disposable where Source.Element == Sequence {
|
||||
return { cellFactory in
|
||||
let dataSource = RxCollectionViewReactiveArrayDataSourceSequenceWrapper<Sequence>(cellFactory: cellFactory)
|
||||
return self.items(dataSource: dataSource)(source)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
Binds sequences of elements to collection view items.
|
||||
|
||||
- parameter cellIdentifier: Identifier used to dequeue cells.
|
||||
- parameter source: Observable sequence of items.
|
||||
- parameter configureCell: Transform between sequence elements and view cells.
|
||||
- parameter cellType: Type of collection view cell.
|
||||
- returns: Disposable object that can be used to unbind.
|
||||
|
||||
Example
|
||||
|
||||
let items = Observable.just([
|
||||
1,
|
||||
2,
|
||||
3
|
||||
])
|
||||
|
||||
items
|
||||
.bind(to: collectionView.rx.items(cellIdentifier: "Cell", cellType: NumberCell.self)) { (row, element, cell) in
|
||||
cell.value?.text = "\(element) @ \(row)"
|
||||
}
|
||||
.disposed(by: disposeBag)
|
||||
*/
|
||||
public func items<Sequence: Swift.Sequence, Cell: UICollectionViewCell, Source: ObservableType>
|
||||
(cellIdentifier: String, cellType: Cell.Type = Cell.self)
|
||||
-> (_ source: Source)
|
||||
-> (_ configureCell: @escaping (Int, Sequence.Element, Cell) -> Void)
|
||||
-> Disposable where Source.Element == Sequence {
|
||||
return { source in
|
||||
return { configureCell in
|
||||
let dataSource = RxCollectionViewReactiveArrayDataSourceSequenceWrapper<Sequence> { cv, i, item in
|
||||
let indexPath = IndexPath(item: i, section: 0)
|
||||
let cell = cv.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as! Cell
|
||||
configureCell(i, item, cell)
|
||||
return cell
|
||||
}
|
||||
|
||||
return self.items(dataSource: dataSource)(source)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Binds sequences of elements to collection view items using a custom reactive data used to perform the transformation.
|
||||
|
||||
- parameter dataSource: Data source used to transform elements to view cells.
|
||||
- parameter source: Observable sequence of items.
|
||||
- returns: Disposable object that can be used to unbind.
|
||||
|
||||
Example
|
||||
|
||||
let dataSource = RxCollectionViewSectionedReloadDataSource<SectionModel<String, Double>>()
|
||||
|
||||
let items = Observable.just([
|
||||
SectionModel(model: "First section", items: [
|
||||
1.0,
|
||||
2.0,
|
||||
3.0
|
||||
]),
|
||||
SectionModel(model: "Second section", items: [
|
||||
1.0,
|
||||
2.0,
|
||||
3.0
|
||||
]),
|
||||
SectionModel(model: "Third section", items: [
|
||||
1.0,
|
||||
2.0,
|
||||
3.0
|
||||
])
|
||||
])
|
||||
|
||||
dataSource.configureCell = { (dataSource, cv, indexPath, element) in
|
||||
let cell = cv.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! NumberCell
|
||||
cell.value?.text = "\(element) @ row \(indexPath.row)"
|
||||
return cell
|
||||
}
|
||||
|
||||
items
|
||||
.bind(to: collectionView.rx.items(dataSource: dataSource))
|
||||
.disposed(by: disposeBag)
|
||||
*/
|
||||
public func items<
|
||||
DataSource: RxCollectionViewDataSourceType & UICollectionViewDataSource,
|
||||
Source: ObservableType>
|
||||
(dataSource: DataSource)
|
||||
-> (_ source: Source)
|
||||
-> Disposable where DataSource.Element == Source.Element
|
||||
{
|
||||
return { source in
|
||||
// This is called for side effects only, and to make sure delegate proxy is in place when
|
||||
// data source is being bound.
|
||||
// This is needed because theoretically the data source subscription itself might
|
||||
// call `self.rx.delegate`. If that happens, it might cause weird side effects since
|
||||
// setting data source will set delegate, and UICollectionView might get into a weird state.
|
||||
// Therefore it's better to set delegate proxy first, just to be sure.
|
||||
_ = self.delegate
|
||||
// Strong reference is needed because data source is in use until result subscription is disposed
|
||||
return source.subscribeProxyDataSource(ofObject: self.base, dataSource: dataSource, retainDataSource: true) { [weak collectionView = self.base] (_: RxCollectionViewDataSourceProxy, event) -> Void in
|
||||
guard let collectionView = collectionView else {
|
||||
return
|
||||
}
|
||||
dataSource.collectionView(collectionView, observedEvent: event)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Reactive where Base: UICollectionView {
|
||||
public typealias DisplayCollectionViewCellEvent = (cell: UICollectionViewCell, at: IndexPath)
|
||||
public typealias DisplayCollectionViewSupplementaryViewEvent = (supplementaryView: UICollectionReusableView, elementKind: String, at: IndexPath)
|
||||
|
||||
/// Reactive wrapper for `dataSource`.
|
||||
///
|
||||
/// For more information take a look at `DelegateProxyType` protocol documentation.
|
||||
public var dataSource: DelegateProxy<UICollectionView, UICollectionViewDataSource> {
|
||||
RxCollectionViewDataSourceProxy.proxy(for: base)
|
||||
}
|
||||
|
||||
/// Installs data source as forwarding delegate on `rx.dataSource`.
|
||||
/// Data source won't be retained.
|
||||
///
|
||||
/// It enables using normal delegate mechanism with reactive delegate mechanism.
|
||||
///
|
||||
/// - parameter dataSource: Data source object.
|
||||
/// - returns: Disposable object that can be used to unbind the data source.
|
||||
public func setDataSource(_ dataSource: UICollectionViewDataSource)
|
||||
-> Disposable {
|
||||
RxCollectionViewDataSourceProxy.installForwardDelegate(dataSource, retainDelegate: false, onProxyForObject: self.base)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `delegate` message `collectionView(_:didSelectItemAtIndexPath:)`.
|
||||
public var itemSelected: ControlEvent<IndexPath> {
|
||||
let source = delegate.methodInvoked(#selector(UICollectionViewDelegate.collectionView(_:didSelectItemAt:)))
|
||||
.map { a in
|
||||
return try castOrThrow(IndexPath.self, a[1])
|
||||
}
|
||||
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `delegate` message `collectionView(_:didDeselectItemAtIndexPath:)`.
|
||||
public var itemDeselected: ControlEvent<IndexPath> {
|
||||
let source = delegate.methodInvoked(#selector(UICollectionViewDelegate.collectionView(_:didDeselectItemAt:)))
|
||||
.map { a in
|
||||
return try castOrThrow(IndexPath.self, a[1])
|
||||
}
|
||||
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `delegate` message `collectionView(_:didHighlightItemAt:)`.
|
||||
public var itemHighlighted: ControlEvent<IndexPath> {
|
||||
let source = delegate.methodInvoked(#selector(UICollectionViewDelegate.collectionView(_:didHighlightItemAt:)))
|
||||
.map { a in
|
||||
return try castOrThrow(IndexPath.self, a[1])
|
||||
}
|
||||
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `delegate` message `collectionView(_:didUnhighlightItemAt:)`.
|
||||
public var itemUnhighlighted: ControlEvent<IndexPath> {
|
||||
let source = delegate.methodInvoked(#selector(UICollectionViewDelegate.collectionView(_:didUnhighlightItemAt:)))
|
||||
.map { a in
|
||||
return try castOrThrow(IndexPath.self, a[1])
|
||||
}
|
||||
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `delegate` message `collectionView:willDisplay:forItemAt:`.
|
||||
public var willDisplayCell: ControlEvent<DisplayCollectionViewCellEvent> {
|
||||
let source: Observable<DisplayCollectionViewCellEvent> = self.delegate.methodInvoked(#selector(UICollectionViewDelegate.collectionView(_:willDisplay:forItemAt:)))
|
||||
.map { a in
|
||||
return (try castOrThrow(UICollectionViewCell.self, a[1]), try castOrThrow(IndexPath.self, a[2]))
|
||||
}
|
||||
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `delegate` message `collectionView(_:willDisplaySupplementaryView:forElementKind:at:)`.
|
||||
public var willDisplaySupplementaryView: ControlEvent<DisplayCollectionViewSupplementaryViewEvent> {
|
||||
let source: Observable<DisplayCollectionViewSupplementaryViewEvent> = self.delegate.methodInvoked(#selector(UICollectionViewDelegate.collectionView(_:willDisplaySupplementaryView:forElementKind:at:)))
|
||||
.map { a in
|
||||
return (try castOrThrow(UICollectionReusableView.self, a[1]),
|
||||
try castOrThrow(String.self, a[2]),
|
||||
try castOrThrow(IndexPath.self, a[3]))
|
||||
}
|
||||
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `delegate` message `collectionView:didEndDisplaying:forItemAt:`.
|
||||
public var didEndDisplayingCell: ControlEvent<DisplayCollectionViewCellEvent> {
|
||||
let source: Observable<DisplayCollectionViewCellEvent> = self.delegate.methodInvoked(#selector(UICollectionViewDelegate.collectionView(_:didEndDisplaying:forItemAt:)))
|
||||
.map { a in
|
||||
return (try castOrThrow(UICollectionViewCell.self, a[1]), try castOrThrow(IndexPath.self, a[2]))
|
||||
}
|
||||
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `delegate` message `collectionView(_:didEndDisplayingSupplementaryView:forElementOfKind:at:)`.
|
||||
public var didEndDisplayingSupplementaryView: ControlEvent<DisplayCollectionViewSupplementaryViewEvent> {
|
||||
let source: Observable<DisplayCollectionViewSupplementaryViewEvent> = self.delegate.methodInvoked(#selector(UICollectionViewDelegate.collectionView(_:didEndDisplayingSupplementaryView:forElementOfKind:at:)))
|
||||
.map { a in
|
||||
return (try castOrThrow(UICollectionReusableView.self, a[1]),
|
||||
try castOrThrow(String.self, a[2]),
|
||||
try castOrThrow(IndexPath.self, a[3]))
|
||||
}
|
||||
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `delegate` message `collectionView(_:didSelectItemAtIndexPath:)`.
|
||||
///
|
||||
/// It can be only used when one of the `rx.itemsWith*` methods is used to bind observable sequence,
|
||||
/// or any other data source conforming to `SectionedViewDataSourceType` protocol.
|
||||
///
|
||||
/// ```
|
||||
/// collectionView.rx.modelSelected(MyModel.self)
|
||||
/// .map { ...
|
||||
/// ```
|
||||
public func modelSelected<T>(_ modelType: T.Type) -> ControlEvent<T> {
|
||||
let source: Observable<T> = itemSelected.flatMap { [weak view = self.base as UICollectionView] indexPath -> Observable<T> in
|
||||
guard let view = view else {
|
||||
return Observable.empty()
|
||||
}
|
||||
|
||||
return Observable.just(try view.rx.model(at: indexPath))
|
||||
}
|
||||
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `delegate` message `collectionView(_:didSelectItemAtIndexPath:)`.
|
||||
///
|
||||
/// It can be only used when one of the `rx.itemsWith*` methods is used to bind observable sequence,
|
||||
/// or any other data source conforming to `SectionedViewDataSourceType` protocol.
|
||||
///
|
||||
/// ```
|
||||
/// collectionView.rx.modelDeselected(MyModel.self)
|
||||
/// .map { ...
|
||||
/// ```
|
||||
public func modelDeselected<T>(_ modelType: T.Type) -> ControlEvent<T> {
|
||||
let source: Observable<T> = itemDeselected.flatMap { [weak view = self.base as UICollectionView] indexPath -> Observable<T> in
|
||||
guard let view = view else {
|
||||
return Observable.empty()
|
||||
}
|
||||
|
||||
return Observable.just(try view.rx.model(at: indexPath))
|
||||
}
|
||||
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Synchronous helper method for retrieving a model at indexPath through a reactive data source
|
||||
public func model<T>(at indexPath: IndexPath) throws -> T {
|
||||
let dataSource: SectionedViewDataSourceType = castOrFatalError(self.dataSource.forwardToDelegate(), message: "This method only works in case one of the `rx.itemsWith*` methods was used.")
|
||||
|
||||
let element = try dataSource.model(at: indexPath)
|
||||
|
||||
return try castOrThrow(T.self, element)
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 10.0, tvOS 10.0, *)
|
||||
extension Reactive where Base: UICollectionView {
|
||||
|
||||
/// Reactive wrapper for `prefetchDataSource`.
|
||||
///
|
||||
/// For more information take a look at `DelegateProxyType` protocol documentation.
|
||||
public var prefetchDataSource: DelegateProxy<UICollectionView, UICollectionViewDataSourcePrefetching> {
|
||||
RxCollectionViewDataSourcePrefetchingProxy.proxy(for: base)
|
||||
}
|
||||
|
||||
/**
|
||||
Installs prefetch data source as forwarding delegate on `rx.prefetchDataSource`.
|
||||
Prefetch data source won't be retained.
|
||||
|
||||
It enables using normal delegate mechanism with reactive delegate mechanism.
|
||||
|
||||
- parameter prefetchDataSource: Prefetch data source object.
|
||||
- returns: Disposable object that can be used to unbind the data source.
|
||||
*/
|
||||
public func setPrefetchDataSource(_ prefetchDataSource: UICollectionViewDataSourcePrefetching)
|
||||
-> Disposable {
|
||||
return RxCollectionViewDataSourcePrefetchingProxy.installForwardDelegate(prefetchDataSource, retainDelegate: false, onProxyForObject: self.base)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `prefetchDataSource` message `collectionView(_:prefetchItemsAt:)`.
|
||||
public var prefetchItems: ControlEvent<[IndexPath]> {
|
||||
let source = RxCollectionViewDataSourcePrefetchingProxy.proxy(for: base).prefetchItemsPublishSubject
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `prefetchDataSource` message `collectionView(_:cancelPrefetchingForItemsAt:)`.
|
||||
public var cancelPrefetchingForItems: ControlEvent<[IndexPath]> {
|
||||
let source = prefetchDataSource.methodInvoked(#selector(UICollectionViewDataSourcePrefetching.collectionView(_:cancelPrefetchingForItemsAt:)))
|
||||
.map { a in
|
||||
return try castOrThrow(Array<IndexPath>.self, a[1])
|
||||
}
|
||||
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#if os(tvOS)
|
||||
|
||||
extension Reactive where Base: UICollectionView {
|
||||
|
||||
/// Reactive wrapper for `delegate` message `collectionView(_:didUpdateFocusInContext:withAnimationCoordinator:)`.
|
||||
public var didUpdateFocusInContextWithAnimationCoordinator: ControlEvent<(context: UICollectionViewFocusUpdateContext, animationCoordinator: UIFocusAnimationCoordinator)> {
|
||||
|
||||
let source = delegate.methodInvoked(#selector(UICollectionViewDelegate.collectionView(_:didUpdateFocusIn:with:)))
|
||||
.map { a -> (context: UICollectionViewFocusUpdateContext, animationCoordinator: UIFocusAnimationCoordinator) in
|
||||
let context = try castOrThrow(UICollectionViewFocusUpdateContext.self, a[1])
|
||||
let animationCoordinator = try castOrThrow(UIFocusAnimationCoordinator.self, a[2])
|
||||
return (context: context, animationCoordinator: animationCoordinator)
|
||||
}
|
||||
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
86
Pods/RxCocoa/RxCocoa/iOS/UIControl+Rx.swift
generated
Normal file
86
Pods/RxCocoa/RxCocoa/iOS/UIControl+Rx.swift
generated
Normal file
@@ -0,0 +1,86 @@
|
||||
//
|
||||
// UIControl+Rx.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Daniel Tartaglia on 5/23/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
|
||||
import RxSwift
|
||||
import UIKit
|
||||
|
||||
extension Reactive where Base: UIControl {
|
||||
/// Reactive wrapper for target action pattern.
|
||||
///
|
||||
/// - parameter controlEvents: Filter for observed event types.
|
||||
public func controlEvent(_ controlEvents: UIControl.Event) -> ControlEvent<()> {
|
||||
let source: Observable<Void> = Observable.create { [weak control = self.base] observer in
|
||||
MainScheduler.ensureRunningOnMainThread()
|
||||
|
||||
guard let control = control else {
|
||||
observer.on(.completed)
|
||||
return Disposables.create()
|
||||
}
|
||||
|
||||
let controlTarget = ControlTarget(control: control, controlEvents: controlEvents) { _ in
|
||||
observer.on(.next(()))
|
||||
}
|
||||
|
||||
return Disposables.create(with: controlTarget.dispose)
|
||||
}
|
||||
.take(until: deallocated)
|
||||
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Creates a `ControlProperty` that is triggered by target/action pattern value updates.
|
||||
///
|
||||
/// - parameter controlEvents: Events that trigger value update sequence elements.
|
||||
/// - parameter getter: Property value getter.
|
||||
/// - parameter setter: Property value setter.
|
||||
public func controlProperty<T>(
|
||||
editingEvents: UIControl.Event,
|
||||
getter: @escaping (Base) -> T,
|
||||
setter: @escaping (Base, T) -> Void
|
||||
) -> ControlProperty<T> {
|
||||
let source: Observable<T> = Observable.create { [weak weakControl = base] observer in
|
||||
guard let control = weakControl else {
|
||||
observer.on(.completed)
|
||||
return Disposables.create()
|
||||
}
|
||||
|
||||
observer.on(.next(getter(control)))
|
||||
|
||||
let controlTarget = ControlTarget(control: control, controlEvents: editingEvents) { _ in
|
||||
if let control = weakControl {
|
||||
observer.on(.next(getter(control)))
|
||||
}
|
||||
}
|
||||
|
||||
return Disposables.create(with: controlTarget.dispose)
|
||||
}
|
||||
.take(until: deallocated)
|
||||
|
||||
let bindingObserver = Binder(base, binding: setter)
|
||||
|
||||
return ControlProperty<T>(values: source, valueSink: bindingObserver)
|
||||
}
|
||||
|
||||
/// This is a separate method to better communicate to public consumers that
|
||||
/// an `editingEvent` needs to fire for control property to be updated.
|
||||
internal func controlPropertyWithDefaultEvents<T>(
|
||||
editingEvents: UIControl.Event = [.allEditingEvents, .valueChanged],
|
||||
getter: @escaping (Base) -> T,
|
||||
setter: @escaping (Base, T) -> Void
|
||||
) -> ControlProperty<T> {
|
||||
return controlProperty(
|
||||
editingEvents: editingEvents,
|
||||
getter: getter,
|
||||
setter: setter
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
43
Pods/RxCocoa/RxCocoa/iOS/UIDatePicker+Rx.swift
generated
Normal file
43
Pods/RxCocoa/RxCocoa/iOS/UIDatePicker+Rx.swift
generated
Normal file
@@ -0,0 +1,43 @@
|
||||
//
|
||||
// UIDatePicker+Rx.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Daniel Tartaglia on 5/31/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS)
|
||||
|
||||
import RxSwift
|
||||
import UIKit
|
||||
|
||||
extension Reactive where Base: UIDatePicker {
|
||||
/// Reactive wrapper for `date` property.
|
||||
public var date: ControlProperty<Date> {
|
||||
value
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `date` property.
|
||||
public var value: ControlProperty<Date> {
|
||||
return base.rx.controlPropertyWithDefaultEvents(
|
||||
getter: { datePicker in
|
||||
datePicker.date
|
||||
}, setter: { datePicker, value in
|
||||
datePicker.date = value
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `countDownDuration` property.
|
||||
public var countDownDuration: ControlProperty<TimeInterval> {
|
||||
return base.rx.controlPropertyWithDefaultEvents(
|
||||
getter: { datePicker in
|
||||
datePicker.countDownDuration
|
||||
}, setter: { datePicker, value in
|
||||
datePicker.countDownDuration = value
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
75
Pods/RxCocoa/RxCocoa/iOS/UIGestureRecognizer+Rx.swift
generated
Normal file
75
Pods/RxCocoa/RxCocoa/iOS/UIGestureRecognizer+Rx.swift
generated
Normal file
@@ -0,0 +1,75 @@
|
||||
//
|
||||
// UIGestureRecognizer+Rx.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Carlos García on 10/6/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
|
||||
import UIKit
|
||||
import RxSwift
|
||||
|
||||
// This should be only used from `MainScheduler`
|
||||
final class GestureTarget<Recognizer: UIGestureRecognizer>: RxTarget {
|
||||
typealias Callback = (Recognizer) -> Void
|
||||
|
||||
let selector = #selector(ControlTarget.eventHandler(_:))
|
||||
|
||||
weak var gestureRecognizer: Recognizer?
|
||||
var callback: Callback?
|
||||
|
||||
init(_ gestureRecognizer: Recognizer, callback: @escaping Callback) {
|
||||
self.gestureRecognizer = gestureRecognizer
|
||||
self.callback = callback
|
||||
|
||||
super.init()
|
||||
|
||||
gestureRecognizer.addTarget(self, action: selector)
|
||||
|
||||
let method = self.method(for: selector)
|
||||
if method == nil {
|
||||
fatalError("Can't find method")
|
||||
}
|
||||
}
|
||||
|
||||
@objc func eventHandler(_ sender: UIGestureRecognizer) {
|
||||
if let callback = self.callback, let gestureRecognizer = self.gestureRecognizer {
|
||||
callback(gestureRecognizer)
|
||||
}
|
||||
}
|
||||
|
||||
override func dispose() {
|
||||
super.dispose()
|
||||
|
||||
self.gestureRecognizer?.removeTarget(self, action: self.selector)
|
||||
self.callback = nil
|
||||
}
|
||||
}
|
||||
|
||||
extension Reactive where Base: UIGestureRecognizer {
|
||||
|
||||
/// Reactive wrapper for gesture recognizer events.
|
||||
public var event: ControlEvent<Base> {
|
||||
let source: Observable<Base> = Observable.create { [weak control = self.base] observer in
|
||||
MainScheduler.ensureRunningOnMainThread()
|
||||
|
||||
guard let control = control else {
|
||||
observer.on(.completed)
|
||||
return Disposables.create()
|
||||
}
|
||||
|
||||
let observer = GestureTarget(control) { control in
|
||||
observer.on(.next(control))
|
||||
}
|
||||
|
||||
return observer
|
||||
}.take(until: deallocated)
|
||||
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
49
Pods/RxCocoa/RxCocoa/iOS/UINavigationController+Rx.swift
generated
Normal file
49
Pods/RxCocoa/RxCocoa/iOS/UINavigationController+Rx.swift
generated
Normal file
@@ -0,0 +1,49 @@
|
||||
//
|
||||
// UINavigationController+Rx.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Diogo on 13/04/17.
|
||||
// Copyright © 2017 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
|
||||
import RxSwift
|
||||
import UIKit
|
||||
|
||||
extension Reactive where Base: UINavigationController {
|
||||
public typealias ShowEvent = (viewController: UIViewController, animated: Bool)
|
||||
|
||||
/// Reactive wrapper for `delegate`.
|
||||
///
|
||||
/// For more information take a look at `DelegateProxyType` protocol documentation.
|
||||
public var delegate: DelegateProxy<UINavigationController, UINavigationControllerDelegate> {
|
||||
RxNavigationControllerDelegateProxy.proxy(for: base)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for delegate method `navigationController(:willShow:animated:)`.
|
||||
public var willShow: ControlEvent<ShowEvent> {
|
||||
let source: Observable<ShowEvent> = delegate
|
||||
.methodInvoked(#selector(UINavigationControllerDelegate.navigationController(_:willShow:animated:)))
|
||||
.map { arg in
|
||||
let viewController = try castOrThrow(UIViewController.self, arg[1])
|
||||
let animated = try castOrThrow(Bool.self, arg[2])
|
||||
return (viewController, animated)
|
||||
}
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for delegate method `navigationController(:didShow:animated:)`.
|
||||
public var didShow: ControlEvent<ShowEvent> {
|
||||
let source: Observable<ShowEvent> = delegate
|
||||
.methodInvoked(#selector(UINavigationControllerDelegate.navigationController(_:didShow:animated:)))
|
||||
.map { arg in
|
||||
let viewController = try castOrThrow(UIViewController.self, arg[1])
|
||||
let animated = try castOrThrow(Bool.self, arg[2])
|
||||
return (viewController, animated)
|
||||
}
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
224
Pods/RxCocoa/RxCocoa/iOS/UIPickerView+Rx.swift
generated
Normal file
224
Pods/RxCocoa/RxCocoa/iOS/UIPickerView+Rx.swift
generated
Normal file
@@ -0,0 +1,224 @@
|
||||
//
|
||||
// UIPickerView+Rx.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Segii Shulga on 5/12/16.
|
||||
// Copyright © 2016 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS)
|
||||
|
||||
import RxSwift
|
||||
import UIKit
|
||||
|
||||
extension Reactive where Base: UIPickerView {
|
||||
|
||||
/// Reactive wrapper for `delegate`.
|
||||
/// For more information take a look at `DelegateProxyType` protocol documentation.
|
||||
public var delegate: DelegateProxy<UIPickerView, UIPickerViewDelegate> {
|
||||
return RxPickerViewDelegateProxy.proxy(for: base)
|
||||
}
|
||||
|
||||
/// Installs delegate as forwarding delegate on `delegate`.
|
||||
/// Delegate won't be retained.
|
||||
///
|
||||
/// It enables using normal delegate mechanism with reactive delegate mechanism.
|
||||
///
|
||||
/// - parameter delegate: Delegate object.
|
||||
/// - returns: Disposable object that can be used to unbind the delegate.
|
||||
public func setDelegate(_ delegate: UIPickerViewDelegate)
|
||||
-> Disposable {
|
||||
return RxPickerViewDelegateProxy.installForwardDelegate(delegate, retainDelegate: false, onProxyForObject: self.base)
|
||||
}
|
||||
|
||||
/**
|
||||
Reactive wrapper for `dataSource`.
|
||||
|
||||
For more information take a look at `DelegateProxyType` protocol documentation.
|
||||
*/
|
||||
public var dataSource: DelegateProxy<UIPickerView, UIPickerViewDataSource> {
|
||||
return RxPickerViewDataSourceProxy.proxy(for: base)
|
||||
}
|
||||
|
||||
/**
|
||||
Reactive wrapper for `delegate` message `pickerView:didSelectRow:inComponent:`.
|
||||
*/
|
||||
public var itemSelected: ControlEvent<(row: Int, component: Int)> {
|
||||
let source = delegate
|
||||
.methodInvoked(#selector(UIPickerViewDelegate.pickerView(_:didSelectRow:inComponent:)))
|
||||
.map {
|
||||
return (row: try castOrThrow(Int.self, $0[1]), component: try castOrThrow(Int.self, $0[2]))
|
||||
}
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/**
|
||||
Reactive wrapper for `delegate` message `pickerView:didSelectRow:inComponent:`.
|
||||
|
||||
It can be only used when one of the `rx.itemTitles, rx.itemAttributedTitles, items(_ source: O)` methods is used to bind observable sequence,
|
||||
or any other data source conforming to a `ViewDataSourceType` protocol.
|
||||
|
||||
```
|
||||
pickerView.rx.modelSelected(MyModel.self)
|
||||
.map { ...
|
||||
```
|
||||
- parameter modelType: Type of a Model which bound to the dataSource
|
||||
*/
|
||||
public func modelSelected<T>(_ modelType: T.Type) -> ControlEvent<[T]> {
|
||||
let source = itemSelected.flatMap { [weak view = self.base as UIPickerView] _, component -> Observable<[T]> in
|
||||
guard let view = view else {
|
||||
return Observable.empty()
|
||||
}
|
||||
|
||||
let model: [T] = try (0 ..< view.numberOfComponents).map { component in
|
||||
let row = view.selectedRow(inComponent: component)
|
||||
return try view.rx.model(at: IndexPath(row: row, section: component))
|
||||
}
|
||||
|
||||
return Observable.just(model)
|
||||
}
|
||||
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/**
|
||||
Binds sequences of elements to picker view rows.
|
||||
|
||||
- parameter source: Observable sequence of items.
|
||||
- parameter titleForRow: Transform between sequence elements and row titles.
|
||||
- returns: Disposable object that can be used to unbind.
|
||||
|
||||
Example:
|
||||
|
||||
let items = Observable.just([
|
||||
"First Item",
|
||||
"Second Item",
|
||||
"Third Item"
|
||||
])
|
||||
|
||||
items
|
||||
.bind(to: pickerView.rx.itemTitles) { (row, element) in
|
||||
return element.title
|
||||
}
|
||||
.disposed(by: disposeBag)
|
||||
|
||||
*/
|
||||
|
||||
public func itemTitles<Sequence: Swift.Sequence, Source: ObservableType>
|
||||
(_ source: Source)
|
||||
-> (_ titleForRow: @escaping (Int, Sequence.Element) -> String?)
|
||||
-> Disposable where Source.Element == Sequence {
|
||||
return { titleForRow in
|
||||
let adapter = RxStringPickerViewAdapter<Sequence>(titleForRow: titleForRow)
|
||||
return self.items(adapter: adapter)(source)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Binds sequences of elements to picker view rows.
|
||||
|
||||
- parameter source: Observable sequence of items.
|
||||
- parameter attributedTitleForRow: Transform between sequence elements and row attributed titles.
|
||||
- returns: Disposable object that can be used to unbind.
|
||||
|
||||
Example:
|
||||
|
||||
let items = Observable.just([
|
||||
"First Item",
|
||||
"Second Item",
|
||||
"Third Item"
|
||||
])
|
||||
|
||||
items
|
||||
.bind(to: pickerView.rx.itemAttributedTitles) { (row, element) in
|
||||
return NSAttributedString(string: element.title)
|
||||
}
|
||||
.disposed(by: disposeBag)
|
||||
|
||||
*/
|
||||
|
||||
public func itemAttributedTitles<Sequence: Swift.Sequence, Source: ObservableType>
|
||||
(_ source: Source)
|
||||
-> (_ attributedTitleForRow: @escaping (Int, Sequence.Element) -> NSAttributedString?)
|
||||
-> Disposable where Source.Element == Sequence {
|
||||
return { attributedTitleForRow in
|
||||
let adapter = RxAttributedStringPickerViewAdapter<Sequence>(attributedTitleForRow: attributedTitleForRow)
|
||||
return self.items(adapter: adapter)(source)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Binds sequences of elements to picker view rows.
|
||||
|
||||
- parameter source: Observable sequence of items.
|
||||
- parameter viewForRow: Transform between sequence elements and row views.
|
||||
- returns: Disposable object that can be used to unbind.
|
||||
|
||||
Example:
|
||||
|
||||
let items = Observable.just([
|
||||
"First Item",
|
||||
"Second Item",
|
||||
"Third Item"
|
||||
])
|
||||
|
||||
items
|
||||
.bind(to: pickerView.rx.items) { (row, element, view) in
|
||||
guard let myView = view as? MyView else {
|
||||
let view = MyView()
|
||||
view.configure(with: element)
|
||||
return view
|
||||
}
|
||||
myView.configure(with: element)
|
||||
return myView
|
||||
}
|
||||
.disposed(by: disposeBag)
|
||||
|
||||
*/
|
||||
|
||||
public func items<Sequence: Swift.Sequence, Source: ObservableType>
|
||||
(_ source: Source)
|
||||
-> (_ viewForRow: @escaping (Int, Sequence.Element, UIView?) -> UIView)
|
||||
-> Disposable where Source.Element == Sequence {
|
||||
return { viewForRow in
|
||||
let adapter = RxPickerViewAdapter<Sequence>(viewForRow: viewForRow)
|
||||
return self.items(adapter: adapter)(source)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Binds sequences of elements to picker view rows using a custom reactive adapter used to perform the transformation.
|
||||
This method will retain the adapter for as long as the subscription isn't disposed (result `Disposable`
|
||||
being disposed).
|
||||
In case `source` observable sequence terminates successfully, the adapter will present latest element
|
||||
until the subscription isn't disposed.
|
||||
|
||||
- parameter adapter: Adapter used to transform elements to picker components.
|
||||
- parameter source: Observable sequence of items.
|
||||
- returns: Disposable object that can be used to unbind.
|
||||
*/
|
||||
public func items<Source: ObservableType,
|
||||
Adapter: RxPickerViewDataSourceType & UIPickerViewDataSource & UIPickerViewDelegate>(adapter: Adapter)
|
||||
-> (_ source: Source)
|
||||
-> Disposable where Source.Element == Adapter.Element {
|
||||
return { source in
|
||||
let delegateSubscription = self.setDelegate(adapter)
|
||||
let dataSourceSubscription = source.subscribeProxyDataSource(ofObject: self.base, dataSource: adapter, retainDataSource: true, binding: { [weak pickerView = self.base] (_: RxPickerViewDataSourceProxy, event) in
|
||||
guard let pickerView = pickerView else { return }
|
||||
adapter.pickerView(pickerView, observedEvent: event)
|
||||
})
|
||||
return Disposables.create(delegateSubscription, dataSourceSubscription)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Synchronous helper method for retrieving a model at indexPath through a reactive data source.
|
||||
*/
|
||||
public func model<T>(at indexPath: IndexPath) throws -> T {
|
||||
let dataSource: SectionedViewDataSourceType = castOrFatalError(self.dataSource.forwardToDelegate(), message: "This method only works in case one of the `rx.itemTitles, rx.itemAttributedTitles, items(_ source: O)` methods was used.")
|
||||
|
||||
return castOrFatalError(try dataSource.model(at: indexPath))
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
28
Pods/RxCocoa/RxCocoa/iOS/UIRefreshControl+Rx.swift
generated
Normal file
28
Pods/RxCocoa/RxCocoa/iOS/UIRefreshControl+Rx.swift
generated
Normal file
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// UIRefreshControl+Rx.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Yosuke Ishikawa on 1/31/16.
|
||||
// Copyright © 2016 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS)
|
||||
|
||||
import UIKit
|
||||
import RxSwift
|
||||
|
||||
extension Reactive where Base: UIRefreshControl {
|
||||
/// Bindable sink for `beginRefreshing()`, `endRefreshing()` methods.
|
||||
public var isRefreshing: Binder<Bool> {
|
||||
return Binder(self.base) { refreshControl, refresh in
|
||||
if refresh {
|
||||
refreshControl.beginRefreshing()
|
||||
} else {
|
||||
refreshControl.endRefreshing()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
131
Pods/RxCocoa/RxCocoa/iOS/UIScrollView+Rx.swift
generated
Normal file
131
Pods/RxCocoa/RxCocoa/iOS/UIScrollView+Rx.swift
generated
Normal file
@@ -0,0 +1,131 @@
|
||||
//
|
||||
// UIScrollView+Rx.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 4/3/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
|
||||
import RxSwift
|
||||
import UIKit
|
||||
|
||||
extension Reactive where Base: UIScrollView {
|
||||
public typealias EndZoomEvent = (view: UIView?, scale: CGFloat)
|
||||
public typealias WillEndDraggingEvent = (velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>)
|
||||
|
||||
/// Reactive wrapper for `delegate`.
|
||||
///
|
||||
/// For more information take a look at `DelegateProxyType` protocol documentation.
|
||||
public var delegate: DelegateProxy<UIScrollView, UIScrollViewDelegate> {
|
||||
return RxScrollViewDelegateProxy.proxy(for: base)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `contentOffset`.
|
||||
public var contentOffset: ControlProperty<CGPoint> {
|
||||
let proxy = RxScrollViewDelegateProxy.proxy(for: base)
|
||||
|
||||
let bindingObserver = Binder(self.base) { scrollView, contentOffset in
|
||||
scrollView.contentOffset = contentOffset
|
||||
}
|
||||
|
||||
return ControlProperty(values: proxy.contentOffsetBehaviorSubject, valueSink: bindingObserver)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for delegate method `scrollViewDidScroll`
|
||||
public var didScroll: ControlEvent<Void> {
|
||||
let source = RxScrollViewDelegateProxy.proxy(for: base).contentOffsetPublishSubject
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for delegate method `scrollViewWillBeginDecelerating`
|
||||
public var willBeginDecelerating: ControlEvent<Void> {
|
||||
let source = delegate.methodInvoked(#selector(UIScrollViewDelegate.scrollViewWillBeginDecelerating(_:))).map { _ in }
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for delegate method `scrollViewDidEndDecelerating`
|
||||
public var didEndDecelerating: ControlEvent<Void> {
|
||||
let source = delegate.methodInvoked(#selector(UIScrollViewDelegate.scrollViewDidEndDecelerating(_:))).map { _ in }
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for delegate method `scrollViewWillBeginDragging`
|
||||
public var willBeginDragging: ControlEvent<Void> {
|
||||
let source = delegate.methodInvoked(#selector(UIScrollViewDelegate.scrollViewWillBeginDragging(_:))).map { _ in }
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for delegate method `scrollViewWillEndDragging(_:withVelocity:targetContentOffset:)`
|
||||
public var willEndDragging: ControlEvent<WillEndDraggingEvent> {
|
||||
let source = delegate.methodInvoked(#selector(UIScrollViewDelegate.scrollViewWillEndDragging(_:withVelocity:targetContentOffset:)))
|
||||
.map { value -> WillEndDraggingEvent in
|
||||
let velocity = try castOrThrow(CGPoint.self, value[1])
|
||||
let targetContentOffsetValue = try castOrThrow(NSValue.self, value[2])
|
||||
|
||||
guard let rawPointer = targetContentOffsetValue.pointerValue else { throw RxCocoaError.unknown }
|
||||
let typedPointer = rawPointer.bindMemory(to: CGPoint.self, capacity: MemoryLayout<CGPoint>.size)
|
||||
|
||||
return (velocity, typedPointer)
|
||||
}
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for delegate method `scrollViewDidEndDragging(_:willDecelerate:)`
|
||||
public var didEndDragging: ControlEvent<Bool> {
|
||||
let source = delegate.methodInvoked(#selector(UIScrollViewDelegate.scrollViewDidEndDragging(_:willDecelerate:))).map { value -> Bool in
|
||||
return try castOrThrow(Bool.self, value[1])
|
||||
}
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for delegate method `scrollViewDidZoom`
|
||||
public var didZoom: ControlEvent<Void> {
|
||||
let source = delegate.methodInvoked(#selector(UIScrollViewDelegate.scrollViewDidZoom)).map { _ in }
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
|
||||
/// Reactive wrapper for delegate method `scrollViewDidScrollToTop`
|
||||
public var didScrollToTop: ControlEvent<Void> {
|
||||
let source = delegate.methodInvoked(#selector(UIScrollViewDelegate.scrollViewDidScrollToTop(_:))).map { _ in }
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for delegate method `scrollViewDidEndScrollingAnimation`
|
||||
public var didEndScrollingAnimation: ControlEvent<Void> {
|
||||
let source = delegate.methodInvoked(#selector(UIScrollViewDelegate.scrollViewDidEndScrollingAnimation(_:))).map { _ in }
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for delegate method `scrollViewWillBeginZooming(_:with:)`
|
||||
public var willBeginZooming: ControlEvent<UIView?> {
|
||||
let source = delegate.methodInvoked(#selector(UIScrollViewDelegate.scrollViewWillBeginZooming(_:with:))).map { value -> UIView? in
|
||||
return try castOptionalOrThrow(UIView.self, value[1] as AnyObject)
|
||||
}
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for delegate method `scrollViewDidEndZooming(_:with:atScale:)`
|
||||
public var didEndZooming: ControlEvent<EndZoomEvent> {
|
||||
let source = delegate.methodInvoked(#selector(UIScrollViewDelegate.scrollViewDidEndZooming(_:with:atScale:))).map { value -> EndZoomEvent in
|
||||
return (try castOptionalOrThrow(UIView.self, value[1] as AnyObject), try castOrThrow(CGFloat.self, value[2]))
|
||||
}
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Installs delegate as forwarding delegate on `delegate`.
|
||||
/// Delegate won't be retained.
|
||||
///
|
||||
/// It enables using normal delegate mechanism with reactive delegate mechanism.
|
||||
///
|
||||
/// - parameter delegate: Delegate object.
|
||||
/// - returns: Disposable object that can be used to unbind the delegate.
|
||||
public func setDelegate(_ delegate: UIScrollViewDelegate)
|
||||
-> Disposable {
|
||||
return RxScrollViewDelegateProxy.installForwardDelegate(delegate, retainDelegate: false, onProxyForObject: self.base)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
136
Pods/RxCocoa/RxCocoa/iOS/UISearchBar+Rx.swift
generated
Normal file
136
Pods/RxCocoa/RxCocoa/iOS/UISearchBar+Rx.swift
generated
Normal file
@@ -0,0 +1,136 @@
|
||||
//
|
||||
// UISearchBar+Rx.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Krunoslav Zaher on 3/28/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
|
||||
import RxSwift
|
||||
import UIKit
|
||||
|
||||
extension Reactive where Base: UISearchBar {
|
||||
|
||||
/// Reactive wrapper for `delegate`.
|
||||
///
|
||||
/// For more information take a look at `DelegateProxyType` protocol documentation.
|
||||
public var delegate: DelegateProxy<UISearchBar, UISearchBarDelegate> {
|
||||
RxSearchBarDelegateProxy.proxy(for: base)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `text` property.
|
||||
public var text: ControlProperty<String?> {
|
||||
value
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `text` property.
|
||||
public var value: ControlProperty<String?> {
|
||||
let source: Observable<String?> = Observable.deferred { [weak searchBar = self.base as UISearchBar] () -> Observable<String?> in
|
||||
let text = searchBar?.text
|
||||
|
||||
let textDidChange = (searchBar?.rx.delegate.methodInvoked(#selector(UISearchBarDelegate.searchBar(_:textDidChange:))) ?? Observable.empty())
|
||||
let didEndEditing = (searchBar?.rx.delegate.methodInvoked(#selector(UISearchBarDelegate.searchBarTextDidEndEditing(_:))) ?? Observable.empty())
|
||||
|
||||
return Observable.merge(textDidChange, didEndEditing)
|
||||
.map { _ in searchBar?.text ?? "" }
|
||||
.startWith(text)
|
||||
}
|
||||
|
||||
let bindingObserver = Binder(self.base) { (searchBar, text: String?) in
|
||||
searchBar.text = text
|
||||
}
|
||||
|
||||
return ControlProperty(values: source, valueSink: bindingObserver)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `selectedScopeButtonIndex` property.
|
||||
public var selectedScopeButtonIndex: ControlProperty<Int> {
|
||||
let source: Observable<Int> = Observable.deferred { [weak source = self.base as UISearchBar] () -> Observable<Int> in
|
||||
let index = source?.selectedScopeButtonIndex ?? 0
|
||||
|
||||
return (source?.rx.delegate.methodInvoked(#selector(UISearchBarDelegate.searchBar(_:selectedScopeButtonIndexDidChange:))) ?? Observable.empty())
|
||||
.map { a in
|
||||
return try castOrThrow(Int.self, a[1])
|
||||
}
|
||||
.startWith(index)
|
||||
}
|
||||
|
||||
let bindingObserver = Binder(self.base) { (searchBar, index: Int) in
|
||||
searchBar.selectedScopeButtonIndex = index
|
||||
}
|
||||
|
||||
return ControlProperty(values: source, valueSink: bindingObserver)
|
||||
}
|
||||
|
||||
#if os(iOS)
|
||||
/// Reactive wrapper for delegate method `searchBarCancelButtonClicked`.
|
||||
public var cancelButtonClicked: ControlEvent<Void> {
|
||||
let source: Observable<Void> = self.delegate.methodInvoked(#selector(UISearchBarDelegate.searchBarCancelButtonClicked(_:)))
|
||||
.map { _ in
|
||||
return ()
|
||||
}
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for delegate method `searchBarBookmarkButtonClicked`.
|
||||
public var bookmarkButtonClicked: ControlEvent<Void> {
|
||||
let source: Observable<Void> = self.delegate.methodInvoked(#selector(UISearchBarDelegate.searchBarBookmarkButtonClicked(_:)))
|
||||
.map { _ in
|
||||
return ()
|
||||
}
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for delegate method `searchBarResultsListButtonClicked`.
|
||||
public var resultsListButtonClicked: ControlEvent<Void> {
|
||||
let source: Observable<Void> = self.delegate.methodInvoked(#selector(UISearchBarDelegate.searchBarResultsListButtonClicked(_:)))
|
||||
.map { _ in
|
||||
return ()
|
||||
}
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
#endif
|
||||
|
||||
/// Reactive wrapper for delegate method `searchBarSearchButtonClicked`.
|
||||
public var searchButtonClicked: ControlEvent<Void> {
|
||||
let source: Observable<Void> = self.delegate.methodInvoked(#selector(UISearchBarDelegate.searchBarSearchButtonClicked(_:)))
|
||||
.map { _ in
|
||||
return ()
|
||||
}
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for delegate method `searchBarTextDidBeginEditing`.
|
||||
public var textDidBeginEditing: ControlEvent<Void> {
|
||||
let source: Observable<Void> = self.delegate.methodInvoked(#selector(UISearchBarDelegate.searchBarTextDidBeginEditing(_:)))
|
||||
.map { _ in
|
||||
return ()
|
||||
}
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for delegate method `searchBarTextDidEndEditing`.
|
||||
public var textDidEndEditing: ControlEvent<Void> {
|
||||
let source: Observable<Void> = self.delegate.methodInvoked(#selector(UISearchBarDelegate.searchBarTextDidEndEditing(_:)))
|
||||
.map { _ in
|
||||
return ()
|
||||
}
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Installs delegate as forwarding delegate on `delegate`.
|
||||
/// Delegate won't be retained.
|
||||
///
|
||||
/// It enables using normal delegate mechanism with reactive delegate mechanism.
|
||||
///
|
||||
/// - parameter delegate: Delegate object.
|
||||
/// - returns: Disposable object that can be used to unbind the delegate.
|
||||
public func setDelegate(_ delegate: UISearchBarDelegate)
|
||||
-> Disposable {
|
||||
RxSearchBarDelegateProxy.installForwardDelegate(delegate, retainDelegate: false, onProxyForObject: self.base)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
58
Pods/RxCocoa/RxCocoa/iOS/UISearchController+Rx.swift
generated
Normal file
58
Pods/RxCocoa/RxCocoa/iOS/UISearchController+Rx.swift
generated
Normal file
@@ -0,0 +1,58 @@
|
||||
//
|
||||
// UISearchController+Rx.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Segii Shulga on 3/17/16.
|
||||
// Copyright © 2016 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS)
|
||||
|
||||
import RxSwift
|
||||
import UIKit
|
||||
|
||||
extension Reactive where Base: UISearchController {
|
||||
/// Reactive wrapper for `delegate`.
|
||||
/// For more information take a look at `DelegateProxyType` protocol documentation.
|
||||
public var delegate: DelegateProxy<UISearchController, UISearchControllerDelegate> {
|
||||
return RxSearchControllerDelegateProxy.proxy(for: base)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `delegate` message.
|
||||
public var didDismiss: Observable<Void> {
|
||||
return delegate
|
||||
.methodInvoked( #selector(UISearchControllerDelegate.didDismissSearchController(_:)))
|
||||
.map { _ in }
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `delegate` message.
|
||||
public var didPresent: Observable<Void> {
|
||||
return delegate
|
||||
.methodInvoked(#selector(UISearchControllerDelegate.didPresentSearchController(_:)))
|
||||
.map { _ in }
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `delegate` message.
|
||||
public var present: Observable<Void> {
|
||||
return delegate
|
||||
.methodInvoked( #selector(UISearchControllerDelegate.presentSearchController(_:)))
|
||||
.map { _ in }
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `delegate` message.
|
||||
public var willDismiss: Observable<Void> {
|
||||
return delegate
|
||||
.methodInvoked(#selector(UISearchControllerDelegate.willDismissSearchController(_:)))
|
||||
.map { _ in }
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `delegate` message.
|
||||
public var willPresent: Observable<Void> {
|
||||
return delegate
|
||||
.methodInvoked( #selector(UISearchControllerDelegate.willPresentSearchController(_:)))
|
||||
.map { _ in }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
54
Pods/RxCocoa/RxCocoa/iOS/UISegmentedControl+Rx.swift
generated
Normal file
54
Pods/RxCocoa/RxCocoa/iOS/UISegmentedControl+Rx.swift
generated
Normal file
@@ -0,0 +1,54 @@
|
||||
//
|
||||
// UISegmentedControl+Rx.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Carlos García on 8/7/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
|
||||
import UIKit
|
||||
import RxSwift
|
||||
|
||||
extension Reactive where Base: UISegmentedControl {
|
||||
/// Reactive wrapper for `selectedSegmentIndex` property.
|
||||
public var selectedSegmentIndex: ControlProperty<Int> {
|
||||
value
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `selectedSegmentIndex` property.
|
||||
public var value: ControlProperty<Int> {
|
||||
return base.rx.controlPropertyWithDefaultEvents(
|
||||
getter: { segmentedControl in
|
||||
segmentedControl.selectedSegmentIndex
|
||||
}, setter: { segmentedControl, value in
|
||||
segmentedControl.selectedSegmentIndex = value
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `setEnabled(_:forSegmentAt:)`
|
||||
public func enabledForSegment(at index: Int) -> Binder<Bool> {
|
||||
return Binder(self.base) { segmentedControl, segmentEnabled -> Void in
|
||||
segmentedControl.setEnabled(segmentEnabled, forSegmentAt: index)
|
||||
}
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `setTitle(_:forSegmentAt:)`
|
||||
public func titleForSegment(at index: Int) -> Binder<String?> {
|
||||
return Binder(self.base) { segmentedControl, title -> Void in
|
||||
segmentedControl.setTitle(title, forSegmentAt: index)
|
||||
}
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `setImage(_:forSegmentAt:)`
|
||||
public func imageForSegment(at index: Int) -> Binder<UIImage?> {
|
||||
return Binder(self.base) { segmentedControl, image -> Void in
|
||||
segmentedControl.setImage(image, forSegmentAt: index)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
29
Pods/RxCocoa/RxCocoa/iOS/UISlider+Rx.swift
generated
Normal file
29
Pods/RxCocoa/RxCocoa/iOS/UISlider+Rx.swift
generated
Normal file
@@ -0,0 +1,29 @@
|
||||
//
|
||||
// UISlider+Rx.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Alexander van der Werff on 28/05/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS)
|
||||
|
||||
import RxSwift
|
||||
import UIKit
|
||||
|
||||
extension Reactive where Base: UISlider {
|
||||
|
||||
/// Reactive wrapper for `value` property.
|
||||
public var value: ControlProperty<Float> {
|
||||
return base.rx.controlPropertyWithDefaultEvents(
|
||||
getter: { slider in
|
||||
slider.value
|
||||
}, setter: { slider, value in
|
||||
slider.value = value
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
29
Pods/RxCocoa/RxCocoa/iOS/UIStepper+Rx.swift
generated
Normal file
29
Pods/RxCocoa/RxCocoa/iOS/UIStepper+Rx.swift
generated
Normal file
@@ -0,0 +1,29 @@
|
||||
//
|
||||
// UIStepper+Rx.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Yuta ToKoRo on 9/1/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS)
|
||||
|
||||
import UIKit
|
||||
import RxSwift
|
||||
|
||||
extension Reactive where Base: UIStepper {
|
||||
|
||||
/// Reactive wrapper for `value` property.
|
||||
public var value: ControlProperty<Double> {
|
||||
return base.rx.controlPropertyWithDefaultEvents(
|
||||
getter: { stepper in
|
||||
stepper.value
|
||||
}, setter: { stepper, value in
|
||||
stepper.value = value
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
38
Pods/RxCocoa/RxCocoa/iOS/UISwitch+Rx.swift
generated
Normal file
38
Pods/RxCocoa/RxCocoa/iOS/UISwitch+Rx.swift
generated
Normal file
@@ -0,0 +1,38 @@
|
||||
//
|
||||
// UISwitch+Rx.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Carlos García on 8/7/15.
|
||||
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS)
|
||||
|
||||
import UIKit
|
||||
import RxSwift
|
||||
|
||||
extension Reactive where Base: UISwitch {
|
||||
|
||||
/// Reactive wrapper for `isOn` property.
|
||||
public var isOn: ControlProperty<Bool> {
|
||||
value
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `isOn` property.
|
||||
///
|
||||
/// ⚠️ Versions prior to iOS 10.2 were leaking `UISwitch`'s, so on those versions
|
||||
/// underlying observable sequence won't complete when nothing holds a strong reference
|
||||
/// to `UISwitch`.
|
||||
public var value: ControlProperty<Bool> {
|
||||
return base.rx.controlPropertyWithDefaultEvents(
|
||||
getter: { uiSwitch in
|
||||
uiSwitch.isOn
|
||||
}, setter: { uiSwitch, value in
|
||||
uiSwitch.isOn = value
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user