├── Podfile ├── Podfile.lock ├── Pods ├── Manifest.lock ├── Pods.xcodeproj │ ├── project.pbxproj │ └── xcuserdata │ │ └── dan.xcuserdatad │ │ └── xcschemes │ │ ├── Pods-ReactiveRegistration.xcscheme │ │ ├── ReactiveCocoa.xcscheme │ │ ├── ReactiveSwift.xcscheme │ │ ├── Result.xcscheme │ │ └── xcschememanagement.plist ├── ReactiveCocoa │ ├── LICENSE.md │ ├── README.md │ └── ReactiveCocoa │ │ ├── AppKit │ │ ├── NSButton.swift │ │ ├── NSCollectionView.swift │ │ ├── NSControl.swift │ │ ├── NSPopUpButton.swift │ │ ├── NSTableView.swift │ │ ├── NSTextField.swift │ │ └── ReusableComponents.swift │ │ ├── CocoaAction.swift │ │ ├── CocoaTarget.swift │ │ ├── Deprecations+Removals.swift │ │ ├── DynamicProperty.swift │ │ ├── NSObject+Association.swift │ │ ├── NSObject+BindingTarget.swift │ │ ├── NSObject+Intercepting.swift │ │ ├── NSObject+KeyValueObserving.swift │ │ ├── NSObject+Lifetime.swift │ │ ├── NSObject+ObjCRuntime.swift │ │ ├── NSObject+ReactiveExtensionsProvider.swift │ │ ├── NSObject+Synchronizing.swift │ │ ├── ObjC+Constants.swift │ │ ├── ObjC+Messages.swift │ │ ├── ObjC+Runtime.swift │ │ ├── ObjC+RuntimeSubclassing.swift │ │ ├── ObjC+Selector.swift │ │ ├── ObjCRuntimeAliases.h │ │ ├── ObjCRuntimeAliases.m │ │ ├── ReactiveCocoa.h │ │ ├── Shared │ │ ├── MKMapView.swift │ │ └── NSLayoutConstraint.swift │ │ ├── UIKit │ │ ├── ReusableComponents.swift │ │ ├── UIActivityIndicatorView.swift │ │ ├── UIBarButtonItem.swift │ │ ├── UIBarItem.swift │ │ ├── UIButton.swift │ │ ├── UICollectionView.swift │ │ ├── UIControl.swift │ │ ├── UIGestureRecognizer.swift │ │ ├── UIImageView.swift │ │ ├── UILabel.swift │ │ ├── UIProgressView.swift │ │ ├── UIScrollView.swift │ │ ├── UISegmentedControl.swift │ │ ├── UITableView.swift │ │ ├── UITextField.swift │ │ ├── UITextView.swift │ │ ├── UIView.swift │ │ └── iOS │ │ │ ├── UIDatePicker.swift │ │ │ ├── UIKeyboard.swift │ │ │ ├── UIRefreshControl.swift │ │ │ ├── UISearchBar.swift │ │ │ ├── UISlider.swift │ │ │ ├── UIStepper.swift │ │ │ └── UISwitch.swift │ │ └── module.modulemap ├── ReactiveSwift │ ├── LICENSE.md │ ├── README.md │ └── Sources │ │ ├── Action.swift │ │ ├── Atomic.swift │ │ ├── Bag.swift │ │ ├── Deprecations+Removals.swift │ │ ├── Disposable.swift │ │ ├── Event.swift │ │ ├── EventLogger.swift │ │ ├── Flatten.swift │ │ ├── FoundationExtensions.swift │ │ ├── Lifetime.swift │ │ ├── Observer.swift │ │ ├── Optional.swift │ │ ├── Property.swift │ │ ├── Reactive.swift │ │ ├── ResultExtensions.swift │ │ ├── Scheduler.swift │ │ ├── Signal.swift │ │ ├── SignalProducer.swift │ │ ├── TupleExtensions.swift │ │ └── UnidirectionalBinding.swift ├── Result │ ├── LICENSE │ ├── README.md │ └── Result │ │ ├── Result.swift │ │ └── ResultProtocol.swift └── Target Support Files │ ├── Pods-ReactiveRegistration │ ├── Info.plist │ ├── Pods-ReactiveRegistration-acknowledgements.markdown │ ├── Pods-ReactiveRegistration-acknowledgements.plist │ ├── Pods-ReactiveRegistration-dummy.m │ ├── Pods-ReactiveRegistration-frameworks.sh │ ├── Pods-ReactiveRegistration-resources.sh │ ├── Pods-ReactiveRegistration-umbrella.h │ ├── Pods-ReactiveRegistration.debug.xcconfig │ ├── Pods-ReactiveRegistration.modulemap │ └── Pods-ReactiveRegistration.release.xcconfig │ ├── ReactiveCocoa │ ├── Info.plist │ ├── ReactiveCocoa-dummy.m │ ├── ReactiveCocoa-prefix.pch │ ├── ReactiveCocoa.modulemap │ └── ReactiveCocoa.xcconfig │ ├── ReactiveSwift │ ├── Info.plist │ ├── ReactiveSwift-dummy.m │ ├── ReactiveSwift-prefix.pch │ ├── ReactiveSwift-umbrella.h │ ├── ReactiveSwift.modulemap │ └── ReactiveSwift.xcconfig │ └── Result │ ├── Info.plist │ ├── Result-dummy.m │ ├── Result-prefix.pch │ ├── Result-umbrella.h │ ├── Result.modulemap │ └── Result.xcconfig ├── README.md ├── ReactiveRegistration.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── dan.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── dan.xcuserdatad │ └── xcschemes │ ├── ReactiveRegistration.xcscheme │ └── xcschememanagement.plist ├── ReactiveRegistration.xcworkspace ├── contents.xcworkspacedata └── xcuserdata │ └── dan.xcuserdatad │ ├── UserInterfaceState.xcuserstate │ └── xcdebugger │ └── Breakpoints_v2.xcbkptlist └── ReactiveRegistration ├── AppDelegate.swift ├── Assets.xcassets ├── AppIcon.appiconset │ └── Contents.json ├── Avatar.imageset │ ├── Avatar.png │ └── Contents.json └── Contents.json ├── Base.lproj ├── LaunchScreen.storyboard └── Main.storyboard ├── FakeAPIService.swift ├── Info.plist ├── ReactiveUtils ├── RACHelpers.swift └── UIKitExtensions.swift ├── RegistrationViewController.swift ├── RegistrationViewModel.swift ├── StringExtension.swift ├── SummaryViewController.swift └── SummaryViewModel.swift /Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, '8.0' 2 | xcodeproj 'ReactiveRegistration.xcodeproj' 3 | use_frameworks! 4 | inhibit_all_warnings! 5 | 6 | target 'ReactiveRegistration' do 7 | pod 'ReactiveCocoa', '~> 5.0.0' 8 | end 9 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - ReactiveCocoa (5.0.0): 3 | - ReactiveSwift (~> 1.0.0) 4 | - ReactiveSwift (1.0.0): 5 | - Result (~> 3.1) 6 | - Result (3.1.0) 7 | 8 | DEPENDENCIES: 9 | - ReactiveCocoa (~> 5.0.0) 10 | 11 | SPEC CHECKSUMS: 12 | ReactiveCocoa: 60ef0da915b4f70c34ebecc3f4fb8f96af0e53d6 13 | ReactiveSwift: f391724ee318a2cfd3e37dfb041cd49ecf4e7869 14 | Result: 4e3ed5995ed94d0cd6a09be9a431fce3f3624bbf 15 | 16 | PODFILE CHECKSUM: 756bd9790c791cc39eecf6f38e50baec1d5546db 17 | 18 | COCOAPODS: 1.1.1 19 | -------------------------------------------------------------------------------- /Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - ReactiveCocoa (5.0.0): 3 | - ReactiveSwift (~> 1.0.0) 4 | - ReactiveSwift (1.0.0): 5 | - Result (~> 3.1) 6 | - Result (3.1.0) 7 | 8 | DEPENDENCIES: 9 | - ReactiveCocoa (~> 5.0.0) 10 | 11 | SPEC CHECKSUMS: 12 | ReactiveCocoa: 60ef0da915b4f70c34ebecc3f4fb8f96af0e53d6 13 | ReactiveSwift: f391724ee318a2cfd3e37dfb041cd49ecf4e7869 14 | Result: 4e3ed5995ed94d0cd6a09be9a431fce3f3624bbf 15 | 16 | PODFILE CHECKSUM: 756bd9790c791cc39eecf6f38e50baec1d5546db 17 | 18 | COCOAPODS: 1.1.1 19 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/dan.xcuserdatad/xcschemes/Pods-ReactiveRegistration.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 66 | 67 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/dan.xcuserdatad/xcschemes/ReactiveCocoa.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 45 | 46 | 52 | 53 | 55 | 56 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/dan.xcuserdatad/xcschemes/ReactiveSwift.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 45 | 46 | 52 | 53 | 55 | 56 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/dan.xcuserdatad/xcschemes/Result.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 45 | 46 | 52 | 53 | 55 | 56 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/dan.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Pods-ReactiveRegistration.xcscheme 8 | 9 | isShown 10 | 11 | 12 | ReactiveCocoa.xcscheme 13 | 14 | isShown 15 | 16 | 17 | ReactiveSwift.xcscheme 18 | 19 | isShown 20 | 21 | 22 | Result.xcscheme 23 | 24 | isShown 25 | 26 | 27 | 28 | SuppressBuildableAutocreation 29 | 30 | 1A2C55CF4643361ABA8640685B553AB8 31 | 32 | primary 33 | 34 | 35 | 41B109ADA0AC041CA625B5E7F268293D 36 | 37 | primary 38 | 39 | 40 | 673DBC0293D4528BC961ABDB403C10CC 41 | 42 | primary 43 | 44 | 45 | C4E86928F2FF7CA53F4B2E87E13CAA33 46 | 47 | primary 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/LICENSE.md: -------------------------------------------------------------------------------- 1 | **Copyright (c) 2012 - 2016, GitHub, Inc.** 2 | **All rights reserved.** 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of 5 | this software and associated documentation files (the "Software"), to deal in 6 | the Software without restriction, including without limitation the rights to 7 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 8 | the Software, and to permit persons to whom the Software is furnished to do so, 9 | subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 16 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 17 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 18 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/README.md: -------------------------------------------------------------------------------- 1 |

2 | ReactiveCocoa

3 | Reactive extensions to Cocoa frameworks, built on top of ReactiveSwift.

4 | Join the ReactiveSwift Slack community. 5 |

6 |
7 | [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](#carthage) [![CocoaPods compatible](https://img.shields.io/cocoapods/v/ReactiveCocoa.svg)](#cocoapods) [![GitHub release](https://img.shields.io/github/release/ReactiveCocoa/ReactiveCocoa.svg)](https://github.com/ReactiveCocoa/ReactiveCocoa/releases) ![Swift 3.0.x](https://img.shields.io/badge/Swift-3.0.x-orange.svg) ![platforms](https://img.shields.io/badge/platforms-iOS%20%7C%20OS%20X%20%7C%20watchOS%20%7C%20tvOS%20-lightgrey.svg) 8 | 9 | ⚠️ [Looking for the Objective-C API?][] ⚠️ [Still using Swift 2.x?][] 10 | 11 | 🎉 [Migrating from RAC 4.x?][CHANGELOG] 12 | 13 | 🚄 [Release Roadmap](#release-roadmap) 14 | 15 | ## What is ReactiveSwift? 16 | __ReactiveSwift__ offers composable, declarative and flexible primitives that are built around the grand concept of ___streams of values over time___. These primitives can be used to uniformly represent common Cocoa and generic programming patterns that are fundamentally an act of observation. 17 | 18 | For more information about the core primitives, see [ReactiveSwift][]. 19 | 20 | ## What is ReactiveCocoa? 21 | 22 | __ReactiveCocoa__ wraps various aspects of Cocoa frameworks with the declarative [ReactiveSwift][] primitives. 23 | 24 | 1. **UI Bindings** 25 | 26 | UI components expose [`BindingTarget`][]s, which accept bindings from any 27 | kind of streams of values via the `<~` operator. 28 | 29 | ```swift 30 | // Bind the `name` property of `person` to the text value of an `UILabel`. 31 | nameLabel.reactive.text <~ person.name 32 | ``` 33 | 34 | _Note_: You'll need to import ReactiveSwift as well to make use of the `<~` operator. 35 | 36 | 1. **Controls and User Interactions** 37 | 38 | Interactive UI components expose [`Signal`][]s for control events 39 | and updates in the control value upon user interactions. 40 | 41 | A selected set of controls provide a convenience, expressive binding 42 | API for [`Action`][]s. 43 | 44 | 45 | ```swift 46 | // Update `allowsCookies` whenever the toggle is flipped. 47 | preferences.allowsCookies <~ toggle.reactive.isOnValues 48 | 49 | // Compute live character counts from the continuous stream of user initiated 50 | // changes in the text. 51 | textField.reactive.continuousTextValues.map { $0.characters.count } 52 | 53 | // Trigger `commit` whenever the button is pressed. 54 | button.reactive.pressed = CocoaAction(viewModel.commit) 55 | ``` 56 | 57 | 1. **Declarative Objective-C Dynamism** 58 | 59 | Create signals that are sourced by intercepting Objective-C objects, 60 | e.g. method call interception and object deinitialization. 61 | 62 | ```swift 63 | // Notify after every time `viewWillAppear(_:)` is called. 64 | let appearing = view.reactive.trigger(for: #selector(viewWillAppear(_:))) 65 | 66 | // Observe the lifetime of `object`. 67 | object.reactive.lifetime.ended.observeCompleted(doCleanup) 68 | ``` 69 | 70 | 1. **Expressive, Safe Key Path Observation** 71 | 72 | Establish key-value observations in the form of [`SignalProducer`][]s and 73 | `DynamicProperty`s, and enjoy the inherited composability. 74 | 75 | ```swift 76 | // A producer that sends the current value of `keyPath`, followed by 77 | // subsequent changes. 78 | // 79 | // Terminate the KVO observation if the lifetime of `self` ends. 80 | let producer = object.reactive.values(forKeyPath: #keyPath(key)) 81 | .take(during: self.reactive.lifetime) 82 | 83 | // A parameterized property that represents the supplied key path of the 84 | // wrapped object. It holds a weak reference to the wrapped object. 85 | let property = DynamicProperty(object: person, 86 | keyPath: #keyPath(person.name)) 87 | ``` 88 | 89 | But there are still more to be discovered and introduced. Read our in-code documentations and release notes to 90 | find out more. 91 | 92 | ## Getting started 93 | 94 | ReactiveCocoa supports macOS 10.9+, iOS 8.0+, watchOS 2.0+, and tvOS 9.0+. 95 | 96 | #### Carthage 97 | 98 | If you use [Carthage][] to manage your dependencies, simply add 99 | ReactiveCocoa to your `Cartfile`: 100 | 101 | ``` 102 | github "ReactiveCocoa/ReactiveCocoa" "5.0.0" 103 | ``` 104 | 105 | If you use Carthage to build your dependencies, make sure you have added `ReactiveCocoa.framework`, `ReactiveSwift.framework`, and `Result.framework` to the "_Linked Frameworks and Libraries_" section of your target, and have included them in your Carthage framework copying build phase. 106 | 107 | #### CocoaPods 108 | 109 | If you use [CocoaPods][] to manage your dependencies, simply add 110 | ReactiveCocoa to your `Podfile`: 111 | 112 | ``` 113 | pod 'ReactiveCocoa', '~> 5.0.0' 114 | ``` 115 | 116 | #### Git submodule 117 | 118 | 1. Add the ReactiveCocoa repository as a [submodule][] of your 119 | application’s repository. 120 | 1. Run `git submodule update --init --recursive` from within the ReactiveCocoa folder. 121 | 1. Drag and drop `ReactiveCocoa.xcodeproj`, 122 | `Carthage/Checkouts/ReactiveSwift/ReactiveSwift.xcodeproj`, and 123 | `Carthage/Checkouts/Result/Result.xcodeproj` into your application’s Xcode 124 | project or workspace. 125 | 1. On the “General” tab of your application target’s settings, add 126 | `ReactiveCocoa.framework`, `ReactiveSwift.framework`, and `Result.framework` 127 | to the “Embedded Binaries” section. 128 | 1. If your application target does not contain Swift code at all, you should also 129 | set the `EMBEDDED_CONTENT_CONTAINS_SWIFT` build setting to “Yes”. 130 | 131 | ## Have a question? 132 | If you need any help, please visit our [GitHub issues][] or [Stack Overflow][]. Feel free to file an issue if you do not manage to find any solution from the archives. 133 | 134 | ## Release Roadmap 135 | **Current Stable Release:**
[![GitHub release](https://img.shields.io/github/release/ReactiveCocoa/ReactiveCocoa.svg)](https://github.com/ReactiveCocoa/ReactiveCocoa/releases) 136 | 137 | #### ReactiveCocoa 6.0 138 | It targets Swift 3.1.x and ReactiveSwift 2.0. The estimated schedule is Spring 2017. 139 | 140 | Since ReactiveSwift 2.0 would contain breaking changes, the public API of ReactiveCocoa is considered breaking too. 141 | 142 | As resilience would be enforced in Swift 4.0, it is important for us to have a clean and steady API to start with. The expectation is to **have the API reviewing to be concluded in ReactiveCocoa 6.0**, before we move on to ReactiveSwift 3.0 and Swift 4.0. Any contribution to help realising this goal is welcomed. 143 | 144 | #### ReactiveCocoa 7.0 145 | It targets Swift 4.0.x and ReactiveSwift 3.0. The estimated schedule is late 2017. 146 | 147 | The release may contain breaking changes due to changes in ReactiveSwift 3.0. 148 | 149 | ReactiveCocoa 7.0 would focus on three main goals: 150 | 151 | 1. Swift 4.0 Resilience 152 | 1. Migration to ReactiveSwift 3.0 153 | 1. Support new features introduced to AppKit, UIKit and Swift. 154 | 155 | [ReactiveSwift]: https://github.com/ReactiveCocoa/ReactiveSwift 156 | [ReactiveObjC]: https://github.com/ReactiveCocoa/ReactiveObjC 157 | [GitHub issues]: https://github.com/ReactiveCocoa/ReactiveCocoa/issues?q=is%3Aissue+label%3Aquestion+ 158 | [Stack Overflow]: http://stackoverflow.com/questions/tagged/reactive-cocoa 159 | [CHANGELOG]: CHANGELOG.md 160 | [Carthage]: https://github.com/Carthage/Carthage 161 | [CocoaPods]: https://cocoapods.org/ 162 | [submodule]: https://git-scm.com/book/en/v2/Git-Tools-Submodules 163 | [Looking for the Objective-C API?]: https://github.com/ReactiveCocoa/ReactiveObjC 164 | [Still using Swift 2.x?]: https://github.com/ReactiveCocoa/ReactiveCocoa/tree/v4.0.0 165 | [`Signal`]: https://github.com/ReactiveCocoa/ReactiveSwift/blob/master/Documentation/FrameworkOverview.md#signals 166 | [`SignalProducer`]: https://github.com/ReactiveCocoa/ReactiveSwift/blob/master/Documentation/FrameworkOverview.md#signal-producers 167 | [`Action`]: https://github.com/ReactiveCocoa/ReactiveSwift/blob/master/Documentation/FrameworkOverview.md#actions 168 | [`BindingTarget`]: https://github.com/ReactiveCocoa/ReactiveSwift/blob/master/Documentation/FrameworkOverview.md#properties 169 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/AppKit/NSButton.swift: -------------------------------------------------------------------------------- 1 | import ReactiveSwift 2 | import enum Result.NoError 3 | import AppKit 4 | 5 | extension Reactive where Base: NSButton { 6 | 7 | internal var associatedAction: Atomic<(action: CocoaAction, disposable: CompositeDisposable)?> { 8 | return associatedValue { _ in Atomic(nil) } 9 | } 10 | 11 | public var pressed: CocoaAction? { 12 | get { 13 | return associatedAction.value?.action 14 | } 15 | 16 | nonmutating set { 17 | associatedAction 18 | .modify { action in 19 | action?.disposable.dispose() 20 | action = newValue.map { action in 21 | let disposable = CompositeDisposable() 22 | disposable += isEnabled <~ action.isEnabled 23 | disposable += trigger.observeValues { [unowned base = self.base] in 24 | action.execute(base) 25 | } 26 | return (action, disposable) 27 | } 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/AppKit/NSCollectionView.swift: -------------------------------------------------------------------------------- 1 | import AppKit 2 | import ReactiveSwift 3 | 4 | extension Reactive where Base: NSCollectionView { 5 | @available(macOS 10.11, *) 6 | public var reloadData: BindingTarget<()> { 7 | return makeBindingTarget { base, _ in base.reloadData() } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/AppKit/NSControl.swift: -------------------------------------------------------------------------------- 1 | import ReactiveSwift 2 | import enum Result.NoError 3 | import AppKit 4 | 5 | extension Reactive where Base: NSControl { 6 | /// Sets whether the control is enabled. 7 | public var isEnabled: BindingTarget { 8 | return makeBindingTarget { $0.isEnabled = $1 } 9 | } 10 | 11 | /// Sets the value of the control with an `NSAttributedString`. 12 | public var attributedStringValue: BindingTarget { 13 | return makeBindingTarget { $0.attributedStringValue = $1 } 14 | } 15 | 16 | /// A signal of values in `NSAttributedString`, emitted by the control. 17 | public var attributedStringValues: Signal { 18 | return trigger.map { [unowned base = self.base] in base.attributedStringValue } 19 | } 20 | 21 | /// Sets the value of the control with a `Bool`. 22 | public var boolValue: BindingTarget { 23 | return makeBindingTarget { $0.integerValue = $1 ? NSOnState : NSOffState } 24 | } 25 | 26 | /// A signal of values in `Bool`, emitted by the control. 27 | public var boolValues: Signal { 28 | return trigger.map { [unowned base = self.base] in 29 | return base.integerValue == NSOffState ? false : true 30 | } 31 | } 32 | 33 | /// Sets the value of the control with a `Double`. 34 | public var doubleValue: BindingTarget { 35 | return makeBindingTarget { $0.doubleValue = $1 } 36 | } 37 | 38 | /// A signal of values in `Double`, emitted by the control. 39 | public var doubleValues: Signal { 40 | return trigger.map { [unowned base = self.base] in base.doubleValue } 41 | } 42 | 43 | /// Sets the value of the control with a `Float`. 44 | public var floatValue: BindingTarget { 45 | return makeBindingTarget { $0.floatValue = $1 } 46 | } 47 | 48 | /// A signal of values in `Float`, emitted by the control. 49 | public var floatValues: Signal { 50 | return trigger.map { [unowned base = self.base] in base.floatValue } 51 | } 52 | 53 | /// Sets the value of the control with an `Int32`. 54 | public var intValue: BindingTarget { 55 | return makeBindingTarget { $0.intValue = $1 } 56 | } 57 | 58 | /// A signal of values in `Int32`, emitted by the control. 59 | public var intValues: Signal { 60 | return trigger.map { [unowned base = self.base] in base.intValue } 61 | } 62 | 63 | /// Sets the value of the control with an `Int`. 64 | public var integerValue: BindingTarget { 65 | return makeBindingTarget { $0.integerValue = $1 } 66 | } 67 | 68 | /// A signal of values in `Int`, emitted by the control. 69 | public var integerValues: Signal { 70 | return trigger.map { [unowned base = self.base] in base.integerValue } 71 | } 72 | 73 | /// Sets the value of the control. 74 | public var objectValue: BindingTarget { 75 | return makeBindingTarget { $0.objectValue = $1 } 76 | } 77 | 78 | /// A signal of values in `Any?`, emitted by the control. 79 | public var objectValues: Signal { 80 | return trigger.map { [unowned base = self.base] in base.objectValue } 81 | } 82 | 83 | /// Sets the value of the control with a `String`. 84 | public var stringValue: BindingTarget { 85 | return makeBindingTarget { $0.stringValue = $1 } 86 | } 87 | 88 | /// A signal of values in `String`, emitted by the control. 89 | public var stringValues: Signal { 90 | return trigger.map { [unowned base = self.base] in base.stringValue } 91 | } 92 | 93 | /// A trigger signal that sends a `next` event for every action messages 94 | /// received from the control, and completes when the control deinitializes. 95 | internal var trigger: Signal<(), NoError> { 96 | return associatedValue { base in 97 | let (signal, observer) = Signal<(), NoError>.pipe() 98 | 99 | let receiver = CocoaTarget(observer) 100 | base.target = receiver 101 | base.action = #selector(receiver.sendNext) 102 | 103 | lifetime.ended.observeCompleted { 104 | _ = receiver 105 | observer.sendCompleted() 106 | } 107 | 108 | return signal 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/AppKit/NSPopUpButton.swift: -------------------------------------------------------------------------------- 1 | import ReactiveSwift 2 | import AppKit 3 | import enum Result.NoError 4 | 5 | extension Reactive where Base: NSPopUpButton { 6 | 7 | /// A signal of selected indexes 8 | public var selectedIndexes: Signal { 9 | return self.integerValues 10 | .map { [unowned base = self.base] _ -> Int in 11 | return base.indexOfSelectedItem 12 | } 13 | } 14 | 15 | /// Sets the button with an index. 16 | public var selectedIndex: BindingTarget { 17 | return makeBindingTarget { 18 | $0.selectItem(at: $1 ?? -1) 19 | } 20 | } 21 | 22 | /// A signal of selected title 23 | public var selectedTitles: Signal { 24 | return self.objectValues 25 | .map { [unowned base = self.base] _ -> String? in 26 | return base.titleOfSelectedItem 27 | } 28 | .skipNil() 29 | } 30 | 31 | /// Sets the button with title. 32 | /// note: emitting nil to this target will set selectedTitle to empty string 33 | public var selectedTitle: BindingTarget { 34 | return makeBindingTarget { 35 | $0.selectItem(withTitle: $1 ?? "") 36 | } 37 | } 38 | 39 | public var selectedItems: Signal { 40 | return self.objectValues 41 | .map { [unowned base = self.base] _ -> NSMenuItem? in 42 | return base.selectedItem 43 | } 44 | .skipNil() 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/AppKit/NSTableView.swift: -------------------------------------------------------------------------------- 1 | import AppKit 2 | import ReactiveSwift 3 | 4 | extension Reactive where Base: NSTableView { 5 | public var reloadData: BindingTarget<()> { 6 | return makeBindingTarget { base, _ in base.reloadData() } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/AppKit/NSTextField.swift: -------------------------------------------------------------------------------- 1 | import ReactiveSwift 2 | import AppKit 3 | import enum Result.NoError 4 | 5 | extension Reactive where Base: NSTextField { 6 | private var notifications: Signal { 7 | return NotificationCenter.default 8 | .reactive 9 | .notifications(forName: .NSControlTextDidChange, object: base) 10 | .take(during: lifetime) 11 | } 12 | 13 | /// A signal of values in `String` from the text field upon any changes. 14 | public var continuousStringValues: Signal { 15 | return notifications 16 | .map { ($0.object as! NSTextField).stringValue } 17 | } 18 | 19 | /// A signal of values in `NSAttributedString` from the text field upon any 20 | /// changes. 21 | public var continuousAttributedStringValues: Signal { 22 | return notifications 23 | .map { ($0.object as! NSTextField).attributedStringValue } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/AppKit/ReusableComponents.swift: -------------------------------------------------------------------------------- 1 | import AppKit 2 | import ReactiveSwift 3 | import enum Result.NoError 4 | 5 | extension Reactive where Base: NSObject, Base: NSView { 6 | public var prepareForReuse: Signal<(), NoError> { 7 | return trigger(for: #selector(base.prepareForReuse)) 8 | } 9 | } 10 | 11 | extension Reactive where Base: NSObject, Base: NSCollectionViewElement { 12 | @available(macOS 10.11, *) 13 | public var prepareForReuse: Signal<(), NoError> { 14 | return trigger(for: #selector(base.prepareForReuse)) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/CocoaAction.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import ReactiveSwift 3 | import enum Result.NoError 4 | 5 | /// CocoaAction wraps an `Action` for use by a UI control (such as `NSControl` or 6 | /// `UIControl`). 7 | public final class CocoaAction: NSObject { 8 | /// The selector for message senders. 9 | public static var selector: Selector { 10 | return #selector(CocoaAction.execute(_:)) 11 | } 12 | 13 | /// Whether the action is enabled. 14 | /// 15 | /// This property will only change on the main thread. 16 | public let isEnabled: Property 17 | 18 | /// Whether the action is executing. 19 | /// 20 | /// This property will only change on the main thread. 21 | public let isExecuting: Property 22 | 23 | private let _execute: (Sender) -> Void 24 | 25 | /// Initialize a CocoaAction that invokes the given Action by mapping the 26 | /// sender to the input type of the Action. 27 | /// 28 | /// - parameters: 29 | /// - action: The Action. 30 | /// - inputTransform: A closure that maps Sender to the input type of the 31 | /// Action. 32 | public init(_ action: Action, _ inputTransform: @escaping (Sender) -> Input) { 33 | _execute = { sender in 34 | let producer = action.apply(inputTransform(sender)) 35 | producer.start() 36 | } 37 | 38 | isEnabled = Property(initial: action.isEnabled.value, 39 | then: action.isEnabled.producer.observe(on: UIScheduler())) 40 | isExecuting = Property(initial: action.isExecuting.value, 41 | then: action.isExecuting.producer.observe(on: UIScheduler())) 42 | 43 | super.init() 44 | } 45 | 46 | /// Initialize a CocoaAction that invokes the given Action. 47 | /// 48 | /// - parameters: 49 | /// - action: The Action. 50 | public convenience init(_ action: Action<(), Output, Error>) { 51 | self.init(action, { _ in }) 52 | } 53 | 54 | /// Initialize a CocoaAction that invokes the given Action with the given 55 | /// constant. 56 | /// 57 | /// - parameters: 58 | /// - action: The Action. 59 | /// - input: The constant value as the input to the action. 60 | public convenience init(_ action: Action, input: Input) { 61 | self.init(action, { _ in input }) 62 | } 63 | 64 | /// Attempt to execute the underlying action with the given input, subject 65 | /// to the behavior described by the initializer that was used. 66 | /// 67 | /// - parameters: 68 | /// - sender: The sender which initiates the attempt. 69 | @IBAction public func execute(_ sender: Any) { 70 | _execute(sender as! Sender) 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/CocoaTarget.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import ReactiveSwift 3 | import enum Result.NoError 4 | 5 | /// A target that accepts action messages. 6 | internal final class CocoaTarget: NSObject { 7 | private let observer: Observer 8 | private let transform: (Any?) -> Value 9 | 10 | internal init(_ observer: Observer, transform: @escaping (Any?) -> Value) { 11 | self.observer = observer 12 | self.transform = transform 13 | } 14 | 15 | @objc internal func sendNext(_ receiver: Any?) { 16 | observer.send(value: transform(receiver)) 17 | } 18 | } 19 | 20 | internal protocol CocoaTargetProtocol: class { 21 | associatedtype Value 22 | init(_ observer: Observer, transform: @escaping (Any?) -> Value) 23 | } 24 | 25 | extension CocoaTarget: CocoaTargetProtocol {} 26 | 27 | extension CocoaTargetProtocol where Value == Void { 28 | internal init(_ observer: Observer<(), NoError>) { 29 | self.init(observer, transform: { _ in }) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/Deprecations+Removals.swift: -------------------------------------------------------------------------------- 1 | import ReactiveSwift 2 | 3 | extension Action { 4 | @available(*, unavailable, message:"Use the `CocoaAction` initializers instead.") 5 | public var unsafeCocoaAction: CocoaAction { fatalError() } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/DynamicProperty.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import ReactiveSwift 3 | import enum Result.NoError 4 | 5 | /// Wraps a `dynamic` property, or one defined in Objective-C, using Key-Value 6 | /// Coding and Key-Value Observing. 7 | /// 8 | /// Use this class only as a last resort! `MutableProperty` is generally better 9 | /// unless KVC/KVO is required by the API you're using (for example, 10 | /// `NSOperation`). 11 | public final class DynamicProperty: MutablePropertyProtocol { 12 | private weak var object: NSObject? 13 | private let keyPath: String 14 | 15 | /// The current value of the property, as read and written using Key-Value 16 | /// Coding. 17 | public var value: Value? { 18 | get { 19 | return object?.value(forKeyPath: keyPath) as! Value 20 | } 21 | 22 | set(newValue) { 23 | object?.setValue(newValue, forKeyPath: keyPath) 24 | } 25 | } 26 | 27 | /// The lifetime of the property. 28 | public var lifetime: Lifetime { 29 | return object?.reactive.lifetime ?? .empty 30 | } 31 | 32 | /// A producer that will create a Key-Value Observer for the given object, 33 | /// send its initial value then all changes over time, and then complete 34 | /// when the observed object has deallocated. 35 | /// 36 | /// - important: This only works if the object given to init() is KVO-compliant. 37 | /// Most UI controls are not! 38 | public var producer: SignalProducer { 39 | return (object.map { $0.reactive.values(forKeyPath: keyPath) } ?? .empty) 40 | .map { $0 as! Value } 41 | } 42 | 43 | public private(set) lazy var signal: Signal = { 44 | var signal: Signal! 45 | self.producer.startWithSignal { innerSignal, _ in signal = innerSignal } 46 | return signal 47 | }() 48 | 49 | /// Initializes a property that will observe and set the given key path of 50 | /// the given object. The generic type `Value` can be any Swift type, and will 51 | /// be bridged to Objective-C via `Any`. 52 | /// 53 | /// - important: `object` must support weak references! 54 | /// 55 | /// - parameters: 56 | /// - object: An object to be observed. 57 | /// - keyPath: Key path to observe on the object. 58 | public init(object: NSObject, keyPath: String) { 59 | self.object = object 60 | self.keyPath = keyPath 61 | 62 | /// A DynamicProperty will stay alive as long as its object is alive. 63 | /// This is made possible by strong reference cycles. 64 | _ = object.reactive.lifetime.ended.observeCompleted { _ = self } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/NSObject+Association.swift: -------------------------------------------------------------------------------- 1 | import ReactiveSwift 2 | 3 | internal struct AssociationKey { 4 | fileprivate let address: UnsafeRawPointer 5 | fileprivate let `default`: Value! 6 | 7 | /// Create an ObjC association key. 8 | /// 9 | /// - warning: The key must be uniqued. 10 | /// 11 | /// - parameters: 12 | /// - default: The default value, or `nil` to trap on undefined value. It is 13 | /// ignored if `Value` is an optional. 14 | init(default: Value? = nil) { 15 | self.address = UnsafeRawPointer(UnsafeMutablePointer.allocate(capacity: 1)) 16 | self.default = `default` 17 | } 18 | 19 | /// Create an ObjC association key from a `StaticString`. 20 | /// 21 | /// - precondition: `key` has a pointer representation. 22 | /// 23 | /// - parameters: 24 | /// - default: The default value, or `nil` to trap on undefined value. It is 25 | /// ignored if `Value` is an optional. 26 | init(_ key: StaticString, default: Value? = nil) { 27 | assert(key.hasPointerRepresentation) 28 | self.address = UnsafeRawPointer(key.utf8Start) 29 | self.default = `default` 30 | } 31 | 32 | /// Create an ObjC association key from a `Selector`. 33 | /// 34 | /// - parameters: 35 | /// - default: The default value, or `nil` to trap on undefined value. It is 36 | /// ignored if `Value` is an optional. 37 | init(_ key: Selector, default: Value? = nil) { 38 | self.address = UnsafeRawPointer(key.utf8Start) 39 | self.default = `default` 40 | } 41 | } 42 | 43 | internal struct Associations { 44 | fileprivate let base: Base 45 | 46 | init(_ base: Base) { 47 | self.base = base 48 | } 49 | } 50 | 51 | extension Reactive where Base: NSObject { 52 | /// Retrieve the associated value for the specified key. If the value does not 53 | /// exist, `initial` would be called and the returned value would be 54 | /// associated subsequently. 55 | /// 56 | /// - parameters: 57 | /// - key: An optional key to differentiate different values. 58 | /// - initial: The action that supples an initial value. 59 | /// 60 | /// - returns: 61 | /// The associated value for the specified key. 62 | internal func associatedValue(forKey key: StaticString = #function, initial: (Base) -> T) -> T { 63 | let key = AssociationKey(key) 64 | 65 | if let value = base.associations.value(forKey: key) { 66 | return value 67 | } 68 | 69 | let value = initial(base) 70 | base.associations.setValue(value, forKey: key) 71 | 72 | return value 73 | } 74 | } 75 | 76 | extension NSObject { 77 | @nonobjc internal var associations: Associations { 78 | return Associations(self) 79 | } 80 | } 81 | 82 | extension Associations { 83 | /// Retrieve the associated value for the specified key. 84 | /// 85 | /// - parameters: 86 | /// - key: The key. 87 | /// 88 | /// - returns: The associated value, or the default value if no value has been 89 | /// associated with the key. 90 | internal func value(forKey key: AssociationKey) -> Value { 91 | return (objc_getAssociatedObject(base, key.address) as! Value?) ?? key.default 92 | } 93 | 94 | /// Retrieve the associated value for the specified key. 95 | /// 96 | /// - parameters: 97 | /// - key: The key. 98 | /// 99 | /// - returns: The associated value, or `nil` if no value is associated with 100 | /// the key. 101 | internal func value(forKey key: AssociationKey) -> Value? { 102 | return objc_getAssociatedObject(base, key.address) as! Value? 103 | } 104 | 105 | /// Set the associated value for the specified key. 106 | /// 107 | /// - parameters: 108 | /// - value: The value to be associated. 109 | /// - key: The key. 110 | internal func setValue(_ value: Value, forKey key: AssociationKey) { 111 | objc_setAssociatedObject(base, key.address, value, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) 112 | } 113 | 114 | /// Set the associated value for the specified key. 115 | /// 116 | /// - parameters: 117 | /// - value: The value to be associated. 118 | /// - key: The key. 119 | internal func setValue(_ value: Value?, forKey key: AssociationKey) { 120 | objc_setAssociatedObject(base, key.address, value, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) 121 | } 122 | } 123 | 124 | /// Set the associated value for the specified key. 125 | /// 126 | /// - parameters: 127 | /// - value: The value to be associated. 128 | /// - key: The key. 129 | /// - address: The address of the object. 130 | internal func unsafeSetAssociatedValue(_ value: Value?, forKey key: AssociationKey, forObjectAt address: UnsafeRawPointer) { 131 | _rac_objc_setAssociatedObject(address, key.address, value, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) 132 | } 133 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/NSObject+BindingTarget.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import ReactiveSwift 3 | 4 | extension Reactive where Base: NSObject { 5 | /// Creates a binding target which uses the lifetime of the object, and weakly 6 | /// references the object so that the supplied `action` is triggered only if 7 | /// the object has not deinitialized. 8 | /// 9 | /// - parameters: 10 | /// - scheduler: An optional scheduler that the binding target uses. If it 11 | /// is not specified, a UI scheduler would be used. 12 | /// - action: The action to consume values from the bindings. 13 | /// 14 | /// - returns: 15 | /// A binding target that holds no strong references to the object. 16 | public func makeBindingTarget(on scheduler: SchedulerProtocol = UIScheduler(), _ action: @escaping (Base, U) -> Void) -> BindingTarget { 17 | return BindingTarget(on: scheduler, lifetime: lifetime) { [weak base = self.base] value in 18 | if let base = base { 19 | action(base, value) 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/NSObject+Lifetime.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import ReactiveSwift 3 | 4 | /// Holds the `Lifetime` of the object. 5 | fileprivate let isSwizzledKey = AssociationKey(default: false) 6 | 7 | /// Holds the `Lifetime` of the object. 8 | fileprivate let lifetimeKey = AssociationKey(default: nil) 9 | 10 | /// Holds the `Lifetime.Token` of the object. 11 | fileprivate let lifetimeTokenKey = AssociationKey(default: nil) 12 | 13 | extension Reactive where Base: NSObject { 14 | /// Returns a lifetime that ends when the object is deallocated. 15 | @nonobjc public var lifetime: Lifetime { 16 | return base.synchronized { 17 | if let lifetime = base.associations.value(forKey: lifetimeKey) { 18 | return lifetime 19 | } 20 | 21 | let token = Lifetime.Token() 22 | let lifetime = Lifetime(token) 23 | 24 | let objcClass: AnyClass = (base as AnyObject).objcClass 25 | let objcClassAssociations = Associations(objcClass as AnyObject) 26 | 27 | let deallocSelector = sel_registerName("dealloc")! 28 | 29 | // Swizzle `-dealloc` so that the lifetime token is released at the 30 | // beginning of the deallocation chain, and only after the KVO `-dealloc`. 31 | synchronized(objcClass) { 32 | // Swizzle the class only if it has not been swizzled before. 33 | if !objcClassAssociations.value(forKey: isSwizzledKey) { 34 | objcClassAssociations.setValue(true, forKey: isSwizzledKey) 35 | 36 | var existingImpl: IMP? = nil 37 | 38 | let newImplBlock: @convention(block) (UnsafeRawPointer) -> Void = { objectRef in 39 | // A custom trampoline of `objc_setAssociatedObject` is used, since 40 | // the imported version has been inserted with ARC calls that would 41 | // mess with the object deallocation chain. 42 | 43 | // Release the lifetime token. 44 | unsafeSetAssociatedValue(nil, forKey: lifetimeTokenKey, forObjectAt: objectRef) 45 | 46 | let impl: IMP 47 | 48 | // Call the existing implementation if one has been caught. Otherwise, 49 | // call the one first available in the superclass hierarchy. 50 | if let existingImpl = existingImpl { 51 | impl = existingImpl 52 | } else { 53 | let superclass: AnyClass = class_getSuperclass(objcClass) 54 | impl = class_getMethodImplementation(superclass, deallocSelector) 55 | } 56 | 57 | typealias Impl = @convention(c) (UnsafeRawPointer, Selector) -> Void 58 | unsafeBitCast(impl, to: Impl.self)(objectRef, deallocSelector) 59 | } 60 | 61 | let newImpl = imp_implementationWithBlock(newImplBlock as Any) 62 | 63 | if !class_addMethod(objcClass, deallocSelector, newImpl, "v@:") { 64 | // The class has an existing `dealloc`. Preserve that as `existingImpl`. 65 | let deallocMethod = class_getInstanceMethod(objcClass, deallocSelector) 66 | 67 | // Store the existing implementation to `existingImpl` to ensure it is 68 | // available before our version is swapped in. 69 | existingImpl = method_getImplementation(deallocMethod) 70 | 71 | // Store the swapped-out implementation to `existingImpl` in case 72 | // the implementation has been changed concurrently. 73 | existingImpl = method_setImplementation(deallocMethod, newImpl) 74 | } 75 | } 76 | } 77 | 78 | base.associations.setValue(token, forKey: lifetimeTokenKey) 79 | base.associations.setValue(lifetime, forKey: lifetimeKey) 80 | 81 | return lifetime 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/NSObject+ObjCRuntime.swift: -------------------------------------------------------------------------------- 1 | extension NSObject { 2 | /// The class of the instance reported by the ObjC `-class:` message. 3 | /// 4 | /// - note: `type(of:)` might return the runtime subclass, while this property 5 | /// always returns the original class. 6 | @nonobjc internal var objcClass: AnyClass { 7 | return (self as AnyObject).objcClass 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/NSObject+ReactiveExtensionsProvider.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import ReactiveSwift 3 | 4 | extension NSObject: ReactiveExtensionsProvider {} 5 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/NSObject+Synchronizing.swift: -------------------------------------------------------------------------------- 1 | extension NSObject { 2 | @nonobjc internal final func synchronized(execute: () throws -> Result) rethrows -> Result { 3 | objc_sync_enter(self) 4 | defer { objc_sync_exit(self) } 5 | return try execute() 6 | } 7 | } 8 | 9 | internal func synchronized(_ token: AnyObject, execute: () throws -> Result) rethrows -> Result { 10 | objc_sync_enter(token) 11 | defer { objc_sync_exit(token) } 12 | return try execute() 13 | } 14 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/ObjC+Constants.swift: -------------------------------------------------------------------------------- 1 | // Unavailable selectors in Swift. 2 | internal enum ObjCSelector { 3 | static let forwardInvocation = Selector((("forwardInvocation:"))) 4 | static let methodSignatureForSelector = Selector((("methodSignatureForSelector:"))) 5 | static let getClass = Selector((("class"))) 6 | } 7 | 8 | // Method encoding of the unavailable selectors. 9 | internal enum ObjCMethodEncoding { 10 | static let forwardInvocation = extract("v@:@") 11 | static let methodSignatureForSelector = extract("v@::") 12 | static let getClass = extract("#@:") 13 | 14 | private static func extract(_ string: StaticString) -> UnsafePointer { 15 | return UnsafeRawPointer(string.utf8Start).assumingMemoryBound(to: CChar.self) 16 | } 17 | } 18 | 19 | /// Objective-C type encoding. 20 | /// 21 | /// The enum does not cover all options, but only those that are expressive in 22 | /// Swift. 23 | internal enum ObjCTypeEncoding: Int8 { 24 | case char = 99 25 | case int = 105 26 | case short = 115 27 | case long = 108 28 | case longLong = 113 29 | 30 | case unsignedChar = 67 31 | case unsignedInt = 73 32 | case unsignedShort = 83 33 | case unsignedLong = 76 34 | case unsignedLongLong = 81 35 | 36 | case float = 102 37 | case double = 100 38 | 39 | case bool = 66 40 | 41 | case object = 64 42 | case type = 35 43 | case selector = 58 44 | 45 | case undefined = -1 46 | } 47 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/ObjC+Messages.swift: -------------------------------------------------------------------------------- 1 | // Unavailable classes like `NSInvocation` can still be passed into Swift as 2 | // `AnyClass` and `AnyObject`, and receive messages as `AnyClass` and 3 | // `AnyObject` existentials. 4 | // 5 | // These `@objc` protocols host the method signatures so that they can be used 6 | // with `AnyObject`. 7 | 8 | internal let NSInvocation: AnyClass = NSClassFromString("NSInvocation")! 9 | internal let NSMethodSignature: AnyClass = NSClassFromString("NSMethodSignature")! 10 | 11 | // Signatures defined in `@objc` protocols would be available for ObjC message 12 | // sending via `AnyObject`. 13 | @objc internal protocol ObjCClassReporting { 14 | // An alias for `-class`, which is unavailable in Swift. 15 | @objc(class) 16 | var objcClass: AnyClass! { get } 17 | } 18 | 19 | // Methods of `NSInvocation`. 20 | @objc internal protocol ObjCInvocation { 21 | @objc(setSelector:) 22 | func setSelector(_ selector: Selector) 23 | 24 | @objc(methodSignature) 25 | var objcMethodSignature: AnyObject { get } 26 | 27 | @objc(getArgument:atIndex:) 28 | func copy(to buffer: UnsafeMutableRawPointer?, forArgumentAt index: Int) 29 | 30 | func invoke() 31 | 32 | @objc(invocationWithMethodSignature:) 33 | static func invocation(withMethodSignature signature: AnyObject) -> AnyObject 34 | } 35 | 36 | // Methods of `NSMethodSignature`. 37 | @objc internal protocol ObjCMethodSignature { 38 | var numberOfArguments: UInt { get } 39 | 40 | @objc(getArgumentTypeAtIndex:) 41 | func argumentType(at index: UInt) -> UnsafePointer 42 | 43 | @objc(signatureWithObjCTypes:) 44 | static func signature(withObjCTypes typeEncoding: UnsafePointer) -> AnyObject 45 | } 46 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/ObjC+Runtime.swift: -------------------------------------------------------------------------------- 1 | /// Search in `class` for any method that matches the supplied selector without 2 | /// propagating to the ancestors. 3 | /// 4 | /// - parameters: 5 | /// - class: The class to search the method in. 6 | /// - selector: The selector of the method. 7 | /// 8 | /// - returns: 9 | /// The matching method, or `nil` if none is found. 10 | internal func class_getImmediateMethod(_ `class`: AnyClass, _ selector: Selector) -> Method? { 11 | if let buffer = class_copyMethodList(`class`, nil) { 12 | defer { free(buffer) } 13 | 14 | var iterator = buffer 15 | while let method = iterator.pointee { 16 | if method_getName(method) == selector { 17 | return method 18 | } 19 | iterator = iterator.advanced(by: 1) 20 | } 21 | } 22 | 23 | return nil 24 | } 25 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/ObjC+RuntimeSubclassing.swift: -------------------------------------------------------------------------------- 1 | import ReactiveSwift 2 | 3 | /// Whether the runtime subclass has already been swizzled. 4 | fileprivate let runtimeSubclassedKey = AssociationKey(default: false) 5 | 6 | /// A known RAC runtime subclass of the instance. `nil` if the runtime subclass 7 | /// has not been requested for the instance before. 8 | fileprivate let knownRuntimeSubclassKey = AssociationKey(default: nil) 9 | 10 | /// ISA-swizzle the class of the supplied instance. 11 | /// 12 | /// - note: If the instance has already been isa-swizzled, the swizzling happens 13 | /// in place in the runtime subclass created by external parties. 14 | /// 15 | /// - parameters: 16 | /// - instance: The instance to be swizzled. 17 | /// 18 | /// - returns: 19 | /// The runtime subclass of the perceived class of the instance. 20 | internal func swizzleClass(_ instance: NSObject) -> AnyClass { 21 | if let knownSubclass = instance.associations.value(forKey: knownRuntimeSubclassKey) { 22 | return knownSubclass 23 | } 24 | 25 | let perceivedClass: AnyClass = instance.objcClass 26 | let realClass: AnyClass = object_getClass(instance)! 27 | let realClassAssociations = Associations(realClass as AnyObject) 28 | 29 | if perceivedClass != realClass { 30 | // If the class is already lying about what it is, it's probably a KVO 31 | // dynamic subclass or something else that we shouldn't subclass at runtime. 32 | synchronized(realClass) { 33 | let isSwizzled = realClassAssociations.value(forKey: runtimeSubclassedKey) 34 | if !isSwizzled { 35 | replaceGetClass(in: realClass, decoy: perceivedClass) 36 | realClassAssociations.setValue(true, forKey: runtimeSubclassedKey) 37 | } 38 | } 39 | 40 | return realClass 41 | } else { 42 | let name = subclassName(of: perceivedClass) 43 | let subclass: AnyClass = name.withCString { cString in 44 | if let existingClass = objc_getClass(cString) as! AnyClass? { 45 | return existingClass 46 | } else { 47 | let subclass: AnyClass = objc_allocateClassPair(perceivedClass, cString, 0)! 48 | replaceGetClass(in: subclass, decoy: perceivedClass) 49 | objc_registerClassPair(subclass) 50 | return subclass 51 | } 52 | } 53 | 54 | object_setClass(instance, subclass) 55 | instance.associations.setValue(subclass, forKey: knownRuntimeSubclassKey) 56 | return subclass 57 | } 58 | } 59 | 60 | private func subclassName(of class: AnyClass) -> String { 61 | return String(cString: class_getName(`class`)).appending("_RACSwift") 62 | } 63 | 64 | /// Swizzle the `-class` and `+class` methods. 65 | /// 66 | /// - parameters: 67 | /// - class: The class to swizzle. 68 | /// - perceivedClass: The class to be reported by the methods. 69 | private func replaceGetClass(in class: AnyClass, decoy perceivedClass: AnyClass) { 70 | let getClass: @convention(block) (Any) -> AnyClass = { _ in 71 | return perceivedClass 72 | } 73 | 74 | let impl = imp_implementationWithBlock(getClass as Any) 75 | 76 | _ = class_replaceMethod(`class`, 77 | ObjCSelector.getClass, 78 | impl, 79 | ObjCMethodEncoding.getClass) 80 | 81 | _ = class_replaceMethod(object_getClass(`class`), 82 | ObjCSelector.getClass, 83 | impl, 84 | ObjCMethodEncoding.getClass) 85 | } 86 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/ObjC+Selector.swift: -------------------------------------------------------------------------------- 1 | extension Selector { 2 | /// `self` as a pointer. It is uniqued across instances, similar to 3 | /// `StaticString`. 4 | internal var utf8Start: UnsafePointer { 5 | return unsafeBitCast(self, to: UnsafePointer.self) 6 | } 7 | 8 | /// An alias of `self`, used in method interception. 9 | internal var alias: Selector { 10 | return prefixing("rac0_") 11 | } 12 | 13 | /// An alias of `self`, used in method interception specifically for 14 | /// preserving (if found) an immediate implementation of `self` in the 15 | /// runtime subclass. 16 | internal var interopAlias: Selector { 17 | return prefixing("rac1_") 18 | } 19 | 20 | internal func prefixing(_ prefix: StaticString) -> Selector { 21 | let length = Int(strlen(utf8Start)) 22 | let prefixedLength = length + prefix.utf8CodeUnitCount 23 | 24 | let asciiPrefix = UnsafeRawPointer(prefix.utf8Start).assumingMemoryBound(to: Int8.self) 25 | 26 | let cString = UnsafeMutablePointer.allocate(capacity: prefixedLength + 1) 27 | defer { 28 | cString.deinitialize() 29 | cString.deallocate(capacity: prefixedLength + 1) 30 | } 31 | 32 | cString.initialize(from: asciiPrefix, count: prefix.utf8CodeUnitCount) 33 | (cString + prefix.utf8CodeUnitCount).initialize(from: utf8Start, count: length) 34 | (cString + prefixedLength).initialize(to: Int8(UInt8(ascii: "\0"))) 35 | 36 | return sel_registerName(cString) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/ObjCRuntimeAliases.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | NS_ASSUME_NONNULL_BEGIN 5 | 6 | const IMP _rac_objc_msgForward; 7 | 8 | /// A trampoline of `objc_setAssociatedObject` that is made to circumvent the 9 | /// reference counting calls in the imported version in Swift. 10 | void _rac_objc_setAssociatedObject(const void* object, const void* key, id _Nullable value, objc_AssociationPolicy policy); 11 | 12 | NS_ASSUME_NONNULL_END 13 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/ObjCRuntimeAliases.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | const IMP _rac_objc_msgForward = _objc_msgForward; 5 | 6 | void _rac_objc_setAssociatedObject(const void* object, const void* key, id value, objc_AssociationPolicy policy) { 7 | __unsafe_unretained id obj = (__bridge typeof(obj)) object; 8 | objc_setAssociatedObject(obj, key, value, policy); 9 | } 10 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/ReactiveCocoa.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | //! Project version number for ReactiveCocoa. 4 | FOUNDATION_EXPORT double ReactiveCocoaVersionNumber; 5 | 6 | //! Project version string for ReactiveCocoa. 7 | FOUNDATION_EXPORT const unsigned char ReactiveCocoaVersionString[]; 8 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/Shared/MKMapView.swift: -------------------------------------------------------------------------------- 1 | import ReactiveSwift 2 | import MapKit 3 | 4 | @available(tvOS 9.2, *) 5 | extension Reactive where Base: MKMapView { 6 | 7 | /// Sets the map type. 8 | public var mapType: BindingTarget { 9 | return makeBindingTarget { $0.mapType = $1 } 10 | } 11 | 12 | /// Sets if zoom is enabled for map. 13 | public var isZoomEnabled: BindingTarget { 14 | return makeBindingTarget { $0.isZoomEnabled = $1 } 15 | } 16 | 17 | /// Sets if scroll is enabled for map. 18 | public var isScrollEnabled: BindingTarget { 19 | return makeBindingTarget { $0.isScrollEnabled = $1 } 20 | } 21 | 22 | #if !os(tvOS) 23 | /// Sets if pitch is enabled for map. 24 | public var isPitchEnabled: BindingTarget { 25 | return makeBindingTarget { $0.isPitchEnabled = $1 } 26 | } 27 | 28 | /// Sets if rotation is enabled for map. 29 | public var isRotateEnabled: BindingTarget { 30 | return makeBindingTarget { $0.isRotateEnabled = $1 } 31 | } 32 | #endif 33 | } 34 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/Shared/NSLayoutConstraint.swift: -------------------------------------------------------------------------------- 1 | import ReactiveSwift 2 | 3 | #if os(macOS) 4 | import AppKit 5 | #else 6 | import UIKit 7 | #endif 8 | 9 | extension Reactive where Base: NSLayoutConstraint { 10 | 11 | /// Sets the constant. 12 | public var constant: BindingTarget { 13 | return makeBindingTarget { $0.constant = $1 } 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/UIKit/ReusableComponents.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import ReactiveSwift 3 | import enum Result.NoError 4 | 5 | @objc public protocol Reusable: class { 6 | func prepareForReuse() 7 | } 8 | 9 | extension Reactive where Base: NSObject, Base: Reusable { 10 | public var prepareForReuse: Signal<(), NoError> { 11 | return trigger(for: #selector(base.prepareForReuse)) 12 | } 13 | } 14 | 15 | extension UITableViewCell: Reusable {} 16 | extension UITableViewHeaderFooterView: Reusable {} 17 | extension UICollectionReusableView: Reusable {} 18 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/UIKit/UIActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | import ReactiveSwift 2 | import UIKit 3 | 4 | extension Reactive where Base: UIActivityIndicatorView { 5 | /// Sets whether the activity indicator should be animating. 6 | public var isAnimating: BindingTarget { 7 | return makeBindingTarget { $1 ? $0.startAnimating() : $0.stopAnimating() } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/UIKit/UIBarButtonItem.swift: -------------------------------------------------------------------------------- 1 | import ReactiveSwift 2 | import UIKit 3 | 4 | extension Reactive where Base: UIBarButtonItem { 5 | /// The current associated action of `self`. 6 | private var associatedAction: Atomic<(action: CocoaAction, disposable: Disposable?)?> { 7 | return associatedValue { _ in Atomic(nil) } 8 | } 9 | 10 | /// The action to be triggered when the button is pressed. It also controls 11 | /// the enabled state of the button. 12 | public var pressed: CocoaAction? { 13 | get { 14 | return associatedAction.value?.action 15 | } 16 | 17 | nonmutating set { 18 | base.target = newValue 19 | base.action = newValue.map { _ in CocoaAction.selector } 20 | 21 | associatedAction 22 | .swap(newValue.map { action in 23 | let disposable = isEnabled <~ action.isEnabled 24 | return (action, disposable) 25 | })? 26 | .disposable?.dispose() 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/UIKit/UIBarItem.swift: -------------------------------------------------------------------------------- 1 | import ReactiveSwift 2 | import UIKit 3 | 4 | extension Reactive where Base: UIBarItem { 5 | /// Sets whether the bar item is enabled. 6 | public var isEnabled: BindingTarget { 7 | return makeBindingTarget { $0.isEnabled = $1 } 8 | } 9 | 10 | /// Sets image of bar item. 11 | public var image: BindingTarget { 12 | return makeBindingTarget { $0.image = $1 } 13 | } 14 | 15 | /// Sets the title of bar item. 16 | public var title: BindingTarget { 17 | return makeBindingTarget { $0.title = $1 } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/UIKit/UIButton.swift: -------------------------------------------------------------------------------- 1 | import ReactiveSwift 2 | import UIKit 3 | 4 | extension Reactive where Base: UIButton { 5 | /// The action to be triggered when the button is pressed. It also controls 6 | /// the enabled state of the button. 7 | public var pressed: CocoaAction? { 8 | get { 9 | return associatedAction.withValue { info in 10 | return info.flatMap { info in 11 | return info.controlEvents == .touchUpInside ? info.action : nil 12 | } 13 | } 14 | } 15 | 16 | nonmutating set { 17 | setAction(newValue, for: .touchUpInside) 18 | } 19 | } 20 | 21 | /// Sets the title of the button for its normal state. 22 | public var title: BindingTarget { 23 | return makeBindingTarget { $0.setTitle($1, for: .normal) } 24 | } 25 | 26 | /// Sets the title of the button for the specified state. 27 | public func title(for state: UIControlState) -> BindingTarget { 28 | return makeBindingTarget { $0.setTitle($1, for: state) } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/UIKit/UICollectionView.swift: -------------------------------------------------------------------------------- 1 | import ReactiveSwift 2 | import UIKit 3 | 4 | extension Reactive where Base: UICollectionView { 5 | public var reloadData: BindingTarget<()> { 6 | return makeBindingTarget { base, _ in base.reloadData() } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/UIKit/UIControl.swift: -------------------------------------------------------------------------------- 1 | import ReactiveSwift 2 | import UIKit 3 | import enum Result.NoError 4 | 5 | extension Reactive where Base: UIControl { 6 | /// The current associated action of `self`, with its registered event mask 7 | /// and its disposable. 8 | internal var associatedAction: Atomic<(action: CocoaAction, controlEvents: UIControlEvents, disposable: Disposable)?> { 9 | return associatedValue { _ in Atomic(nil) } 10 | } 11 | 12 | /// Set the associated action of `self` to `action`, and register it for the 13 | /// control events specified by `controlEvents`. 14 | /// 15 | /// - parameters: 16 | /// - action: The action to be associated. 17 | /// - controlEvents: The control event mask. 18 | /// - disposable: An outside disposable that will be bound to the scope of 19 | /// the given `action`. 20 | internal func setAction(_ action: CocoaAction?, for controlEvents: UIControlEvents, disposable: Disposable? = nil) { 21 | associatedAction.modify { associatedAction in 22 | associatedAction?.disposable.dispose() 23 | 24 | if let action = action { 25 | base.addTarget(action, action: CocoaAction.selector, for: controlEvents) 26 | 27 | let compositeDisposable = CompositeDisposable() 28 | compositeDisposable += isEnabled <~ action.isEnabled 29 | compositeDisposable += { [weak base = self.base] in 30 | base?.removeTarget(action, action: CocoaAction.selector, for: controlEvents) 31 | } 32 | compositeDisposable += disposable 33 | 34 | associatedAction = (action, controlEvents, ScopedDisposable(compositeDisposable)) 35 | } else { 36 | associatedAction = nil 37 | } 38 | } 39 | } 40 | 41 | /// Create a signal which sends a `value` event for each of the specified 42 | /// control events. 43 | /// 44 | /// - parameters: 45 | /// - controlEvents: The control event mask. 46 | /// 47 | /// - returns: 48 | /// A signal that sends the control each time the control event occurs. 49 | public func controlEvents(_ controlEvents: UIControlEvents) -> Signal { 50 | return Signal { observer in 51 | let receiver = CocoaTarget(observer) { $0 as! Base } 52 | base.addTarget(receiver, 53 | action: #selector(receiver.sendNext), 54 | for: controlEvents) 55 | 56 | let disposable = lifetime.ended.observeCompleted(observer.sendCompleted) 57 | 58 | return ActionDisposable { [weak base = self.base] in 59 | disposable?.dispose() 60 | 61 | base?.removeTarget(receiver, 62 | action: #selector(receiver.sendNext), 63 | for: controlEvents) 64 | } 65 | } 66 | } 67 | 68 | @available(*, unavailable, renamed: "controlEvents(_:)") 69 | public func trigger(for controlEvents: UIControlEvents) -> Signal<(), NoError> { 70 | fatalError() 71 | } 72 | 73 | /// Sets whether the control is enabled. 74 | public var isEnabled: BindingTarget { 75 | return makeBindingTarget { $0.isEnabled = $1 } 76 | } 77 | 78 | /// Sets whether the control is selected. 79 | public var isSelected: BindingTarget { 80 | return makeBindingTarget { $0.isSelected = $1 } 81 | } 82 | 83 | /// Sets whether the control is highlighted. 84 | public var isHighlighted: BindingTarget { 85 | return makeBindingTarget { $0.isHighlighted = $1 } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/UIKit/UIGestureRecognizer.swift: -------------------------------------------------------------------------------- 1 | import ReactiveSwift 2 | import UIKit 3 | import enum Result.NoError 4 | 5 | extension Reactive where Base: UIGestureRecognizer { 6 | /// Create a signal which sends a `next` event for each gesture event 7 | /// 8 | /// - returns: 9 | /// A trigger signal. 10 | public var stateChanged: Signal { 11 | return Signal { observer in 12 | let receiver = CocoaTarget(observer) { gestureRecognizer in 13 | return gestureRecognizer as! Base 14 | } 15 | base.addTarget(receiver, action: #selector(receiver.sendNext)) 16 | 17 | let disposable = lifetime.ended.observeCompleted(observer.sendCompleted) 18 | 19 | return ActionDisposable { [weak base = self.base] in 20 | disposable?.dispose() 21 | base?.removeTarget(receiver, action: #selector(receiver.sendNext)) 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/UIKit/UIImageView.swift: -------------------------------------------------------------------------------- 1 | import ReactiveSwift 2 | import UIKit 3 | 4 | extension Reactive where Base: UIImageView { 5 | /// Sets the image of the image view. 6 | public var image: BindingTarget { 7 | return makeBindingTarget { $0.image = $1 } 8 | } 9 | 10 | /// Sets the image of the image view for its highlighted state. 11 | public var highlightedImage: BindingTarget { 12 | return makeBindingTarget { $0.highlightedImage = $1 } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/UIKit/UILabel.swift: -------------------------------------------------------------------------------- 1 | import ReactiveSwift 2 | import UIKit 3 | 4 | extension Reactive where Base: UILabel { 5 | /// Sets the text of the label. 6 | public var text: BindingTarget { 7 | return makeBindingTarget { $0.text = $1 } 8 | } 9 | 10 | /// Sets the attributed text of the label. 11 | public var attributedText: BindingTarget { 12 | return makeBindingTarget { $0.attributedText = $1 } 13 | } 14 | 15 | /// Sets the color of the text of the label. 16 | public var textColor: BindingTarget { 17 | return makeBindingTarget { $0.textColor = $1 } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/UIKit/UIProgressView.swift: -------------------------------------------------------------------------------- 1 | import ReactiveSwift 2 | import UIKit 3 | 4 | extension Reactive where Base: UIProgressView { 5 | /// Sets the relative progress to be reflected by the progress view. 6 | public var progress: BindingTarget { 7 | return makeBindingTarget { $0.progress = $1 } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/UIKit/UIScrollView.swift: -------------------------------------------------------------------------------- 1 | import ReactiveSwift 2 | import UIKit 3 | 4 | extension Reactive where Base: UIScrollView { 5 | /// Sets the content inset of the scroll view. 6 | public var contentInset: BindingTarget { 7 | return makeBindingTarget { $0.contentInset = $1 } 8 | } 9 | 10 | /// Sets the scroll indicator insets of the scroll view. 11 | public var scrollIndicatorInsets: BindingTarget { 12 | return makeBindingTarget { $0.scrollIndicatorInsets = $1 } 13 | } 14 | 15 | /// Sets whether scrolling the scroll view is enabled. 16 | public var isScrollEnabled: BindingTarget { 17 | return makeBindingTarget { $0.isScrollEnabled = $1 } 18 | } 19 | 20 | /// Sets the zoom scale of the scroll view. 21 | public var zoomScale: BindingTarget { 22 | return makeBindingTarget { $0.zoomScale = $1 } 23 | } 24 | 25 | /// Sets the minimum zoom scale of the scroll view. 26 | public var minimumZoomScale: BindingTarget { 27 | return makeBindingTarget { $0.minimumZoomScale = $1 } 28 | } 29 | 30 | /// Sets the maximum zoom scale of the scroll view. 31 | public var maximumZoomScale: BindingTarget { 32 | return makeBindingTarget { $0.maximumZoomScale = $1 } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/UIKit/UISegmentedControl.swift: -------------------------------------------------------------------------------- 1 | import ReactiveSwift 2 | import enum Result.NoError 3 | import UIKit 4 | 5 | extension Reactive where Base: UISegmentedControl { 6 | /// Changes the selected segment of the segmented control. 7 | public var selectedSegmentIndex: BindingTarget { 8 | return makeBindingTarget { $0.selectedSegmentIndex = $1 } 9 | } 10 | 11 | /// A signal of indexes of selections emitted by the segmented control. 12 | public var selectedSegmentIndexes: Signal { 13 | return controlEvents(.valueChanged).map { $0.selectedSegmentIndex } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/UIKit/UITableView.swift: -------------------------------------------------------------------------------- 1 | import ReactiveSwift 2 | import UIKit 3 | 4 | extension Reactive where Base: UITableView { 5 | public var reloadData: BindingTarget<()> { 6 | return makeBindingTarget { base, _ in base.reloadData() } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/UIKit/UITextField.swift: -------------------------------------------------------------------------------- 1 | import ReactiveSwift 2 | import enum Result.NoError 3 | import UIKit 4 | 5 | extension Reactive where Base: UITextField { 6 | /// Sets the text of the text field. 7 | public var text: BindingTarget { 8 | return makeBindingTarget { $0.text = $1 } 9 | } 10 | 11 | /// A signal of text values emitted by the text field upon end of editing. 12 | /// 13 | /// - note: To observe text values that change on all editing events, 14 | /// see `continuousTextValues`. 15 | public var textValues: Signal { 16 | return controlEvents(.editingDidEnd).map { $0.text } 17 | } 18 | 19 | /// A signal of text values emitted by the text field upon any changes. 20 | /// 21 | /// - note: To observe text values only when editing ends, see `textValues`. 22 | public var continuousTextValues: Signal { 23 | return controlEvents(.editingChanged).map { $0.text } 24 | } 25 | 26 | /// Sets the attributed text of the text field. 27 | public var attributedText: BindingTarget { 28 | return makeBindingTarget { $0.attributedText = $1 } 29 | } 30 | 31 | /// A signal of attributed text values emitted by the text field upon end of editing. 32 | /// 33 | /// - note: To observe attributed text values that change on all editing events, 34 | /// see `continuousAttributedTextValues`. 35 | public var attributedTextValues: Signal { 36 | return controlEvents(.editingDidEnd).map { $0.attributedText } 37 | } 38 | 39 | /// A signal of attributed text values emitted by the text field upon any changes. 40 | /// 41 | /// - note: To observe attributed text values only when editing ends, see `attributedTextValues`. 42 | public var continuousAttributedTextValues: Signal { 43 | return controlEvents(.editingChanged).map { $0.attributedText } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/UIKit/UITextView.swift: -------------------------------------------------------------------------------- 1 | import ReactiveSwift 2 | import UIKit 3 | import enum Result.NoError 4 | 5 | extension Reactive where Base: UITextView { 6 | /// Sets the text of the text view. 7 | public var text: BindingTarget { 8 | return makeBindingTarget { $0.text = $1 } 9 | } 10 | 11 | private func textValues(forName name: NSNotification.Name) -> Signal { 12 | return NotificationCenter.default 13 | .reactive 14 | .notifications(forName: name, object: base) 15 | .take(during: lifetime) 16 | .map { ($0.object as! UITextView).text! } 17 | } 18 | 19 | /// A signal of text values emitted by the text view upon end of editing. 20 | /// 21 | /// - note: To observe text values that change on all editing events, 22 | /// see `continuousTextValues`. 23 | public var textValues: Signal { 24 | return textValues(forName: .UITextViewTextDidEndEditing) 25 | } 26 | 27 | /// A signal of text values emitted by the text view upon any changes. 28 | /// 29 | /// - note: To observe text values only when editing ends, see `textValues`. 30 | public var continuousTextValues: Signal { 31 | return textValues(forName: .UITextViewTextDidChange) 32 | } 33 | 34 | /// Sets the attributed text of the text view. 35 | public var attributedText: BindingTarget { 36 | return makeBindingTarget { $0.attributedText = $1 } 37 | } 38 | 39 | private func attributedTextValues(forName name: NSNotification.Name) -> Signal { 40 | return NotificationCenter.default 41 | .reactive 42 | .notifications(forName: name, object: base) 43 | .take(during: lifetime) 44 | .map { ($0.object as! UITextView).attributedText! } 45 | } 46 | 47 | /// A signal of attributed text values emitted by the text view upon end of editing. 48 | /// 49 | /// - note: To observe attributed text values that change on all editing events, 50 | /// see `continuousAttributedTextValues`. 51 | public var attributedTextValues: Signal { 52 | return attributedTextValues(forName: .UITextViewTextDidEndEditing) 53 | } 54 | 55 | /// A signal of attributed text values emitted by the text view upon any changes. 56 | /// 57 | /// - note: To observe text values only when editing ends, see `attributedTextValues`. 58 | public var continuousAttributedTextValues: Signal { 59 | return attributedTextValues(forName: .UITextViewTextDidChange) 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/UIKit/UIView.swift: -------------------------------------------------------------------------------- 1 | import ReactiveSwift 2 | import UIKit 3 | 4 | extension Reactive where Base: UIView { 5 | /// Sets the alpha value of the view. 6 | public var alpha: BindingTarget { 7 | return makeBindingTarget { $0.alpha = $1 } 8 | } 9 | 10 | /// Sets whether the view is hidden. 11 | public var isHidden: BindingTarget { 12 | return makeBindingTarget { $0.isHidden = $1 } 13 | } 14 | 15 | /// Sets whether the view accepts user interactions. 16 | public var isUserInteractionEnabled: BindingTarget { 17 | return makeBindingTarget { $0.isUserInteractionEnabled = $1 } 18 | } 19 | 20 | /// Sets the background color of the view. 21 | public var backgroundColor: BindingTarget { 22 | return makeBindingTarget { $0.backgroundColor = $1 } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/UIKit/iOS/UIDatePicker.swift: -------------------------------------------------------------------------------- 1 | import ReactiveSwift 2 | import enum Result.NoError 3 | import UIKit 4 | 5 | extension Reactive where Base: UIDatePicker { 6 | /// Sets the date of the date picker. 7 | public var date: BindingTarget { 8 | return makeBindingTarget { $0.date = $1 } 9 | } 10 | 11 | /// A signal of dates emitted by the date picker. 12 | public var dates: Signal { 13 | return controlEvents(.valueChanged).map { $0.date } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/UIKit/iOS/UIKeyboard.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import ReactiveSwift 3 | import enum Result.NoError 4 | 5 | /// The context of an upcoming change in the frame of the system keyboard. 6 | public struct KeyboardChangeContext { 7 | private let base: [AnyHashable: Any] 8 | 9 | /// The current frame of the system keyboard. 10 | public var beginFrame: CGRect { 11 | return base[UIKeyboardFrameBeginUserInfoKey] as! CGRect 12 | } 13 | 14 | /// The final frame of the system keyboard. 15 | public var endFrame: CGRect { 16 | return base[UIKeyboardFrameEndUserInfoKey] as! CGRect 17 | } 18 | 19 | /// The animation curve which the system keyboard will use to animate the 20 | /// change in its frame. 21 | public var animationCurve: UIViewAnimationCurve { 22 | return base[UIKeyboardAnimationCurveUserInfoKey] as! UIViewAnimationCurve 23 | } 24 | 25 | /// The duration in which the system keyboard expects to animate the change in 26 | /// its frame. 27 | public var animationDuration: Double { 28 | return base[UIKeyboardAnimationDurationUserInfoKey] as! Double 29 | } 30 | 31 | /// Indicates whether the change is triggered locally. Used in iPad 32 | /// multitasking, where all foreground apps would be notified of any changes 33 | /// in the system keyboard's frame. 34 | @available(iOS 9.0, *) 35 | public var isLocal: Bool { 36 | return base[UIKeyboardIsLocalUserInfoKey] as! Bool 37 | } 38 | 39 | fileprivate init(_ userInfo: [AnyHashable: Any]) { 40 | base = userInfo 41 | } 42 | } 43 | 44 | extension Reactive where Base: NotificationCenter { 45 | /// Create a `Signal` that notifies whenever the system keyboard announces an 46 | /// upcoming change in its frame. 47 | /// 48 | /// - returns: A `Signal` that emits the context of every change in the 49 | /// system keyboard's frame. 50 | public var keyboardChange: Signal { 51 | return notifications(forName: .UIKeyboardWillChangeFrame) 52 | .map { notification in KeyboardChangeContext(notification.userInfo!) } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/UIKit/iOS/UIRefreshControl.swift: -------------------------------------------------------------------------------- 1 | import ReactiveSwift 2 | import enum Result.NoError 3 | import UIKit 4 | 5 | extension Reactive where Base: UIRefreshControl { 6 | /// Sets whether the refresh control should be refreshing. 7 | public var isRefreshing: BindingTarget { 8 | return makeBindingTarget { $1 ? $0.beginRefreshing() : $0.endRefreshing() } 9 | } 10 | 11 | /// Sets the attributed title of the refresh control. 12 | public var attributedTitle: BindingTarget { 13 | return makeBindingTarget { $0.attributedTitle = $1 } 14 | } 15 | 16 | /// The action to be triggered when the refresh control is refreshed. It 17 | /// also controls the enabled and refreshing states of the refresh control. 18 | public var refresh: CocoaAction? { 19 | get { 20 | return associatedAction.withValue { info in 21 | return info.flatMap { info in 22 | return info.controlEvents == .valueChanged ? info.action : nil 23 | } 24 | } 25 | } 26 | 27 | nonmutating set { 28 | let disposable = newValue.flatMap { isRefreshing <~ $0.isExecuting } 29 | setAction(newValue, for: .valueChanged, disposable: disposable) 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/UIKit/iOS/UISearchBar.swift: -------------------------------------------------------------------------------- 1 | import ReactiveSwift 2 | import enum Result.NoError 3 | import UIKit 4 | 5 | private class ReactiveUISearchBarDelegate: NSObject, UISearchBarDelegate { 6 | 7 | @objc func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {} 8 | @objc func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {} 9 | } 10 | 11 | private var delegateKey: UInt8 = 0 12 | 13 | extension Reactive where Base: UISearchBar { 14 | 15 | private var delegate: ReactiveUISearchBarDelegate { 16 | if let delegate = objc_getAssociatedObject(base, &delegateKey) as? ReactiveUISearchBarDelegate { 17 | return delegate 18 | } else if let _ = base.delegate { 19 | fatalError("Cannot use reactive values on UISearchBar with a custom delegate!") 20 | } 21 | 22 | let delegate = ReactiveUISearchBarDelegate() 23 | base.delegate = delegate 24 | objc_setAssociatedObject(base, &delegateKey, delegate, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) 25 | return delegate 26 | } 27 | 28 | /// Sets the text of the search bar. 29 | public var text: BindingTarget { 30 | return makeBindingTarget { $0.text = $1 } 31 | } 32 | 33 | /// A signal of text values emitted by the search bar upon end of editing. 34 | /// 35 | /// - important: Creating this Signal will make the reactive extension 36 | /// provider the delegate of the search bar. Setting your own delegate is 37 | /// not supported and will result in a runtime error. 38 | /// 39 | /// - note: To observe text values that change on all editing events, 40 | /// see `continuousTextValues`. 41 | public var textValues: Signal { 42 | return delegate.reactive.trigger(for: #selector(UISearchBarDelegate.searchBarTextDidEndEditing)) 43 | .map { [unowned base] in base.text } 44 | } 45 | 46 | /// A signal of text values emitted by the search bar upon any changes. 47 | /// 48 | /// - important: Creating this Signal will make the reactive extension 49 | /// provider the delegate of the search bar. Setting your own delegate is 50 | /// not supported and will result in a runtime error. 51 | /// 52 | /// - note: To observe text values only when editing ends, see `textValues`. 53 | public var continuousTextValues: Signal { 54 | return delegate.reactive.trigger(for: #selector(UISearchBarDelegate.searchBar(_:textDidChange:))) 55 | .map { [unowned base] in base.text } 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/UIKit/iOS/UISlider.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import ReactiveSwift 3 | import enum Result.NoError 4 | 5 | extension Reactive where Base: UISlider { 6 | 7 | /// Sets slider's value. 8 | public var value: BindingTarget { 9 | return makeBindingTarget { $0.value = $1 } 10 | } 11 | 12 | /// Sets slider's minimum value. 13 | public var minimumValue: BindingTarget { 14 | return makeBindingTarget { $0.minimumValue = $1 } 15 | } 16 | 17 | /// Sets slider's maximum value. 18 | public var maximumValue: BindingTarget { 19 | return makeBindingTarget { $0.maximumValue = $1 } 20 | } 21 | 22 | /// A signal of float values emitted by the slider while being dragged by 23 | /// the user. 24 | /// 25 | /// - note: If slider's `isContinuous` property is `false` then values are 26 | /// sent only when user releases the slider. 27 | public var values: Signal { 28 | return controlEvents(.valueChanged).map { $0.value } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/UIKit/iOS/UIStepper.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import ReactiveSwift 3 | import enum Result.NoError 4 | 5 | extension Reactive where Base: UIStepper { 6 | 7 | /// Sets the stepper's value. 8 | public var value: BindingTarget { 9 | return makeBindingTarget { $0.value = $1 } 10 | } 11 | 12 | /// Sets stepper's minimum value. 13 | public var minimumValue: BindingTarget { 14 | return makeBindingTarget { $0.minimumValue = $1 } 15 | } 16 | 17 | /// Sets stepper's maximum value. 18 | public var maximumValue: BindingTarget { 19 | return makeBindingTarget { $0.maximumValue = $1 } 20 | } 21 | 22 | /// A signal of double values emitted by the stepper upon each user's 23 | /// interaction. 24 | public var values: Signal { 25 | return controlEvents(.valueChanged).map { $0.value } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/UIKit/iOS/UISwitch.swift: -------------------------------------------------------------------------------- 1 | import ReactiveSwift 2 | import enum Result.NoError 3 | import UIKit 4 | 5 | extension Reactive where Base: UISwitch { 6 | /// The action to be triggered when the switch is changed. It also controls 7 | /// the enabled state of the switch 8 | public var toggled: CocoaAction? { 9 | get { 10 | return associatedAction.withValue { info in 11 | return info.flatMap { info in 12 | return info.controlEvents == .valueChanged ? info.action : nil 13 | } 14 | } 15 | } 16 | 17 | nonmutating set { 18 | setAction(newValue, for: .valueChanged) 19 | } 20 | } 21 | /// Sets the on-off state of the switch. 22 | public var isOn: BindingTarget { 23 | return makeBindingTarget { $0.isOn = $1 } 24 | } 25 | 26 | /// A signal of on-off states in `Bool` emitted by the switch. 27 | public var isOnValues: Signal { 28 | return controlEvents(.valueChanged).map { $0.isOn } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Pods/ReactiveCocoa/ReactiveCocoa/module.modulemap: -------------------------------------------------------------------------------- 1 | framework module ReactiveCocoa { 2 | umbrella header "ReactiveCocoa.h" 3 | private header "ObjCRuntimeAliases.h" 4 | 5 | export * 6 | module * { export * } 7 | } 8 | -------------------------------------------------------------------------------- /Pods/ReactiveSwift/LICENSE.md: -------------------------------------------------------------------------------- 1 | **Copyright (c) 2012 - 2016, GitHub, Inc.** 2 | **All rights reserved.** 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of 5 | this software and associated documentation files (the "Software"), to deal in 6 | the Software without restriction, including without limitation the rights to 7 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 8 | the Software, and to permit persons to whom the Software is furnished to do so, 9 | subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 16 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 17 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 18 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Pods/ReactiveSwift/Sources/Atomic.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Atomic.swift 3 | // ReactiveSwift 4 | // 5 | // Created by Justin Spahr-Summers on 2014-06-10. 6 | // Copyright (c) 2014 GitHub. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) 11 | import MachO 12 | #endif 13 | 14 | /// Represents a finite state machine that can transit from one state to 15 | /// another. 16 | internal protocol AtomicStateProtocol { 17 | associatedtype State: RawRepresentable 18 | 19 | /// Try to transit from the expected current state to the specified next 20 | /// state. 21 | /// 22 | /// - parameters: 23 | /// - expected: The expected state. 24 | /// 25 | /// - returns: 26 | /// `true` if the transition succeeds. `false` otherwise. 27 | func tryTransiting(from expected: State, to next: State) -> Bool 28 | } 29 | 30 | /// A simple, generic lock-free finite state machine. 31 | /// 32 | /// - warning: `deinitialize` must be called to dispose of the consumed memory. 33 | internal struct UnsafeAtomicState: AtomicStateProtocol where State.RawValue == Int32 { 34 | internal typealias Transition = (expected: State, next: State) 35 | #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) 36 | private let value: UnsafeMutablePointer 37 | 38 | /// Create a finite state machine with the specified initial state. 39 | /// 40 | /// - parameters: 41 | /// - initial: The desired initial state. 42 | internal init(_ initial: State) { 43 | value = UnsafeMutablePointer.allocate(capacity: 1) 44 | value.initialize(to: initial.rawValue) 45 | } 46 | 47 | /// Deinitialize the finite state machine. 48 | internal func deinitialize() { 49 | value.deinitialize() 50 | value.deallocate(capacity: 1) 51 | } 52 | 53 | /// Compare the current state with the specified state. 54 | /// 55 | /// - parameters: 56 | /// - expected: The expected state. 57 | /// 58 | /// - returns: 59 | /// `true` if the current state matches the expected state. `false` 60 | /// otherwise. 61 | @inline(__always) 62 | internal func `is`(_ expected: State) -> Bool { 63 | return OSAtomicCompareAndSwap32Barrier(expected.rawValue, 64 | expected.rawValue, 65 | value) 66 | } 67 | 68 | /// Try to transit from the expected current state to the specified next 69 | /// state. 70 | /// 71 | /// - parameters: 72 | /// - expected: The expected state. 73 | /// 74 | /// - returns: 75 | /// `true` if the transition succeeds. `false` otherwise. 76 | @inline(__always) 77 | internal func tryTransiting(from expected: State, to next: State) -> Bool { 78 | return OSAtomicCompareAndSwap32Barrier(expected.rawValue, 79 | next.rawValue, 80 | value) 81 | } 82 | #else 83 | private let value: Atomic 84 | 85 | /// Create a finite state machine with the specified initial state. 86 | /// 87 | /// - parameters: 88 | /// - initial: The desired initial state. 89 | internal init(_ initial: State) { 90 | value = Atomic(initial.rawValue) 91 | } 92 | 93 | /// Deinitialize the finite state machine. 94 | internal func deinitialize() {} 95 | 96 | /// Compare the current state with the specified state. 97 | /// 98 | /// - parameters: 99 | /// - expected: The expected state. 100 | /// 101 | /// - returns: 102 | /// `true` if the current state matches the expected state. `false` 103 | /// otherwise. 104 | internal func `is`(_ expected: State) -> Bool { 105 | return value.modify { $0 == expected.rawValue } 106 | } 107 | 108 | /// Try to transit from the expected current state to the specified next 109 | /// state. 110 | /// 111 | /// - parameters: 112 | /// - expected: The expected state. 113 | /// 114 | /// - returns: 115 | /// `true` if the transition succeeds. `false` otherwise. 116 | internal func tryTransiting(from expected: State, to next: State) -> Bool { 117 | return value.modify { value in 118 | if value == expected.rawValue { 119 | value = next.rawValue 120 | return true 121 | } 122 | return false 123 | } 124 | } 125 | #endif 126 | } 127 | 128 | final class PosixThreadMutex: NSLocking { 129 | private var mutex = pthread_mutex_t() 130 | 131 | init() { 132 | let result = pthread_mutex_init(&mutex, nil) 133 | precondition(result == 0, "Failed to initialize mutex with error \(result).") 134 | } 135 | 136 | deinit { 137 | let result = pthread_mutex_destroy(&mutex) 138 | precondition(result == 0, "Failed to destroy mutex with error \(result).") 139 | } 140 | 141 | func lock() { 142 | let result = pthread_mutex_lock(&mutex) 143 | precondition(result == 0, "Failed to lock \(self) with error \(result).") 144 | } 145 | 146 | func unlock() { 147 | let result = pthread_mutex_unlock(&mutex) 148 | precondition(result == 0, "Failed to unlock \(self) with error \(result).") 149 | } 150 | } 151 | 152 | /// An atomic variable. 153 | public final class Atomic: AtomicProtocol { 154 | private let lock: PosixThreadMutex 155 | private var _value: Value 156 | 157 | /// Initialize the variable with the given initial value. 158 | /// 159 | /// - parameters: 160 | /// - value: Initial value for `self`. 161 | public init(_ value: Value) { 162 | _value = value 163 | lock = PosixThreadMutex() 164 | } 165 | 166 | /// Atomically modifies the variable. 167 | /// 168 | /// - parameters: 169 | /// - action: A closure that takes the current value. 170 | /// 171 | /// - returns: The result of the action. 172 | @discardableResult 173 | public func modify(_ action: (inout Value) throws -> Result) rethrows -> Result { 174 | lock.lock() 175 | defer { lock.unlock() } 176 | 177 | return try action(&_value) 178 | } 179 | 180 | /// Atomically perform an arbitrary action using the current value of the 181 | /// variable. 182 | /// 183 | /// - parameters: 184 | /// - action: A closure that takes the current value. 185 | /// 186 | /// - returns: The result of the action. 187 | @discardableResult 188 | public func withValue(_ action: (Value) throws -> Result) rethrows -> Result { 189 | lock.lock() 190 | defer { lock.unlock() } 191 | 192 | return try action(_value) 193 | } 194 | } 195 | 196 | 197 | /// An atomic variable which uses a recursive lock. 198 | internal final class RecursiveAtomic: AtomicProtocol { 199 | private let lock: NSRecursiveLock 200 | private var _value: Value 201 | private let didSetObserver: ((Value) -> Void)? 202 | 203 | /// Initialize the variable with the given initial value. 204 | /// 205 | /// - parameters: 206 | /// - value: Initial value for `self`. 207 | /// - name: An optional name used to create the recursive lock. 208 | /// - action: An optional closure which would be invoked every time the 209 | /// value of `self` is mutated. 210 | internal init(_ value: Value, name: StaticString? = nil, didSet action: ((Value) -> Void)? = nil) { 211 | _value = value 212 | lock = NSRecursiveLock() 213 | lock.name = name.map(String.init(describing:)) 214 | didSetObserver = action 215 | } 216 | 217 | /// Atomically modifies the variable. 218 | /// 219 | /// - parameters: 220 | /// - action: A closure that takes the current value. 221 | /// 222 | /// - returns: The result of the action. 223 | @discardableResult 224 | func modify(_ action: (inout Value) throws -> Result) rethrows -> Result { 225 | lock.lock() 226 | defer { 227 | didSetObserver?(_value) 228 | lock.unlock() 229 | } 230 | 231 | return try action(&_value) 232 | } 233 | 234 | /// Atomically perform an arbitrary action using the current value of the 235 | /// variable. 236 | /// 237 | /// - parameters: 238 | /// - action: A closure that takes the current value. 239 | /// 240 | /// - returns: The result of the action. 241 | @discardableResult 242 | func withValue(_ action: (Value) throws -> Result) rethrows -> Result { 243 | lock.lock() 244 | defer { lock.unlock() } 245 | 246 | return try action(_value) 247 | } 248 | } 249 | 250 | /// A protocol used to constraint convenience `Atomic` methods and properties. 251 | public protocol AtomicProtocol: class { 252 | associatedtype Value 253 | 254 | @discardableResult 255 | func withValue(_ action: (Value) throws -> Result) rethrows -> Result 256 | 257 | @discardableResult 258 | func modify(_ action: (inout Value) throws -> Result) rethrows -> Result 259 | } 260 | 261 | extension AtomicProtocol { 262 | /// Atomically get or set the value of the variable. 263 | public var value: Value { 264 | get { 265 | return withValue { $0 } 266 | } 267 | 268 | set(newValue) { 269 | swap(newValue) 270 | } 271 | } 272 | 273 | /// Atomically replace the contents of the variable. 274 | /// 275 | /// - parameters: 276 | /// - newValue: A new value for the variable. 277 | /// 278 | /// - returns: The old value. 279 | @discardableResult 280 | public func swap(_ newValue: Value) -> Value { 281 | return modify { (value: inout Value) in 282 | let oldValue = value 283 | value = newValue 284 | return oldValue 285 | } 286 | } 287 | } 288 | -------------------------------------------------------------------------------- /Pods/ReactiveSwift/Sources/Bag.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Bag.swift 3 | // ReactiveSwift 4 | // 5 | // Created by Justin Spahr-Summers on 2014-07-10. 6 | // Copyright (c) 2014 GitHub. All rights reserved. 7 | // 8 | 9 | /// A uniquely identifying token for removing a value that was inserted into a 10 | /// Bag. 11 | public final class RemovalToken {} 12 | 13 | /// An unordered, non-unique collection of values of type `Element`. 14 | public struct Bag { 15 | fileprivate var elements: ContiguousArray> = [] 16 | 17 | public init() {} 18 | 19 | /// Insert the given value into `self`, and return a token that can 20 | /// later be passed to `remove(using:)`. 21 | /// 22 | /// - parameters: 23 | /// - value: A value that will be inserted. 24 | @discardableResult 25 | public mutating func insert(_ value: Element) -> RemovalToken { 26 | let token = RemovalToken() 27 | let element = BagElement(value: value, token: token) 28 | 29 | elements.append(element) 30 | return token 31 | } 32 | 33 | /// Remove a value, given the token returned from `insert()`. 34 | /// 35 | /// - note: If the value has already been removed, nothing happens. 36 | /// 37 | /// - parameters: 38 | /// - token: A token returned from a call to `insert()`. 39 | public mutating func remove(using token: RemovalToken) { 40 | let tokenIdentifier = ObjectIdentifier(token) 41 | // Removal is more likely for recent objects than old ones. 42 | for i in elements.indices.reversed() { 43 | if ObjectIdentifier(elements[i].token) == tokenIdentifier { 44 | elements.remove(at: i) 45 | break 46 | } 47 | } 48 | } 49 | } 50 | 51 | extension Bag: Collection { 52 | public typealias Index = Array.Index 53 | 54 | public var startIndex: Index { 55 | return elements.startIndex 56 | } 57 | 58 | public var endIndex: Index { 59 | return elements.endIndex 60 | } 61 | 62 | public subscript(index: Index) -> Element { 63 | return elements[index].value 64 | } 65 | 66 | public func index(after i: Index) -> Index { 67 | return i + 1 68 | } 69 | 70 | public func makeIterator() -> BagIterator { 71 | return BagIterator(elements) 72 | } 73 | } 74 | 75 | private struct BagElement { 76 | let value: Value 77 | let token: RemovalToken 78 | } 79 | 80 | extension BagElement: CustomStringConvertible { 81 | var description: String { 82 | return "BagElement(\(value))" 83 | } 84 | } 85 | 86 | /// An iterator of `Bag`. 87 | public struct BagIterator: IteratorProtocol { 88 | private let base: ContiguousArray> 89 | private var nextIndex: Int 90 | private let endIndex: Int 91 | 92 | fileprivate init(_ base: ContiguousArray>) { 93 | self.base = base 94 | nextIndex = base.startIndex 95 | endIndex = base.endIndex 96 | } 97 | 98 | public mutating func next() -> Element? { 99 | let currentIndex = nextIndex 100 | 101 | if currentIndex < endIndex { 102 | nextIndex = currentIndex + 1 103 | return base[currentIndex].value 104 | } 105 | 106 | return nil 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /Pods/ReactiveSwift/Sources/Event.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Event.swift 3 | // ReactiveSwift 4 | // 5 | // Created by Justin Spahr-Summers on 2015-01-16. 6 | // Copyright (c) 2015 GitHub. All rights reserved. 7 | // 8 | 9 | /// Represents a signal event. 10 | /// 11 | /// Signals must conform to the grammar: 12 | /// `value* (failed | completed | interrupted)?` 13 | public enum Event { 14 | /// A value provided by the signal. 15 | case value(Value) 16 | 17 | /// The signal terminated because of an error. No further events will be 18 | /// received. 19 | case failed(Error) 20 | 21 | /// The signal successfully terminated. No further events will be received. 22 | case completed 23 | 24 | /// Event production on the signal has been interrupted. No further events 25 | /// will be received. 26 | /// 27 | /// - important: This event does not signify the successful or failed 28 | /// completion of the signal. 29 | case interrupted 30 | 31 | /// Whether this event is a completed event. 32 | public var isCompleted: Bool { 33 | switch self { 34 | case .completed: 35 | return true 36 | 37 | case .value, .failed, .interrupted: 38 | return false 39 | } 40 | } 41 | 42 | /// Whether this event indicates signal termination (i.e., that no further 43 | /// events will be received). 44 | public var isTerminating: Bool { 45 | switch self { 46 | case .value: 47 | return false 48 | 49 | case .failed, .completed, .interrupted: 50 | return true 51 | } 52 | } 53 | 54 | /// Lift the given closure over the event's value. 55 | /// 56 | /// - important: The closure is called only on `value` type events. 57 | /// 58 | /// - parameters: 59 | /// - f: A closure that accepts a value and returns a new value 60 | /// 61 | /// - returns: An event with function applied to a value in case `self` is a 62 | /// `value` type of event. 63 | public func map(_ f: (Value) -> U) -> Event { 64 | switch self { 65 | case let .value(value): 66 | return .value(f(value)) 67 | 68 | case let .failed(error): 69 | return .failed(error) 70 | 71 | case .completed: 72 | return .completed 73 | 74 | case .interrupted: 75 | return .interrupted 76 | } 77 | } 78 | 79 | /// Lift the given closure over the event's error. 80 | /// 81 | /// - important: The closure is called only on failed type event. 82 | /// 83 | /// - parameters: 84 | /// - f: A closure that accepts an error object and returns 85 | /// a new error object 86 | /// 87 | /// - returns: An event with function applied to an error object in case 88 | /// `self` is a `.Failed` type of event. 89 | public func mapError(_ f: (Error) -> F) -> Event { 90 | switch self { 91 | case let .value(value): 92 | return .value(value) 93 | 94 | case let .failed(error): 95 | return .failed(f(error)) 96 | 97 | case .completed: 98 | return .completed 99 | 100 | case .interrupted: 101 | return .interrupted 102 | } 103 | } 104 | 105 | /// Unwrap the contained `value` value. 106 | public var value: Value? { 107 | if case let .value(value) = self { 108 | return value 109 | } else { 110 | return nil 111 | } 112 | } 113 | 114 | /// Unwrap the contained `Error` value. 115 | public var error: Error? { 116 | if case let .failed(error) = self { 117 | return error 118 | } else { 119 | return nil 120 | } 121 | } 122 | } 123 | 124 | public func == (lhs: Event, rhs: Event) -> Bool { 125 | switch (lhs, rhs) { 126 | case let (.value(left), .value(right)): 127 | return left == right 128 | 129 | case let (.failed(left), .failed(right)): 130 | return left == right 131 | 132 | case (.completed, .completed): 133 | return true 134 | 135 | case (.interrupted, .interrupted): 136 | return true 137 | 138 | default: 139 | return false 140 | } 141 | } 142 | 143 | extension Event: CustomStringConvertible { 144 | public var description: String { 145 | switch self { 146 | case let .value(value): 147 | return "VALUE \(value)" 148 | 149 | case let .failed(error): 150 | return "FAILED \(error)" 151 | 152 | case .completed: 153 | return "COMPLETED" 154 | 155 | case .interrupted: 156 | return "INTERRUPTED" 157 | } 158 | } 159 | } 160 | 161 | /// Event protocol for constraining signal extensions 162 | public protocol EventProtocol { 163 | /// The value type of an event. 164 | associatedtype Value 165 | /// The error type of an event. If errors aren't possible then `NoError` can 166 | /// be used. 167 | associatedtype Error: Swift.Error 168 | /// Extracts the event from the receiver. 169 | var event: Event { get } 170 | } 171 | 172 | extension Event: EventProtocol { 173 | public var event: Event { 174 | return self 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /Pods/ReactiveSwift/Sources/EventLogger.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EventLogger.swift 3 | // ReactiveSwift 4 | // 5 | // Created by Rui Peres on 30/04/2016. 6 | // Copyright © 2016 GitHub. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /// A namespace for logging event types. 12 | public enum LoggingEvent { 13 | public enum Signal: String { 14 | case value, completed, failed, terminated, disposed, interrupted 15 | 16 | public static let allEvents: Set = [ 17 | .value, .completed, .failed, .terminated, .disposed, .interrupted, 18 | ] 19 | } 20 | 21 | public enum SignalProducer: String { 22 | case starting, started, value, completed, failed, terminated, disposed, interrupted 23 | 24 | public static let allEvents: Set = [ 25 | .starting, .started, .value, .completed, .failed, .terminated, .disposed, .interrupted, 26 | ] 27 | } 28 | } 29 | 30 | private func defaultEventLog(identifier: String, event: String, fileName: String, functionName: String, lineNumber: Int) { 31 | print("[\(identifier)] \(event) fileName: \(fileName), functionName: \(functionName), lineNumber: \(lineNumber)") 32 | } 33 | 34 | /// A type that represents an event logging function. 35 | public typealias EventLogger = ( 36 | _ identifier: String, 37 | _ event: String, 38 | _ fileName: String, 39 | _ functionName: String, 40 | _ lineNumber: Int 41 | ) -> Void 42 | 43 | extension SignalProtocol { 44 | /// Logs all events that the receiver sends. By default, it will print to 45 | /// the standard output. 46 | /// 47 | /// - parameters: 48 | /// - identifier: a string to identify the Signal firing events. 49 | /// - events: Types of events to log. 50 | /// - fileName: Name of the file containing the code which fired the 51 | /// event. 52 | /// - functionName: Function where event was fired. 53 | /// - lineNumber: Line number where event was fired. 54 | /// - logger: Logger that logs the events. 55 | /// 56 | /// - returns: Signal that, when observed, logs the fired events. 57 | public func logEvents(identifier: String = "", events: Set = LoggingEvent.Signal.allEvents, fileName: String = #file, functionName: String = #function, lineNumber: Int = #line, logger: @escaping EventLogger = defaultEventLog) -> Signal { 58 | func log(_ event: LoggingEvent.Signal) -> ((T) -> Void)? { 59 | return event.logIfNeeded(events: events) { event in 60 | logger(identifier, event, fileName, functionName, lineNumber) 61 | } 62 | } 63 | 64 | return self.on( 65 | failed: log(.failed), 66 | completed: log(.completed), 67 | interrupted: log(.interrupted), 68 | terminated: log(.terminated), 69 | disposed: log(.disposed), 70 | value: log(.value) 71 | ) 72 | } 73 | } 74 | 75 | extension SignalProducerProtocol { 76 | /// Logs all events that the receiver sends. By default, it will print to 77 | /// the standard output. 78 | /// 79 | /// - parameters: 80 | /// - identifier: a string to identify the SignalProducer firing events. 81 | /// - events: Types of events to log. 82 | /// - fileName: Name of the file containing the code which fired the 83 | /// event. 84 | /// - functionName: Function where event was fired. 85 | /// - lineNumber: Line number where event was fired. 86 | /// - logger: Logger that logs the events. 87 | /// 88 | /// - returns: Signal producer that, when started, logs the fired events. 89 | public func logEvents(identifier: String = "", 90 | events: Set = LoggingEvent.SignalProducer.allEvents, 91 | fileName: String = #file, 92 | functionName: String = #function, 93 | lineNumber: Int = #line, 94 | logger: @escaping EventLogger = defaultEventLog 95 | ) -> SignalProducer { 96 | func log(_ event: LoggingEvent.SignalProducer) -> ((T) -> Void)? { 97 | return event.logIfNeeded(events: events) { event in 98 | logger(identifier, event, fileName, functionName, lineNumber) 99 | } 100 | } 101 | 102 | return self.on( 103 | starting: log(.starting), 104 | started: log(.started), 105 | failed: log(.failed), 106 | completed: log(.completed), 107 | interrupted: log(.interrupted), 108 | terminated: log(.terminated), 109 | disposed: log(.disposed), 110 | value: log(.value) 111 | ) 112 | } 113 | } 114 | 115 | private protocol LoggingEventProtocol: Hashable, RawRepresentable {} 116 | extension LoggingEvent.Signal: LoggingEventProtocol {} 117 | extension LoggingEvent.SignalProducer: LoggingEventProtocol {} 118 | 119 | private extension LoggingEventProtocol { 120 | func logIfNeeded(events: Set, logger: @escaping (String) -> Void) -> ((T) -> Void)? { 121 | guard events.contains(self) else { 122 | return nil 123 | } 124 | 125 | return { value in 126 | if value is Void { 127 | logger("\(self.rawValue)") 128 | } else { 129 | logger("\(self.rawValue) \(value)") 130 | } 131 | } 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /Pods/ReactiveSwift/Sources/FoundationExtensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FoundationExtensions.swift 3 | // ReactiveSwift 4 | // 5 | // Created by Justin Spahr-Summers on 2014-10-19. 6 | // Copyright (c) 2014 GitHub. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Dispatch 11 | import enum Result.NoError 12 | import struct Result.AnyError 13 | 14 | #if os(Linux) 15 | import let CDispatch.NSEC_PER_USEC 16 | import let CDispatch.NSEC_PER_SEC 17 | #endif 18 | 19 | extension NotificationCenter: ReactiveExtensionsProvider {} 20 | 21 | extension Reactive where Base: NotificationCenter { 22 | /// Returns a Signal to observe posting of the specified notification. 23 | /// 24 | /// - parameters: 25 | /// - name: name of the notification to observe 26 | /// - object: an instance which sends the notifications 27 | /// 28 | /// - returns: A Signal of notifications posted that match the given criteria. 29 | /// 30 | /// - note: The signal does not terminate naturally. Observers must be 31 | /// explicitly disposed to avoid leaks. 32 | public func notifications(forName name: Notification.Name?, object: AnyObject? = nil) -> Signal { 33 | return Signal { [base = self.base] observer in 34 | let notificationObserver = base.addObserver(forName: name, object: object, queue: nil) { notification in 35 | observer.send(value: notification) 36 | } 37 | 38 | return ActionDisposable { 39 | base.removeObserver(notificationObserver) 40 | } 41 | } 42 | } 43 | } 44 | 45 | private let defaultSessionError = NSError(domain: "org.reactivecocoa.ReactiveSwift.Reactivity.URLSession.dataWithRequest", 46 | code: 1, 47 | userInfo: nil) 48 | 49 | extension URLSession: ReactiveExtensionsProvider {} 50 | 51 | extension Reactive where Base: URLSession { 52 | /// Returns a SignalProducer which performs the work associated with an 53 | /// `NSURLSession` 54 | /// 55 | /// - parameters: 56 | /// - request: A request that will be performed when the producer is 57 | /// started 58 | /// 59 | /// - returns: A producer that will execute the given request once for each 60 | /// invocation of `start()`. 61 | /// 62 | /// - note: This method will not send an error event in the case of a server 63 | /// side error (i.e. when a response with status code other than 64 | /// 200...299 is received). 65 | public func data(with request: URLRequest) -> SignalProducer<(Data, URLResponse), AnyError> { 66 | return SignalProducer { [base = self.base] observer, disposable in 67 | let task = base.dataTask(with: request) { data, response, error in 68 | if let data = data, let response = response { 69 | observer.send(value: (data, response)) 70 | observer.sendCompleted() 71 | } else { 72 | observer.send(error: AnyError(error ?? defaultSessionError)) 73 | } 74 | } 75 | 76 | disposable += { 77 | task.cancel() 78 | } 79 | task.resume() 80 | } 81 | } 82 | } 83 | 84 | extension Date { 85 | internal func addingTimeInterval(_ interval: DispatchTimeInterval) -> Date { 86 | return addingTimeInterval(interval.timeInterval) 87 | } 88 | } 89 | 90 | extension DispatchTimeInterval { 91 | internal var timeInterval: TimeInterval { 92 | switch self { 93 | case let .seconds(s): 94 | return TimeInterval(s) 95 | case let .milliseconds(ms): 96 | return TimeInterval(TimeInterval(ms) / 1000.0) 97 | case let .microseconds(us): 98 | return TimeInterval( UInt64(us) * NSEC_PER_USEC ) / TimeInterval(NSEC_PER_SEC) 99 | case let .nanoseconds(ns): 100 | return TimeInterval(ns) / TimeInterval(NSEC_PER_SEC) 101 | } 102 | } 103 | 104 | // This was added purely so that our test scheduler to "go backwards" in 105 | // time. See `TestScheduler.rewind(by interval: DispatchTimeInterval)`. 106 | internal static prefix func -(lhs: DispatchTimeInterval) -> DispatchTimeInterval { 107 | switch lhs { 108 | case let .seconds(s): 109 | return .seconds(-s) 110 | case let .milliseconds(ms): 111 | return .milliseconds(-ms) 112 | case let .microseconds(us): 113 | return .microseconds(-us) 114 | case let .nanoseconds(ns): 115 | return .nanoseconds(-ns) 116 | } 117 | } 118 | 119 | /// Scales a time interval by the given scalar specified in `rhs`. 120 | /// 121 | /// - note: This method is only used internally to "scale down" a time 122 | /// interval. Specifically it's used only to scale intervals to 10% 123 | /// of their original value for the default `leeway` parameter in 124 | /// `SchedulerProtocol.schedule(after:action:)` schedule and similar 125 | /// other methods. 126 | /// 127 | /// If seconds is over 200,000, 10% is ~2,000, and hence we end up 128 | /// with a value of ~2,000,000,000. Not quite overflowing a signed 129 | /// integer on 32-bit platforms, but close. 130 | /// 131 | /// Even still, 200,000 seconds should be a rarely (if ever) 132 | /// specified interval for our APIs. And even then, folks should be 133 | /// smart and specify their own `leeway` parameter. 134 | /// 135 | /// - returns: Scaled interval in microseconds 136 | internal static func *(lhs: DispatchTimeInterval, rhs: Double) -> DispatchTimeInterval { 137 | let seconds = lhs.timeInterval * rhs 138 | return .microseconds(Int(seconds * 1000 * 1000)) 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /Pods/ReactiveSwift/Sources/Lifetime.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import enum Result.NoError 3 | 4 | /// Represents the lifetime of an object, and provides a hook to observe when 5 | /// the object deinitializes. 6 | public final class Lifetime { 7 | /// MARK: Type properties and methods 8 | 9 | /// A `Lifetime` that has already ended. 10 | public static var empty: Lifetime { 11 | return Lifetime(ended: .empty) 12 | } 13 | 14 | /// MARK: Instance properties 15 | 16 | /// A signal that sends a `completed` event when the lifetime ends. 17 | public let ended: Signal<(), NoError> 18 | 19 | /// MARK: Initializers 20 | 21 | /// Initialize a `Lifetime` object with the supplied ended signal. 22 | /// 23 | /// - parameters: 24 | /// - signal: The ended signal. 25 | private init(ended signal: Signal<(), NoError>) { 26 | ended = signal 27 | } 28 | 29 | /// Initialize a `Lifetime` from a lifetime token, which is expected to be 30 | /// associated with an object. 31 | /// 32 | /// - important: The resulting lifetime object does not retain the lifetime 33 | /// token. 34 | /// 35 | /// - parameters: 36 | /// - token: A lifetime token for detecting the deinitialization of the 37 | /// associated object. 38 | public convenience init(_ token: Token) { 39 | self.init(ended: token.ended) 40 | } 41 | 42 | /// A token object which completes its signal when it deinitializes. 43 | /// 44 | /// It is generally used in conjuncion with `Lifetime` as a private 45 | /// deinitialization trigger. 46 | /// 47 | /// ``` 48 | /// class MyController { 49 | /// private let token = Lifetime.Token() 50 | /// public var lifetime: Lifetime { 51 | /// return Lifetime(token) 52 | /// } 53 | /// } 54 | /// ``` 55 | public final class Token { 56 | /// A signal that sends a Completed event when the lifetime ends. 57 | fileprivate let ended: Signal<(), NoError> 58 | 59 | private let endedObserver: Signal<(), NoError>.Observer 60 | 61 | public init() { 62 | (ended, endedObserver) = Signal.pipe() 63 | } 64 | 65 | deinit { 66 | endedObserver.sendCompleted() 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Pods/ReactiveSwift/Sources/Observer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Observer.swift 3 | // ReactiveSwift 4 | // 5 | // Created by Andy Matuschak on 10/2/15. 6 | // Copyright © 2015 GitHub. All rights reserved. 7 | // 8 | 9 | /// A protocol for type-constrained extensions of `Observer`. 10 | public protocol ObserverProtocol { 11 | associatedtype Value 12 | associatedtype Error: Swift.Error 13 | 14 | /// Puts a `value` event into `self`. 15 | func send(value: Value) 16 | 17 | /// Puts a failed event into `self`. 18 | func send(error: Error) 19 | 20 | /// Puts a `completed` event into `self`. 21 | func sendCompleted() 22 | 23 | /// Puts an `interrupted` event into `self`. 24 | func sendInterrupted() 25 | } 26 | 27 | /// An Observer is a simple wrapper around a function which can receive Events 28 | /// (typically from a Signal). 29 | public final class Observer { 30 | public typealias Action = (Event) -> Void 31 | 32 | /// An action that will be performed upon arrival of the event. 33 | public let action: Action 34 | 35 | /// An initializer that accepts a closure accepting an event for the 36 | /// observer. 37 | /// 38 | /// - parameters: 39 | /// - action: A closure to lift over received event. 40 | public init(_ action: @escaping Action) { 41 | self.action = action 42 | } 43 | 44 | /// An initializer that accepts closures for different event types. 45 | /// 46 | /// - parameters: 47 | /// - value: Optional closure executed when a `value` event is observed. 48 | /// - failed: Optional closure that accepts an `Error` parameter when a 49 | /// failed event is observed. 50 | /// - completed: Optional closure executed when a `completed` event is 51 | /// observed. 52 | /// - interruped: Optional closure executed when an `interrupted` event is 53 | /// observed. 54 | public convenience init( 55 | value: ((Value) -> Void)? = nil, 56 | failed: ((Error) -> Void)? = nil, 57 | completed: (() -> Void)? = nil, 58 | interrupted: (() -> Void)? = nil 59 | ) { 60 | self.init { event in 61 | switch event { 62 | case let .value(v): 63 | value?(v) 64 | 65 | case let .failed(error): 66 | failed?(error) 67 | 68 | case .completed: 69 | completed?() 70 | 71 | case .interrupted: 72 | interrupted?() 73 | } 74 | } 75 | } 76 | } 77 | 78 | extension Observer: ObserverProtocol { 79 | /// Puts a `value` event into `self`. 80 | /// 81 | /// - parameters: 82 | /// - value: A value sent with the `value` event. 83 | public func send(value: Value) { 84 | action(.value(value)) 85 | } 86 | 87 | /// Puts a failed event into `self`. 88 | /// 89 | /// - parameters: 90 | /// - error: An error object sent with failed event. 91 | public func send(error: Error) { 92 | action(.failed(error)) 93 | } 94 | 95 | /// Puts a `completed` event into `self`. 96 | public func sendCompleted() { 97 | action(.completed) 98 | } 99 | 100 | /// Puts an `interrupted` event into `self`. 101 | public func sendInterrupted() { 102 | action(.interrupted) 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /Pods/ReactiveSwift/Sources/Optional.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Optional.swift 3 | // ReactiveSwift 4 | // 5 | // Created by Neil Pankey on 6/24/15. 6 | // Copyright (c) 2015 GitHub. All rights reserved. 7 | // 8 | 9 | /// An optional protocol for use in type constraints. 10 | public protocol OptionalProtocol { 11 | /// The type contained in the otpional. 12 | associatedtype Wrapped 13 | 14 | init(reconstructing value: Wrapped?) 15 | 16 | /// Extracts an optional from the receiver. 17 | var optional: Wrapped? { get } 18 | } 19 | 20 | extension Optional: OptionalProtocol { 21 | public var optional: Wrapped? { 22 | return self 23 | } 24 | 25 | public init(reconstructing value: Wrapped?) { 26 | self = value 27 | } 28 | } 29 | 30 | extension SignalProtocol { 31 | /// Turns each value into an Optional. 32 | internal func optionalize() -> Signal { 33 | return map(Optional.init) 34 | } 35 | } 36 | 37 | extension SignalProducerProtocol { 38 | /// Turns each value into an Optional. 39 | internal func optionalize() -> SignalProducer { 40 | return lift { $0.optionalize() } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Pods/ReactiveSwift/Sources/Reactive.swift: -------------------------------------------------------------------------------- 1 | /// Describes a provider of reactive extensions. 2 | /// 3 | /// - note: `ReactiveExtensionsProvider` does not indicate whether a type is 4 | /// reactive. It is intended for extensions to types that are not owned 5 | /// by the module in order to avoid name collisions and return type 6 | /// ambiguities. 7 | public protocol ReactiveExtensionsProvider: class {} 8 | 9 | extension ReactiveExtensionsProvider { 10 | /// A proxy which hosts reactive extensions for `self`. 11 | public var reactive: Reactive { 12 | return Reactive(self) 13 | } 14 | 15 | /// A proxy which hosts static reactive extensions for the type of `self`. 16 | public static var reactive: Reactive.Type { 17 | return Reactive.self 18 | } 19 | } 20 | 21 | /// A proxy which hosts reactive extensions of `Base`. 22 | public struct Reactive { 23 | /// The `Base` instance the extensions would be invoked with. 24 | public let base: Base 25 | 26 | // Construct a proxy. 27 | // 28 | // - parameters: 29 | // - base: The object to be proxied. 30 | fileprivate init(_ base: Base) { 31 | self.base = base 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Pods/ReactiveSwift/Sources/ResultExtensions.swift: -------------------------------------------------------------------------------- 1 | import Result 2 | 3 | /// Private alias of the free `materialize()` from `Result`. 4 | /// 5 | /// This exists because within a `Signal` or `SignalProducer` operator, 6 | /// `materialize()` refers to the operator with that name. 7 | /// Namespacing as `Result.materialize()` doesn't work either, 8 | /// because it tries to resolve a static member on the _type_ 9 | /// `Result`, rather than the free function in the _module_ 10 | /// of the same name. 11 | internal func materialize(_ f: () throws -> T) -> Result { 12 | return materialize(try f()) 13 | } 14 | -------------------------------------------------------------------------------- /Pods/ReactiveSwift/Sources/TupleExtensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TupleExtensions.swift 3 | // ReactiveSwift 4 | // 5 | // Created by Justin Spahr-Summers on 2014-12-20. 6 | // Copyright (c) 2014 GitHub. All rights reserved. 7 | // 8 | 9 | /// Adds a value into an N-tuple, returning an (N+1)-tuple. 10 | /// 11 | /// Supports creating tuples up to 10 elements long. 12 | internal func repack(_ t: (A, B), value: C) -> (A, B, C) { 13 | return (t.0, t.1, value) 14 | } 15 | 16 | internal func repack(_ t: (A, B, C), value: D) -> (A, B, C, D) { 17 | return (t.0, t.1, t.2, value) 18 | } 19 | 20 | internal func repack(_ t: (A, B, C, D), value: E) -> (A, B, C, D, E) { 21 | return (t.0, t.1, t.2, t.3, value) 22 | } 23 | 24 | internal func repack(_ t: (A, B, C, D, E), value: F) -> (A, B, C, D, E, F) { 25 | return (t.0, t.1, t.2, t.3, t.4, value) 26 | } 27 | 28 | internal func repack(_ t: (A, B, C, D, E, F), value: G) -> (A, B, C, D, E, F, G) { 29 | return (t.0, t.1, t.2, t.3, t.4, t.5, value) 30 | } 31 | 32 | internal func repack(_ t: (A, B, C, D, E, F, G), value: H) -> (A, B, C, D, E, F, G, H) { 33 | return (t.0, t.1, t.2, t.3, t.4, t.5, t.6, value) 34 | } 35 | 36 | internal func repack(_ t: (A, B, C, D, E, F, G, H), value: I) -> (A, B, C, D, E, F, G, H, I) { 37 | return (t.0, t.1, t.2, t.3, t.4, t.5, t.6, t.7, value) 38 | } 39 | 40 | internal func repack(_ t: (A, B, C, D, E, F, G, H, I), value: J) -> (A, B, C, D, E, F, G, H, I, J) { 41 | return (t.0, t.1, t.2, t.3, t.4, t.5, t.6, t.7, t.8, value) 42 | } 43 | -------------------------------------------------------------------------------- /Pods/ReactiveSwift/Sources/UnidirectionalBinding.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import Dispatch 3 | import enum Result.NoError 4 | 5 | precedencegroup BindingPrecedence { 6 | associativity: right 7 | 8 | // Binds tighter than assignment but looser than everything else 9 | higherThan: AssignmentPrecedence 10 | } 11 | 12 | infix operator <~ : BindingPrecedence 13 | 14 | /// Describes a source which can be bound. 15 | public protocol BindingSourceProtocol { 16 | associatedtype Value 17 | associatedtype Error: Swift.Error 18 | 19 | /// Observe the binding source by sending any events to the given observer. 20 | @discardableResult 21 | func observe(_ observer: Observer, during lifetime: Lifetime) -> Disposable? 22 | } 23 | 24 | extension Signal: BindingSourceProtocol { 25 | @discardableResult 26 | public func observe(_ observer: Observer, during lifetime: Lifetime) -> Disposable? { 27 | return self.take(during: lifetime).observe(observer) 28 | } 29 | } 30 | 31 | extension SignalProducer: BindingSourceProtocol { 32 | @discardableResult 33 | public func observe(_ observer: ProducedSignal.Observer, during lifetime: Lifetime) -> Disposable? { 34 | var disposable: Disposable! 35 | 36 | self 37 | .take(during: lifetime) 38 | .startWithSignal { signal, signalDisposable in 39 | disposable = signalDisposable 40 | signal.observe(observer) 41 | } 42 | 43 | return disposable 44 | } 45 | } 46 | 47 | /// Describes a target which can be bound. 48 | public protocol BindingTargetProtocol: class { 49 | associatedtype Value 50 | 51 | /// The lifetime of `self`. The binding operators use this to determine when 52 | /// the binding should be torn down. 53 | var lifetime: Lifetime { get } 54 | 55 | /// Consume a value from the binding. 56 | func consume(_ value: Value) 57 | } 58 | 59 | /// Binds a source to a target, updating the target's value to the latest 60 | /// value sent by the source. 61 | /// 62 | /// - note: The binding will automatically terminate when the target is 63 | /// deinitialized, or when the source sends a `completed` event. 64 | /// 65 | /// ```` 66 | /// let property = MutableProperty(0) 67 | /// let signal = Signal({ /* do some work after some time */ }) 68 | /// property <~ signal 69 | /// ```` 70 | /// 71 | /// ```` 72 | /// let property = MutableProperty(0) 73 | /// let signal = Signal({ /* do some work after some time */ }) 74 | /// let disposable = property <~ signal 75 | /// ... 76 | /// // Terminates binding before property dealloc or signal's 77 | /// // `completed` event. 78 | /// disposable.dispose() 79 | /// ```` 80 | /// 81 | /// - parameters: 82 | /// - target: A target to be bond to. 83 | /// - source: A source to bind. 84 | /// 85 | /// - returns: A disposable that can be used to terminate binding before the 86 | /// deinitialization of the target or the source's `completed` 87 | /// event. 88 | @discardableResult 89 | public func <~ 90 | 91 | (target: Target, source: Source) -> Disposable? 92 | where Source.Value == Target.Value, Source.Error == NoError 93 | { 94 | // Alter the semantics of `BindingTarget` to not require it to be retained. 95 | // This is done here--and not in a separate function--so that all variants 96 | // of `<~` can get this behavior. 97 | let observer: Observer 98 | if let target = target as? BindingTarget { 99 | observer = Observer(value: { [setter = target.setter] in setter($0) }) 100 | } else { 101 | observer = Observer(value: { [weak target] in target?.consume($0) }) 102 | } 103 | 104 | return source.observe(observer, during: target.lifetime) 105 | } 106 | 107 | /// Binds a source to a target, updating the target's value to the latest 108 | /// value sent by the source. 109 | /// 110 | /// - note: The binding will automatically terminate when the target is 111 | /// deinitialized, or when the source sends a `completed` event. 112 | /// 113 | /// ```` 114 | /// let property = MutableProperty(0) 115 | /// let signal = Signal({ /* do some work after some time */ }) 116 | /// property <~ signal 117 | /// ```` 118 | /// 119 | /// ```` 120 | /// let property = MutableProperty(0) 121 | /// let signal = Signal({ /* do some work after some time */ }) 122 | /// let disposable = property <~ signal 123 | /// ... 124 | /// // Terminates binding before property dealloc or signal's 125 | /// // `completed` event. 126 | /// disposable.dispose() 127 | /// ```` 128 | /// 129 | /// - parameters: 130 | /// - target: A target to be bond to. 131 | /// - source: A source to bind. 132 | /// 133 | /// - returns: A disposable that can be used to terminate binding before the 134 | /// deinitialization of the target or the source's `completed` 135 | /// event. 136 | @discardableResult 137 | public func <~ 138 | 139 | (target: Target, source: Source) -> Disposable? 140 | where Target.Value: OptionalProtocol, Source.Value == Target.Value.Wrapped, Source.Error == NoError 141 | { 142 | // Alter the semantics of `BindingTarget` to not require it to be retained. 143 | // This is done here--and not in a separate function--so that all variants 144 | // of `<~` can get this behavior. 145 | let observer: Observer 146 | if let target = target as? BindingTarget { 147 | observer = Observer(value: { [setter = target.setter] in setter(Target.Value(reconstructing: $0)) }) 148 | } else { 149 | observer = Observer(value: { [weak target] in target?.consume(Target.Value(reconstructing: $0)) }) 150 | } 151 | 152 | return source.observe(observer, during: target.lifetime) 153 | } 154 | 155 | /// A binding target that can be used with the `<~` operator. 156 | public final class BindingTarget: BindingTargetProtocol { 157 | public let lifetime: Lifetime 158 | fileprivate let setter: (Value) -> Void 159 | 160 | /// Creates a binding target. 161 | /// 162 | /// - parameters: 163 | /// - lifetime: The expected lifetime of any bindings towards `self`. 164 | /// - setter: The action to consume values. 165 | public init(lifetime: Lifetime, setter: @escaping (Value) -> Void) { 166 | self.setter = setter 167 | self.lifetime = lifetime 168 | } 169 | 170 | /// Creates a binding target which consumes values on the specified scheduler. 171 | /// 172 | /// - parameters: 173 | /// - scheduler: The scheduler on which the `setter` consumes the values. 174 | /// - lifetime: The expected lifetime of any bindings towards `self`. 175 | /// - setter: The action to consume values. 176 | public convenience init(on scheduler: SchedulerProtocol, lifetime: Lifetime, setter: @escaping (Value) -> Void) { 177 | let setter: (Value) -> Void = { value in 178 | scheduler.schedule { 179 | setter(value) 180 | } 181 | } 182 | self.init(lifetime: lifetime, setter: setter) 183 | } 184 | 185 | public func consume(_ value: Value) { 186 | setter(value) 187 | } 188 | } 189 | -------------------------------------------------------------------------------- /Pods/Result/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Rob Rix 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /Pods/Result/README.md: -------------------------------------------------------------------------------- 1 | # Result 2 | 3 | [![Build Status](https://travis-ci.org/antitypical/Result.svg?branch=master)](https://travis-ci.org/antitypical/Result) 4 | [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) 5 | [![CocoaPods](https://img.shields.io/cocoapods/v/Result.svg)](https://cocoapods.org/) 6 | [![Reference Status](https://www.versioneye.com/objective-c/result/reference_badge.svg?style=flat)](https://www.versioneye.com/objective-c/result/references) 7 | 8 | This is a Swift µframework providing `Result`. 9 | 10 | `Result` values are either successful (wrapping `Value`) or failed (wrapping `Error`). This is similar to Swift’s native `Optional` type: `success` is like `some`, and `failure` is like `none` except with an associated `Error` value. The addition of an associated `Error` allows errors to be passed along for logging or displaying to the user. 11 | 12 | Using this µframework instead of rolling your own `Result` type allows you to easily interface with other frameworks that also use `Result`. 13 | 14 | ## Use 15 | 16 | Use `Result` whenever an operation has the possibility of failure. Consider the following example of a function that tries to extract a `String` for a given key from a JSON `Dictionary`. 17 | 18 | ```swift 19 | typealias JSONObject = [String: Any] 20 | 21 | enum JSONError: Error { 22 | case noSuchKey(String) 23 | case typeMismatch 24 | } 25 | 26 | func stringForKey(json: JSONObject, key: String) -> Result { 27 | guard let value = json[key] else { 28 | return .failure(.noSuchKey(key)) 29 | } 30 | 31 | if let value = value as? String { 32 | return .success(value) 33 | } 34 | else { 35 | return .failure(.typeMismatch) 36 | } 37 | } 38 | ``` 39 | 40 | This function provides a more robust wrapper around the default subscripting provided by `Dictionary`. Rather than return `Any?`, it returns a `Result` that either contains the `String` value for the given key, or an `ErrorType` detailing what went wrong. 41 | 42 | One simple way to handle a `Result` is to deconstruct it using a `switch` statement. 43 | 44 | ```swift 45 | switch stringForKey(json, key: "email") { 46 | 47 | case let .success(email): 48 | print("The email is \(email)") 49 | 50 | case let .failure(.noSuchKey(key)): 51 | print("\(key) is not a valid key") 52 | 53 | case .failure(.typeMismatch): 54 | print("Didn't have the right type") 55 | } 56 | ``` 57 | 58 | Using a `switch` statement allows powerful pattern matching, and ensures all possible results are covered. Swift 2.0 offers new ways to deconstruct enums like the `if-case` statement, but be wary as such methods do not ensure errors are handled. 59 | 60 | Other methods available for processing `Result` are detailed in the [API documentation](http://cocoadocs.org/docsets/Result/). 61 | 62 | ## Result vs. Throws 63 | 64 | Swift 2.0 introduces error handling via throwing and catching `Error`. `Result` accomplishes the same goal by encapsulating the result instead of hijacking control flow. The `Result` abstraction enables powerful functionality such as `map` and `flatMap`, making `Result` more composable than `throw`. 65 | 66 | Since dealing with APIs that throw is common, you can convert such functions into a `Result` by using the `materialize` method. Conversely, a `Result` can be used to throw an error by calling `dematerialize`. 67 | 68 | ## Higher Order Functions 69 | 70 | `map` and `flatMap` operate the same as `Optional.map` and `Optional.flatMap` except they apply to `Result`. 71 | 72 | `map` transforms a `Result` into a `Result` of a new type. It does this by taking a function that transforms the `Value` type into a new value. This transformation is only applied in the case of a `success`. In the case of a `failure`, the associated error is re-wrapped in the new `Result`. 73 | 74 | ```swift 75 | // transforms a Result to a Result 76 | let idResult = intForKey(json, key:"id").map { id in String(id) } 77 | ``` 78 | 79 | Here, the final result is either the id as a `String`, or carries over the `failure` from the previous result. 80 | 81 | `flatMap` is similar to `map` in that in transforms the `Result` into another `Result`. However, the function passed into `flatMap` must return a `Result`. 82 | 83 | An in depth discussion of `map` and `flatMap` is beyond the scope of this documentation. If you would like a deeper understanding, read about functors and monads. This article is a good place to [start](http://www.javiersoto.me/post/106875422394). 84 | 85 | ## Integration 86 | 87 | ### Carthage 88 | 89 | 1. Add this repository as a submodule and/or [add it to your Cartfile](https://github.com/Carthage/Carthage/blob/master/Documentation/Artifacts.md#cartfile) if you’re using [carthage](https://github.com/Carthage/Carthage/) to manage your dependencies. 90 | 2. Drag `Result.xcodeproj` into your project or workspace. 91 | 3. Link your target against `Result.framework`. 92 | 4. Application targets should ensure that the framework gets copied into their application bundle. (Framework targets should instead require the application linking them to include Result.) 93 | 94 | ### Cocoapods 95 | 96 | ```ruby 97 | pod 'Result', '~> 3.0.0' 98 | ``` 99 | 100 | ### Swift Package Manager 101 | 102 | ```swift 103 | import PackageDescription 104 | 105 | let package = Package( 106 | name: "MyProject", 107 | targets: [], 108 | dependencies: [ 109 | .Package(url: "https://github.com/antitypical/Result.git", 110 | majorVersion: 3) 111 | ] 112 | ) 113 | ``` 114 | -------------------------------------------------------------------------------- /Pods/Result/Result/Result.swift: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Rob Rix. All rights reserved. 2 | 3 | /// An enum representing either a failure with an explanatory error, or a success with a result value. 4 | public enum Result: ResultProtocol, CustomStringConvertible, CustomDebugStringConvertible { 5 | case success(T) 6 | case failure(Error) 7 | 8 | // MARK: Constructors 9 | 10 | /// Constructs a success wrapping a `value`. 11 | public init(value: T) { 12 | self = .success(value) 13 | } 14 | 15 | /// Constructs a failure wrapping an `error`. 16 | public init(error: Error) { 17 | self = .failure(error) 18 | } 19 | 20 | /// Constructs a result from an `Optional`, failing with `Error` if `nil`. 21 | public init(_ value: T?, failWith: @autoclosure () -> Error) { 22 | self = value.map(Result.success) ?? .failure(failWith()) 23 | } 24 | 25 | /// Constructs a result from a function that uses `throw`, failing with `Error` if throws. 26 | public init(_ f: @autoclosure () throws -> T) { 27 | self.init(attempt: f) 28 | } 29 | 30 | /// Constructs a result from a function that uses `throw`, failing with `Error` if throws. 31 | public init(attempt f: () throws -> T) { 32 | do { 33 | self = .success(try f()) 34 | } catch { 35 | self = .failure(error as! Error) 36 | } 37 | } 38 | 39 | // MARK: Deconstruction 40 | 41 | /// Returns the value from `success` Results or `throw`s the error. 42 | public func dematerialize() throws -> T { 43 | switch self { 44 | case let .success(value): 45 | return value 46 | case let .failure(error): 47 | throw error 48 | } 49 | } 50 | 51 | /// Case analysis for Result. 52 | /// 53 | /// Returns the value produced by applying `ifFailure` to `failure` Results, or `ifSuccess` to `success` Results. 54 | public func analysis(ifSuccess: (T) -> Result, ifFailure: (Error) -> Result) -> Result { 55 | switch self { 56 | case let .success(value): 57 | return ifSuccess(value) 58 | case let .failure(value): 59 | return ifFailure(value) 60 | } 61 | } 62 | 63 | // MARK: Errors 64 | 65 | /// The domain for errors constructed by Result. 66 | public static var errorDomain: String { return "com.antitypical.Result" } 67 | 68 | /// The userInfo key for source functions in errors constructed by Result. 69 | public static var functionKey: String { return "\(errorDomain).function" } 70 | 71 | /// The userInfo key for source file paths in errors constructed by Result. 72 | public static var fileKey: String { return "\(errorDomain).file" } 73 | 74 | /// The userInfo key for source file line numbers in errors constructed by Result. 75 | public static var lineKey: String { return "\(errorDomain).line" } 76 | 77 | /// Constructs an error. 78 | public static func error(_ message: String? = nil, function: String = #function, file: String = #file, line: Int = #line) -> NSError { 79 | var userInfo: [String: Any] = [ 80 | functionKey: function, 81 | fileKey: file, 82 | lineKey: line, 83 | ] 84 | 85 | if let message = message { 86 | userInfo[NSLocalizedDescriptionKey] = message 87 | } 88 | 89 | return NSError(domain: errorDomain, code: 0, userInfo: userInfo) 90 | } 91 | 92 | 93 | // MARK: CustomStringConvertible 94 | 95 | public var description: String { 96 | return analysis( 97 | ifSuccess: { ".success(\($0))" }, 98 | ifFailure: { ".failure(\($0))" }) 99 | } 100 | 101 | 102 | // MARK: CustomDebugStringConvertible 103 | 104 | public var debugDescription: String { 105 | return description 106 | } 107 | } 108 | 109 | // MARK: - Derive result from failable closure 110 | 111 | public func materialize(_ f: () throws -> T) -> Result { 112 | return materialize(try f()) 113 | } 114 | 115 | public func materialize(_ f: @autoclosure () throws -> T) -> Result { 116 | do { 117 | return .success(try f()) 118 | } catch { 119 | return .failure(AnyError(error)) 120 | } 121 | } 122 | 123 | @available(*, deprecated, message: "Use the overload which returns `Result` instead") 124 | public func materialize(_ f: () throws -> T) -> Result { 125 | return materialize(try f()) 126 | } 127 | 128 | @available(*, deprecated, message: "Use the overload which returns `Result` instead") 129 | public func materialize(_ f: @autoclosure () throws -> T) -> Result { 130 | do { 131 | return .success(try f()) 132 | } catch let error as NSError { 133 | return .failure(error) 134 | } 135 | } 136 | 137 | // MARK: - Cocoa API conveniences 138 | 139 | #if !os(Linux) 140 | 141 | /// Constructs a `Result` with the result of calling `try` with an error pointer. 142 | /// 143 | /// This is convenient for wrapping Cocoa API which returns an object or `nil` + an error, by reference. e.g.: 144 | /// 145 | /// Result.try { NSData(contentsOfURL: URL, options: .dataReadingMapped, error: $0) } 146 | public func `try`(_ function: String = #function, file: String = #file, line: Int = #line, `try`: (NSErrorPointer) -> T?) -> Result { 147 | var error: NSError? 148 | return `try`(&error).map(Result.success) ?? .failure(error ?? Result.error(function: function, file: file, line: line)) 149 | } 150 | 151 | /// Constructs a `Result` with the result of calling `try` with an error pointer. 152 | /// 153 | /// This is convenient for wrapping Cocoa API which returns a `Bool` + an error, by reference. e.g.: 154 | /// 155 | /// Result.try { NSFileManager.defaultManager().removeItemAtURL(URL, error: $0) } 156 | public func `try`(_ function: String = #function, file: String = #file, line: Int = #line, `try`: (NSErrorPointer) -> Bool) -> Result<(), NSError> { 157 | var error: NSError? 158 | return `try`(&error) ? 159 | .success(()) 160 | : .failure(error ?? Result<(), NSError>.error(function: function, file: file, line: line)) 161 | } 162 | 163 | #endif 164 | 165 | // MARK: - ErrorProtocolConvertible conformance 166 | 167 | extension NSError: ErrorProtocolConvertible { 168 | public static func error(from error: Swift.Error) -> Self { 169 | func cast(_ error: Swift.Error) -> T { 170 | return error as! T 171 | } 172 | 173 | return cast(error) 174 | } 175 | } 176 | 177 | // MARK: - Errors 178 | 179 | /// An “error” that is impossible to construct. 180 | /// 181 | /// This can be used to describe `Result`s where failures will never 182 | /// be generated. For example, `Result` describes a result that 183 | /// contains an `Int`eger and is guaranteed never to be a `failure`. 184 | public enum NoError: Swift.Error, Equatable { 185 | public static func ==(lhs: NoError, rhs: NoError) -> Bool { 186 | return true 187 | } 188 | } 189 | 190 | /// A type-erased error which wraps an arbitrary error instance. This should be 191 | /// useful for generic contexts. 192 | public struct AnyError: Swift.Error { 193 | /// The underlying error. 194 | public let error: Swift.Error 195 | 196 | public init(_ error: Swift.Error) { 197 | if let anyError = error as? AnyError { 198 | self = anyError 199 | } else { 200 | self.error = error 201 | } 202 | } 203 | } 204 | 205 | extension AnyError: ErrorProtocolConvertible { 206 | public static func error(from error: Error) -> AnyError { 207 | return AnyError(error) 208 | } 209 | } 210 | 211 | extension AnyError: CustomStringConvertible { 212 | public var description: String { 213 | return String(describing: error) 214 | } 215 | } 216 | 217 | // MARK: - migration support 218 | extension Result { 219 | @available(*, unavailable, renamed: "success") 220 | public static func Success(_: T) -> Result { 221 | fatalError() 222 | } 223 | 224 | @available(*, unavailable, renamed: "failure") 225 | public static func Failure(_: Error) -> Result { 226 | fatalError() 227 | } 228 | } 229 | 230 | extension NSError { 231 | @available(*, unavailable, renamed: "error(from:)") 232 | public static func errorFromErrorType(_ error: Swift.Error) -> Self { 233 | fatalError() 234 | } 235 | } 236 | 237 | import Foundation 238 | -------------------------------------------------------------------------------- /Pods/Result/Result/ResultProtocol.swift: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Rob Rix. All rights reserved. 2 | 3 | /// A type that can represent either failure with an error or success with a result value. 4 | public protocol ResultProtocol { 5 | associatedtype Value 6 | associatedtype Error: Swift.Error 7 | 8 | /// Constructs a successful result wrapping a `value`. 9 | init(value: Value) 10 | 11 | /// Constructs a failed result wrapping an `error`. 12 | init(error: Error) 13 | 14 | /// Case analysis for ResultProtocol. 15 | /// 16 | /// Returns the value produced by appliying `ifFailure` to the error if self represents a failure, or `ifSuccess` to the result value if self represents a success. 17 | func analysis(ifSuccess: (Value) -> U, ifFailure: (Error) -> U) -> U 18 | 19 | /// Returns the value if self represents a success, `nil` otherwise. 20 | /// 21 | /// A default implementation is provided by a protocol extension. Conforming types may specialize it. 22 | var value: Value? { get } 23 | 24 | /// Returns the error if self represents a failure, `nil` otherwise. 25 | /// 26 | /// A default implementation is provided by a protocol extension. Conforming types may specialize it. 27 | var error: Error? { get } 28 | } 29 | 30 | public extension ResultProtocol { 31 | 32 | /// Returns the value if self represents a success, `nil` otherwise. 33 | public var value: Value? { 34 | return analysis(ifSuccess: { $0 }, ifFailure: { _ in nil }) 35 | } 36 | 37 | /// Returns the error if self represents a failure, `nil` otherwise. 38 | public var error: Error? { 39 | return analysis(ifSuccess: { _ in nil }, ifFailure: { $0 }) 40 | } 41 | 42 | /// Returns a new Result by mapping `Success`es’ values using `transform`, or re-wrapping `Failure`s’ errors. 43 | public func map(_ transform: (Value) -> U) -> Result { 44 | return flatMap { .success(transform($0)) } 45 | } 46 | 47 | /// Returns the result of applying `transform` to `Success`es’ values, or re-wrapping `Failure`’s errors. 48 | public func flatMap(_ transform: (Value) -> Result) -> Result { 49 | return analysis( 50 | ifSuccess: transform, 51 | ifFailure: Result.failure) 52 | } 53 | 54 | /// Returns a new Result by mapping `Failure`'s values using `transform`, or re-wrapping `Success`es’ values. 55 | public func mapError(_ transform: (Error) -> Error2) -> Result { 56 | return flatMapError { .failure(transform($0)) } 57 | } 58 | 59 | /// Returns the result of applying `transform` to `Failure`’s errors, or re-wrapping `Success`es’ values. 60 | public func flatMapError(_ transform: (Error) -> Result) -> Result { 61 | return analysis( 62 | ifSuccess: Result.success, 63 | ifFailure: transform) 64 | } 65 | } 66 | 67 | public extension ResultProtocol { 68 | 69 | // MARK: Higher-order functions 70 | 71 | /// Returns `self.value` if this result is a .Success, or the given value otherwise. Equivalent with `??` 72 | public func recover(_ value: @autoclosure () -> Value) -> Value { 73 | return self.value ?? value() 74 | } 75 | 76 | /// Returns this result if it is a .Success, or the given result otherwise. Equivalent with `??` 77 | public func recover(with result: @autoclosure () -> Self) -> Self { 78 | return analysis( 79 | ifSuccess: { _ in self }, 80 | ifFailure: { _ in result() }) 81 | } 82 | } 83 | 84 | /// Protocol used to constrain `tryMap` to `Result`s with compatible `Error`s. 85 | public protocol ErrorProtocolConvertible: Swift.Error { 86 | static func error(from error: Swift.Error) -> Self 87 | } 88 | 89 | public extension ResultProtocol where Error: ErrorProtocolConvertible { 90 | 91 | /// Returns the result of applying `transform` to `Success`es’ values, or wrapping thrown errors. 92 | public func tryMap(_ transform: (Value) throws -> U) -> Result { 93 | return flatMap { value in 94 | do { 95 | return .success(try transform(value)) 96 | } 97 | catch { 98 | let convertedError = Error.error(from: error) 99 | // Revisit this in a future version of Swift. https://twitter.com/jckarter/status/672931114944696321 100 | return .failure(convertedError) 101 | } 102 | } 103 | } 104 | } 105 | 106 | // MARK: - Operators 107 | 108 | infix operator &&& : LogicalConjunctionPrecedence 109 | 110 | /// Returns a Result with a tuple of `left` and `right` values if both are `Success`es, or re-wrapping the error of the earlier `Failure`. 111 | public func &&& (left: L, right: @autoclosure () -> R) -> Result<(L.Value, R.Value), L.Error> 112 | where L.Error == R.Error 113 | { 114 | return left.flatMap { left in right().map { right in (left, right) } } 115 | } 116 | 117 | precedencegroup ChainingPrecedence { 118 | associativity: left 119 | higherThan: TernaryPrecedence 120 | } 121 | 122 | infix operator >>- : ChainingPrecedence 123 | 124 | /// Returns the result of applying `transform` to `Success`es’ values, or re-wrapping `Failure`’s errors. 125 | /// 126 | /// This is a synonym for `flatMap`. 127 | public func >>- (result: T, transform: (T.Value) -> Result) -> Result { 128 | return result.flatMap(transform) 129 | } 130 | 131 | /// Returns `true` if `left` and `right` are both `Success`es and their values are equal, or if `left` and `right` are both `Failure`s and their errors are equal. 132 | public func == (left: T, right: T) -> Bool 133 | where T.Value: Equatable, T.Error: Equatable 134 | { 135 | if let left = left.value, let right = right.value { 136 | return left == right 137 | } else if let left = left.error, let right = right.error { 138 | return left == right 139 | } 140 | return false 141 | } 142 | 143 | /// Returns `true` if `left` and `right` represent different cases, or if they represent the same case but different values. 144 | public func != (left: T, right: T) -> Bool 145 | where T.Value: Equatable, T.Error: Equatable 146 | { 147 | return !(left == right) 148 | } 149 | 150 | /// Returns the value of `left` if it is a `Success`, or `right` otherwise. Short-circuits. 151 | public func ?? (left: T, right: @autoclosure () -> T.Value) -> T.Value { 152 | return left.recover(right()) 153 | } 154 | 155 | /// Returns `left` if it is a `Success`es, or `right` otherwise. Short-circuits. 156 | public func ?? (left: T, right: @autoclosure () -> T) -> T { 157 | return left.recover(with: right()) 158 | } 159 | 160 | // MARK: - migration support 161 | @available(*, unavailable, renamed: "ResultProtocol") 162 | public typealias ResultType = ResultProtocol 163 | 164 | @available(*, unavailable, renamed: "Error") 165 | public typealias ResultErrorType = Swift.Error 166 | 167 | @available(*, unavailable, renamed: "ErrorProtocolConvertible") 168 | public typealias ErrorTypeConvertible = ErrorProtocolConvertible 169 | 170 | extension ResultProtocol { 171 | @available(*, unavailable, renamed: "recover(with:)") 172 | public func recoverWith(_ result: @autoclosure () -> Self) -> Self { 173 | fatalError() 174 | } 175 | } 176 | 177 | extension ErrorProtocolConvertible { 178 | @available(*, unavailable, renamed: "error(from:)") 179 | public static func errorFromErrorType(_ error: Swift.Error) -> Self { 180 | fatalError() 181 | } 182 | } 183 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-ReactiveRegistration/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-ReactiveRegistration/Pods-ReactiveRegistration-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## ReactiveCocoa 5 | 6 | **Copyright (c) 2012 - 2016, GitHub, Inc.** 7 | **All rights reserved.** 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy of 10 | this software and associated documentation files (the "Software"), to deal in 11 | the Software without restriction, including without limitation the rights to 12 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 13 | the Software, and to permit persons to whom the Software is furnished to do so, 14 | subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 21 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 22 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 23 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 24 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 | 26 | 27 | ## ReactiveSwift 28 | 29 | **Copyright (c) 2012 - 2016, GitHub, Inc.** 30 | **All rights reserved.** 31 | 32 | Permission is hereby granted, free of charge, to any person obtaining a copy of 33 | this software and associated documentation files (the "Software"), to deal in 34 | the Software without restriction, including without limitation the rights to 35 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 36 | the Software, and to permit persons to whom the Software is furnished to do so, 37 | subject to the following conditions: 38 | 39 | The above copyright notice and this permission notice shall be included in all 40 | copies or substantial portions of the Software. 41 | 42 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 43 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 44 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 45 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 46 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 47 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 48 | 49 | 50 | ## Result 51 | 52 | The MIT License (MIT) 53 | 54 | Copyright (c) 2014 Rob Rix 55 | 56 | Permission is hereby granted, free of charge, to any person obtaining a copy 57 | of this software and associated documentation files (the "Software"), to deal 58 | in the Software without restriction, including without limitation the rights 59 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 60 | copies of the Software, and to permit persons to whom the Software is 61 | furnished to do so, subject to the following conditions: 62 | 63 | The above copyright notice and this permission notice shall be included in all 64 | copies or substantial portions of the Software. 65 | 66 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 67 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 68 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 69 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 70 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 71 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 72 | SOFTWARE. 73 | Generated by CocoaPods - https://cocoapods.org 74 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-ReactiveRegistration/Pods-ReactiveRegistration-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | **Copyright (c) 2012 - 2016, GitHub, Inc.** 18 | **All rights reserved.** 19 | 20 | Permission is hereby granted, free of charge, to any person obtaining a copy of 21 | this software and associated documentation files (the "Software"), to deal in 22 | the Software without restriction, including without limitation the rights to 23 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 24 | the Software, and to permit persons to whom the Software is furnished to do so, 25 | subject to the following conditions: 26 | 27 | The above copyright notice and this permission notice shall be included in all 28 | copies or substantial portions of the Software. 29 | 30 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 31 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 32 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 33 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 34 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 35 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 36 | 37 | License 38 | MIT 39 | Title 40 | ReactiveCocoa 41 | Type 42 | PSGroupSpecifier 43 | 44 | 45 | FooterText 46 | **Copyright (c) 2012 - 2016, GitHub, Inc.** 47 | **All rights reserved.** 48 | 49 | Permission is hereby granted, free of charge, to any person obtaining a copy of 50 | this software and associated documentation files (the "Software"), to deal in 51 | the Software without restriction, including without limitation the rights to 52 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 53 | the Software, and to permit persons to whom the Software is furnished to do so, 54 | subject to the following conditions: 55 | 56 | The above copyright notice and this permission notice shall be included in all 57 | copies or substantial portions of the Software. 58 | 59 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 60 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 61 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 62 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 63 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 64 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 65 | 66 | License 67 | MIT 68 | Title 69 | ReactiveSwift 70 | Type 71 | PSGroupSpecifier 72 | 73 | 74 | FooterText 75 | The MIT License (MIT) 76 | 77 | Copyright (c) 2014 Rob Rix 78 | 79 | Permission is hereby granted, free of charge, to any person obtaining a copy 80 | of this software and associated documentation files (the "Software"), to deal 81 | in the Software without restriction, including without limitation the rights 82 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 83 | copies of the Software, and to permit persons to whom the Software is 84 | furnished to do so, subject to the following conditions: 85 | 86 | The above copyright notice and this permission notice shall be included in all 87 | copies or substantial portions of the Software. 88 | 89 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 90 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 91 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 92 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 93 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 94 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 95 | SOFTWARE. 96 | License 97 | MIT 98 | Title 99 | Result 100 | Type 101 | PSGroupSpecifier 102 | 103 | 104 | FooterText 105 | Generated by CocoaPods - https://cocoapods.org 106 | Title 107 | 108 | Type 109 | PSGroupSpecifier 110 | 111 | 112 | StringsTable 113 | Acknowledgements 114 | Title 115 | Acknowledgements 116 | 117 | 118 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-ReactiveRegistration/Pods-ReactiveRegistration-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_ReactiveRegistration : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_ReactiveRegistration 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-ReactiveRegistration/Pods-ReactiveRegistration-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 5 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 6 | 7 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 8 | 9 | install_framework() 10 | { 11 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 12 | local source="${BUILT_PRODUCTS_DIR}/$1" 13 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 14 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 15 | elif [ -r "$1" ]; then 16 | local source="$1" 17 | fi 18 | 19 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 20 | 21 | if [ -L "${source}" ]; then 22 | echo "Symlinked..." 23 | source="$(readlink "${source}")" 24 | fi 25 | 26 | # use filter instead of exclude so missing patterns dont' throw errors 27 | echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 28 | rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 29 | 30 | local basename 31 | basename="$(basename -s .framework "$1")" 32 | binary="${destination}/${basename}.framework/${basename}" 33 | if ! [ -r "$binary" ]; then 34 | binary="${destination}/${basename}" 35 | fi 36 | 37 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 38 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 39 | strip_invalid_archs "$binary" 40 | fi 41 | 42 | # Resign the code if required by the build settings to avoid unstable apps 43 | code_sign_if_enabled "${destination}/$(basename "$1")" 44 | 45 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 46 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 47 | local swift_runtime_libs 48 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) 49 | for lib in $swift_runtime_libs; do 50 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 51 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 52 | code_sign_if_enabled "${destination}/${lib}" 53 | done 54 | fi 55 | } 56 | 57 | # Signs a framework with the provided identity 58 | code_sign_if_enabled() { 59 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 60 | # Use the current code_sign_identitiy 61 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 62 | echo "/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements \"$1\"" 63 | /usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements "$1" 64 | fi 65 | } 66 | 67 | # Strip invalid architectures 68 | strip_invalid_archs() { 69 | binary="$1" 70 | # Get architectures for current file 71 | archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" 72 | stripped="" 73 | for arch in $archs; do 74 | if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then 75 | # Strip non-valid architectures in-place 76 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1 77 | stripped="$stripped $arch" 78 | fi 79 | done 80 | if [[ "$stripped" ]]; then 81 | echo "Stripped $binary of architectures:$stripped" 82 | fi 83 | } 84 | 85 | 86 | if [[ "$CONFIGURATION" == "Debug" ]]; then 87 | install_framework "$BUILT_PRODUCTS_DIR/ReactiveCocoa/ReactiveCocoa.framework" 88 | install_framework "$BUILT_PRODUCTS_DIR/ReactiveSwift/ReactiveSwift.framework" 89 | install_framework "$BUILT_PRODUCTS_DIR/Result/Result.framework" 90 | fi 91 | if [[ "$CONFIGURATION" == "Release" ]]; then 92 | install_framework "$BUILT_PRODUCTS_DIR/ReactiveCocoa/ReactiveCocoa.framework" 93 | install_framework "$BUILT_PRODUCTS_DIR/ReactiveSwift/ReactiveSwift.framework" 94 | install_framework "$BUILT_PRODUCTS_DIR/Result/Result.framework" 95 | fi 96 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-ReactiveRegistration/Pods-ReactiveRegistration-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 5 | 6 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 7 | > "$RESOURCES_TO_COPY" 8 | 9 | XCASSET_FILES=() 10 | 11 | case "${TARGETED_DEVICE_FAMILY}" in 12 | 1,2) 13 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 14 | ;; 15 | 1) 16 | TARGET_DEVICE_ARGS="--target-device iphone" 17 | ;; 18 | 2) 19 | TARGET_DEVICE_ARGS="--target-device ipad" 20 | ;; 21 | *) 22 | TARGET_DEVICE_ARGS="--target-device mac" 23 | ;; 24 | esac 25 | 26 | install_resource() 27 | { 28 | if [[ "$1" = /* ]] ; then 29 | RESOURCE_PATH="$1" 30 | else 31 | RESOURCE_PATH="${PODS_ROOT}/$1" 32 | fi 33 | if [[ ! -e "$RESOURCE_PATH" ]] ; then 34 | cat << EOM 35 | error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. 36 | EOM 37 | exit 1 38 | fi 39 | case $RESOURCE_PATH in 40 | *.storyboard) 41 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" 42 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 43 | ;; 44 | *.xib) 45 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" 46 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 47 | ;; 48 | *.framework) 49 | echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 50 | mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 51 | echo "rsync -av $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 52 | rsync -av "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 53 | ;; 54 | *.xcdatamodel) 55 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" 56 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" 57 | ;; 58 | *.xcdatamodeld) 59 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" 60 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" 61 | ;; 62 | *.xcmappingmodel) 63 | echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" 64 | xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" 65 | ;; 66 | *.xcassets) 67 | ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" 68 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 69 | ;; 70 | *) 71 | echo "$RESOURCE_PATH" 72 | echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" 73 | ;; 74 | esac 75 | } 76 | 77 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 78 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 79 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 80 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 81 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 82 | fi 83 | rm -f "$RESOURCES_TO_COPY" 84 | 85 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] 86 | then 87 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 88 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 89 | while read line; do 90 | if [[ $line != "${PODS_ROOT}*" ]]; then 91 | XCASSET_FILES+=("$line") 92 | fi 93 | done <<<"$OTHER_XCASSETS" 94 | 95 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 96 | fi 97 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-ReactiveRegistration/Pods-ReactiveRegistration-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | 6 | FOUNDATION_EXPORT double Pods_ReactiveRegistrationVersionNumber; 7 | FOUNDATION_EXPORT const unsigned char Pods_ReactiveRegistrationVersionString[]; 8 | 9 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-ReactiveRegistration/Pods-ReactiveRegistration.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | EMBEDDED_CONTENT_CONTAINS_SWIFT = YES 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/ReactiveCocoa" "$PODS_CONFIGURATION_BUILD_DIR/ReactiveSwift" "$PODS_CONFIGURATION_BUILD_DIR/Result" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 6 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/ReactiveCocoa/ReactiveCocoa.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/ReactiveSwift/ReactiveSwift.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/Result/Result.framework/Headers" 7 | OTHER_LDFLAGS = $(inherited) -framework "ReactiveCocoa" -framework "ReactiveSwift" -framework "Result" 8 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 9 | PODS_BUILD_DIR = $BUILD_DIR 10 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-ReactiveRegistration/Pods-ReactiveRegistration.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_ReactiveRegistration { 2 | umbrella header "Pods-ReactiveRegistration-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-ReactiveRegistration/Pods-ReactiveRegistration.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | EMBEDDED_CONTENT_CONTAINS_SWIFT = YES 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/ReactiveCocoa" "$PODS_CONFIGURATION_BUILD_DIR/ReactiveSwift" "$PODS_CONFIGURATION_BUILD_DIR/Result" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 6 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/ReactiveCocoa/ReactiveCocoa.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/ReactiveSwift/ReactiveSwift.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/Result/Result.framework/Headers" 7 | OTHER_LDFLAGS = $(inherited) -framework "ReactiveCocoa" -framework "ReactiveSwift" -framework "Result" 8 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 9 | PODS_BUILD_DIR = $BUILD_DIR 10 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /Pods/Target Support Files/ReactiveCocoa/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 5.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/ReactiveCocoa/ReactiveCocoa-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_ReactiveCocoa : NSObject 3 | @end 4 | @implementation PodsDummy_ReactiveCocoa 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/ReactiveCocoa/ReactiveCocoa-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | -------------------------------------------------------------------------------- /Pods/Target Support Files/ReactiveCocoa/ReactiveCocoa.modulemap: -------------------------------------------------------------------------------- 1 | framework module ReactiveCocoa { 2 | umbrella header "ReactiveCocoa.h" 3 | private header "ObjCRuntimeAliases.h" 4 | 5 | export * 6 | module * { export * } 7 | } 8 | -------------------------------------------------------------------------------- /Pods/Target Support Files/ReactiveCocoa/ReactiveCocoa.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/ReactiveCocoa 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/ReactiveSwift" "$PODS_CONFIGURATION_BUILD_DIR/Result" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" 5 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" "-suppress-warnings" 6 | PODS_BUILD_DIR = $BUILD_DIR 7 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_ROOT = ${SRCROOT} 9 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 10 | SKIP_INSTALL = YES 11 | -------------------------------------------------------------------------------- /Pods/Target Support Files/ReactiveSwift/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/ReactiveSwift/ReactiveSwift-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_ReactiveSwift : NSObject 3 | @end 4 | @implementation PodsDummy_ReactiveSwift 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/ReactiveSwift/ReactiveSwift-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | -------------------------------------------------------------------------------- /Pods/Target Support Files/ReactiveSwift/ReactiveSwift-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | 6 | FOUNDATION_EXPORT double ReactiveSwiftVersionNumber; 7 | FOUNDATION_EXPORT const unsigned char ReactiveSwiftVersionString[]; 8 | 9 | -------------------------------------------------------------------------------- /Pods/Target Support Files/ReactiveSwift/ReactiveSwift.modulemap: -------------------------------------------------------------------------------- 1 | framework module ReactiveSwift { 2 | umbrella header "ReactiveSwift-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/ReactiveSwift/ReactiveSwift.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/ReactiveSwift 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/Result" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" 5 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" "-suppress-warnings" 6 | PODS_BUILD_DIR = $BUILD_DIR 7 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_ROOT = ${SRCROOT} 9 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 10 | SKIP_INSTALL = YES 11 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Result/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 3.1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Result/Result-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Result : NSObject 3 | @end 4 | @implementation PodsDummy_Result 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Result/Result-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Result/Result-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | 6 | FOUNDATION_EXPORT double ResultVersionNumber; 7 | FOUNDATION_EXPORT const unsigned char ResultVersionString[]; 8 | 9 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Result/Result.modulemap: -------------------------------------------------------------------------------- 1 | framework module Result { 2 | umbrella header "Result-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Result/Result.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/Result 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" 4 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" "-suppress-warnings" 5 | PODS_BUILD_DIR = $BUILD_DIR 6 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT} 8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 9 | SKIP_INSTALL = YES 10 | SWIFT_VERSION = 3.0 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # iOS-ReactiveRegistration 2 | 3 | Sample of Reactive Cocoa 5 & MVVM 4 | 5 | This projects implements the simple registration screen. You can proceed the registration only if the form is correctly filled in. It is necessary to enter correct email. Enter the same password to the "Password" and "Password again" fields. Password should be more than 5 characters long. You can decide whether to use credit card. If you dedice to use credit card, you must first enter the card number and then verify it. Button "Verify" starts the fake network request. Only card number "123456" is considered to be valid. 6 | 7 | Project demonstrates using of Reactive Cocoa 5 in Swift 3, UI bindings and the separation of controller and view model. 8 | 9 | Compare this solution with [Allan Barbato's](https://github.com/allbto/iOS-DynamicRegistration) non-reactive implementation of the same project using lightweight MVVM binding provided by [Swiftility](https://github.com/allbto/iOS-Swiftility) library. 10 | 11 | -------------------------------------------------------------------------------- /ReactiveRegistration.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ReactiveRegistration.xcodeproj/project.xcworkspace/xcuserdata/dan.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanielCech/iOS-ReactiveRegistration/adbdaca32cfb2f8b837427f3842dab772adb3e90/ReactiveRegistration.xcodeproj/project.xcworkspace/xcuserdata/dan.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /ReactiveRegistration.xcodeproj/xcuserdata/dan.xcuserdatad/xcschemes/ReactiveRegistration.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /ReactiveRegistration.xcodeproj/xcuserdata/dan.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | ReactiveRegistration.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 37DD12FD1C695CBF008F7826 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /ReactiveRegistration.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ReactiveRegistration.xcworkspace/xcuserdata/dan.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanielCech/iOS-ReactiveRegistration/adbdaca32cfb2f8b837427f3842dab772adb3e90/ReactiveRegistration.xcworkspace/xcuserdata/dan.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /ReactiveRegistration.xcworkspace/xcuserdata/dan.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /ReactiveRegistration/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // ReactiveRegistration 4 | // 5 | // Created by Dan on 09.02.16. 6 | // Copyright © 2016 Dan Cech. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /ReactiveRegistration/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /ReactiveRegistration/Assets.xcassets/Avatar.imageset/Avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanielCech/iOS-ReactiveRegistration/adbdaca32cfb2f8b837427f3842dab772adb3e90/ReactiveRegistration/Assets.xcassets/Avatar.imageset/Avatar.png -------------------------------------------------------------------------------- /ReactiveRegistration/Assets.xcassets/Avatar.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Avatar.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /ReactiveRegistration/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /ReactiveRegistration/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /ReactiveRegistration/FakeAPIService.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RegistrationViewController.swift 3 | // ReactiveRegistration 4 | // 5 | // Created by Dan on 09.02.16. 6 | // Copyright © 2016 Dan Cech. All rights reserved. 7 | // 8 | 9 | import ReactiveSwift 10 | 11 | 12 | public func delay(_ delay: Double, closure: @escaping ()->()) { 13 | DispatchQueue.main.asyncAfter(deadline: .now() + delay) { 14 | closure() 15 | } 16 | } 17 | 18 | 19 | class FakeAPIService { 20 | 21 | static let sharedInstance = FakeAPIService() 22 | 23 | func validateCreditCardNumber(_ number: String) -> SignalProducer 24 | { 25 | return SignalProducer { sink, disposable in 26 | 27 | delay(2) { 28 | sink.send(value: number == "123456") 29 | sink.sendCompleted() 30 | } 31 | 32 | } 33 | } 34 | 35 | 36 | 37 | } 38 | -------------------------------------------------------------------------------- /ReactiveRegistration/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /ReactiveRegistration/ReactiveUtils/RACHelpers.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RACHelpers.swift 3 | // TodaysReactiveMenu 4 | // 5 | // Created by Steffen Damtoft Sommer on 25/05/15. 6 | // Copyright (c) 2015 steffendsommer. All rights reserved. 7 | // 8 | 9 | import ReactiveSwift 10 | import enum Result.NoError 11 | 12 | public typealias NoError = Result.NoError 13 | 14 | extension SignalProducer where Value: OptionalProtocol { 15 | public func ignoreError() -> SignalProducer { 16 | return flatMapError { _ in 17 | SignalProducer.empty 18 | } 19 | } 20 | } 21 | 22 | public func merge(_ signals: [SignalProducer]) -> SignalProducer { 23 | return SignalProducer, E>(signals).flatten(.merge) 24 | } 25 | 26 | -------------------------------------------------------------------------------- /ReactiveRegistration/ReactiveUtils/UIKitExtensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Util.swift 3 | // ReactiveTwitterSearch 4 | // 5 | // Created by Colin Eberhardt on 10/05/2015. 6 | // Copyright (c) 2015 Colin Eberhardt. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import ReactiveSwift 11 | 12 | struct AssociationKey { 13 | static var hidden: UInt8 = 1 14 | static var alpha: UInt8 = 2 15 | static var text: UInt8 = 3 16 | static var image: UInt8 = 4 17 | static var on: UInt8 = 5 18 | static var enabled: UInt8 = 6 19 | } 20 | 21 | // lazily creates a gettable associated property via the given factory 22 | func lazyAssociatedProperty(_ host: AnyObject, key: UnsafeRawPointer, factory: ()->T) -> T { 23 | var associatedProperty = objc_getAssociatedObject(host, key) as? T 24 | 25 | if associatedProperty == nil { 26 | associatedProperty = factory() 27 | objc_setAssociatedObject(host, key, associatedProperty, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN) 28 | } 29 | return associatedProperty! 30 | } 31 | 32 | func lazyMutableProperty(_ host: AnyObject, key: UnsafeRawPointer, setter: @escaping (T) -> (), getter: @escaping () -> T) -> MutableProperty { 33 | return lazyAssociatedProperty(host, key: key) { 34 | let property = MutableProperty(getter()) 35 | property.producer 36 | .startWithValues { newValue in 37 | setter(newValue) 38 | } 39 | return property 40 | } 41 | } 42 | 43 | extension UIView { 44 | public var rac_alpha: MutableProperty { 45 | return lazyMutableProperty(self, key: &AssociationKey.alpha, setter: { self.alpha = $0 }, getter: { self.alpha }) 46 | } 47 | 48 | public var rac_hidden: MutableProperty { 49 | return lazyMutableProperty(self, key: &AssociationKey.hidden, setter: { self.isHidden = $0 }, getter: { self.isHidden }) 50 | } 51 | } 52 | 53 | extension UIImageView { 54 | public var rac_image: MutableProperty { 55 | return lazyMutableProperty(self, key: &AssociationKey.image, setter: { self.image = $0 }, getter: { self.image }) 56 | } 57 | } 58 | 59 | extension UILabel { 60 | public var rac_text: MutableProperty { 61 | return lazyMutableProperty(self, key: &AssociationKey.text, setter: { self.text = $0 }, getter: { self.text ?? "" }) 62 | } 63 | } 64 | 65 | extension UITextField { 66 | public var rac_text: MutableProperty { 67 | return lazyAssociatedProperty(self, key: &AssociationKey.text) { 68 | 69 | self.addTarget(self, action: #selector(UITextField.changed), for: UIControlEvents.editingChanged) 70 | 71 | let property = MutableProperty(self.text ?? "") 72 | property.producer 73 | .startWithValues { newValue in 74 | self.text = newValue 75 | } 76 | return property 77 | } 78 | } 79 | 80 | func changed() { 81 | rac_text.value = self.text! 82 | } 83 | } 84 | 85 | extension UISearchBar: UISearchBarDelegate { 86 | public var rac_text: MutableProperty { 87 | return lazyAssociatedProperty(self, key: &AssociationKey.text) { 88 | 89 | self.delegate = self 90 | 91 | let property = MutableProperty(self.text ?? "") 92 | property.producer 93 | .startWithValues { newValue in 94 | self.text = newValue 95 | } 96 | return property 97 | } 98 | } 99 | 100 | public func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { 101 | rac_text.value = searchBar.text! 102 | } 103 | } 104 | 105 | extension UISwitch { 106 | public var rac_on: MutableProperty { 107 | return lazyAssociatedProperty(self, key: &AssociationKey.on) { 108 | 109 | self.addTarget(self, action: #selector(UISwitch.changed), for: UIControlEvents.valueChanged) 110 | 111 | let property = MutableProperty(self.isOn) 112 | property.producer 113 | .startWithValues { newValue in 114 | self.isOn = newValue 115 | } 116 | return property 117 | } 118 | } 119 | 120 | func changed() { 121 | rac_on.value = self.isOn 122 | } 123 | } 124 | 125 | extension UIButton { 126 | public var rac_enabled: MutableProperty { 127 | return lazyMutableProperty(self, key: &AssociationKey.enabled, setter: { self.isEnabled = $0 }, getter: { self.isEnabled }) 128 | } 129 | } 130 | 131 | -------------------------------------------------------------------------------- /ReactiveRegistration/RegistrationViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RegistrationViewController.swift 3 | // ReactiveRegistration 4 | // 5 | // Created by Dan on 09.02.16. 6 | // Copyright © 2016 Dan Cech. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import ReactiveSwift 11 | import ReactiveCocoa 12 | 13 | class RegistrationViewController: UITableViewController { 14 | 15 | @IBOutlet weak var emailTextField: UITextField! 16 | @IBOutlet weak var passwordTextField: UITextField! 17 | @IBOutlet weak var passwordAgainTextField: UITextField! 18 | @IBOutlet weak var useCreditCardSwitch: UISwitch! 19 | @IBOutlet weak var creditCardTextField: UITextField! 20 | @IBOutlet weak var cardStatusLabel: UILabel! 21 | @IBOutlet weak var verifyCardButton: UIButton! 22 | @IBOutlet weak var activityIndicator: UIActivityIndicatorView! 23 | @IBOutlet weak var registerButton: UIButton! 24 | 25 | var viewModel: RegistrationViewModel! 26 | 27 | 28 | override func viewDidLoad() { 29 | super.viewDidLoad() 30 | 31 | viewModel = RegistrationViewModel() 32 | 33 | initViewModelBindings() 34 | } 35 | 36 | override func didReceiveMemoryWarning() { 37 | super.didReceiveMemoryWarning() 38 | // Dispose of any resources that can be recreated. 39 | } 40 | 41 | 42 | func initViewModelBindings() 43 | { 44 | emailTextField.reactive.continuousTextValues.skipNil().observeValues { email in 45 | print(email) 46 | } 47 | 48 | viewModel.email <~ emailTextField.reactive.continuousTextValues.skipNil() 49 | viewModel.password <~ passwordTextField.reactive.continuousTextValues.skipNil() 50 | viewModel.passwordAgain <~ passwordAgainTextField.reactive.continuousTextValues.skipNil() 51 | viewModel.useCreditCard <~ useCreditCardSwitch.reactive.isOnValues 52 | viewModel.creditCardNumber <~ creditCardTextField.reactive.continuousTextValues.skipNil() 53 | 54 | // cardStatusLabel.rac_text <~ viewModel.cardStatus 55 | 56 | viewModel.initBindings() 57 | 58 | registerButton.reactive.isEnabled <~ viewModel.correctInputProducer 59 | 60 | viewModel.correctEmailProducer.startWithValues { (correct) in 61 | self.emailTextField.textColor = correct ? UIColor.blue : UIColor.gray 62 | } 63 | 64 | viewModel.correctPasswordProducer.startWithValues { (correct) -> () in 65 | let backgroundColor = correct ? UIColor.lightGray : UIColor.red 66 | self.passwordTextField.textColor = backgroundColor 67 | self.passwordAgainTextField.textColor = backgroundColor 68 | } 69 | 70 | viewModel.useCreditCard.producer.startWithValues { (useCard) -> () in 71 | self.tableView.beginUpdates() 72 | self.tableView.endUpdates() 73 | } 74 | 75 | viewModel.cardStatus.producer.startWithValues { (status) -> () in 76 | switch status { 77 | 78 | case .notVerified: 79 | self.cardStatusLabel.text = "Card has not been verified yet" 80 | self.activityIndicator.isHidden = true 81 | self.verifyCardButton.isHidden = false 82 | 83 | case .verifying: 84 | self.cardStatusLabel.text = "Card is currently being verified" 85 | self.activityIndicator.isHidden = false 86 | self.verifyCardButton.isHidden = true 87 | 88 | case .verified: 89 | self.cardStatusLabel.text = "Card is verified" 90 | self.activityIndicator.isHidden = true 91 | self.verifyCardButton.isHidden = true 92 | 93 | case .denied: 94 | self.cardStatusLabel.text = "Card is denied" 95 | self.activityIndicator.isHidden = true 96 | self.verifyCardButton.isHidden = false 97 | 98 | } 99 | 100 | } 101 | } 102 | 103 | 104 | 105 | //////////////////////////////////////////////////////////////// 106 | // MARK: - TableView 107 | 108 | 109 | override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 110 | if (indexPath.row == 4) || (indexPath.row == 5) { 111 | if viewModel.useCreditCard.value { 112 | return 44 113 | } 114 | else { 115 | return 0 116 | } 117 | } 118 | 119 | return 44 120 | } 121 | 122 | 123 | //////////////////////////////////////////////////////////////// 124 | // MARK: - Segue 125 | 126 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 127 | super.prepare(for: segue, sender: sender) 128 | 129 | if segue.identifier == "ShowSummary" { 130 | let summaryController = segue.destination as! SummaryViewController 131 | summaryController.viewModel = viewModel.createSummaryViewModel() 132 | } 133 | } 134 | 135 | 136 | //////////////////////////////////////////////////////////////// 137 | // MARK: - Actions 138 | 139 | @IBAction func showSummary(_ sender: AnyObject) { 140 | performSegue(withIdentifier: "ShowSummary", sender: self) 141 | } 142 | 143 | @IBAction func verifyCardNumber(_ sender: AnyObject) { 144 | viewModel.verifyCardNumber() 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /ReactiveRegistration/RegistrationViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RegistrationViewModel.swift 3 | // ReactiveRegistration 4 | // 5 | // Created by Dan on 09.02.16. 6 | // Copyright © 2016 Dan Cech. All rights reserved. 7 | // 8 | 9 | 10 | //import UIKit 11 | import ReactiveSwift 12 | 13 | 14 | class RegistrationViewModel: NSObject { 15 | 16 | enum CardStatus { 17 | case notVerified 18 | case verifying 19 | case verified 20 | case denied 21 | } 22 | 23 | 24 | var email = MutableProperty("") 25 | var password = MutableProperty("") 26 | var passwordAgain = MutableProperty("") 27 | var useCreditCard = MutableProperty(false) 28 | var creditCardNumber = MutableProperty("") 29 | var cardStatus = MutableProperty(.notVerified) 30 | 31 | var correctEmailProducer: SignalProducer! 32 | var correctPasswordProducer: SignalProducer! 33 | var correctCreditCardProducer: SignalProducer! 34 | var correctInputProducer: SignalProducer! 35 | 36 | 37 | func initBindings() 38 | { 39 | creditCardNumber.producer.startWithValues { _ in 40 | self.cardStatus.value = .notVerified 41 | } 42 | 43 | correctEmailProducer = 44 | email.producer 45 | .map({ (emailText) -> Bool in 46 | emailText.isValidEmail() 47 | }) 48 | 49 | 50 | correctPasswordProducer = 51 | SignalProducer.combineLatest(password.producer, passwordAgain.producer) 52 | .map { (passwordText, passwordAgainText) -> Bool in 53 | return (passwordText.characters.count > 5) && (passwordText == passwordAgainText) 54 | } 55 | 56 | 57 | correctCreditCardProducer = 58 | SignalProducer.combineLatest(useCreditCard.producer, cardStatus.producer) 59 | .map({ (useCard, cardStatus) -> Bool in 60 | if !useCard { 61 | return true 62 | } 63 | else if cardStatus == .verified { 64 | return true 65 | } 66 | 67 | return false 68 | }) 69 | 70 | correctInputProducer = 71 | SignalProducer.combineLatest(correctEmailProducer, correctPasswordProducer, correctCreditCardProducer) 72 | .map({ (email, password, card) -> Bool in 73 | return email && password && card 74 | }) 75 | 76 | } 77 | 78 | 79 | func verifyCardNumber() 80 | { 81 | cardStatus.value = .verifying 82 | 83 | FakeAPIService.sharedInstance.validateCreditCardNumber(creditCardNumber.value) 84 | .startWithValues { valid in 85 | 86 | self.cardStatus.value = valid ? .verified : .denied 87 | } 88 | } 89 | 90 | 91 | func createSummaryViewModel() -> SummaryViewModel 92 | { 93 | let summaryViewModel = SummaryViewModel() 94 | summaryViewModel.email = email.value 95 | summaryViewModel.creditCardNumber = useCreditCard.value ? creditCardNumber.value : nil 96 | 97 | return summaryViewModel 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /ReactiveRegistration/StringExtension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RegistrationViewController.swift 3 | // ReactiveRegistration 4 | // 5 | // Created by Dan on 09.02.16. 6 | // Copyright © 2016 Dan Cech. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | extension String { 12 | func isValidEmail() -> Bool { 13 | do { 14 | let regex = try NSRegularExpression(pattern: "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}", options: .caseInsensitive) 15 | return regex.firstMatch(in: self, options: NSRegularExpression.MatchingOptions(rawValue: 0), range: NSMakeRange(0, self.characters.count)) != nil 16 | } catch { 17 | return false 18 | } 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /ReactiveRegistration/SummaryViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SummaryViewController.swift 3 | // ReactiveRegistration 4 | // 5 | // Created by Dan on 09.02.16. 6 | // Copyright © 2016 Dan Cech. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class SummaryViewController: UIViewController { 12 | 13 | 14 | @IBOutlet weak var emailLabel: UILabel! 15 | @IBOutlet weak var creditCardNumberLabel: UILabel! 16 | 17 | 18 | var viewModel: SummaryViewModel! 19 | 20 | override func viewDidLoad() { 21 | super.viewDidLoad() 22 | 23 | 24 | emailLabel.text = viewModel.email 25 | creditCardNumberLabel.text = viewModel.creditCardNumber ?? "" 26 | } 27 | 28 | override func didReceiveMemoryWarning() { 29 | super.didReceiveMemoryWarning() 30 | // Dispose of any resources that can be recreated. 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /ReactiveRegistration/SummaryViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SummaryViewModel.swift 3 | // ReactiveRegistration 4 | // 5 | // Created by Dan on 09.02.16. 6 | // Copyright © 2016 Dan Cech. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class SummaryViewModel: NSObject { 12 | 13 | var email: String = "" 14 | var creditCardNumber: String? = nil 15 | 16 | } 17 | --------------------------------------------------------------------------------