Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,6 @@
language: objective-c
matrix:
include:
- osx_image: xcode7.3
env: PLATFORM=Mac
- osx_image: xcode7.3
env: PLATFORM=iOS
- osx_image: xcode7.3
env: PLATFORM=tvOS
- osx_image: xcode7.3
env: PLATFORM=watchOS
- osx_image: xcode7.3
env: PLATFORM=CocoaPods
- osx_image: xcode8
env: PLATFORM=Mac TEST_ACTION="build-for-testing test-without-building"
- osx_image: xcode8
Expand Down
2 changes: 1 addition & 1 deletion Cartfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
github "ReactiveCocoa/ReactiveCocoa" ~> 4.2.2
github "ReactiveCocoa/ReactiveCocoa" "5.0.0-alpha.3"
5 changes: 3 additions & 2 deletions Cartfile.resolved
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
github "antitypical/Result" "2.1.3"
github "ReactiveCocoa/ReactiveCocoa" "v4.2.2"
github "antitypical/Result" "3.0.0"
github "ReactiveCocoa/ReactiveSwift" "1.0.0-alpha.3"
github "ReactiveCocoa/ReactiveCocoa" "5.0.0-alpha.3"
20 changes: 7 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Rex [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)
Extensions for [ReactiveCocoa](https://github.com/ReactiveCocoa/ReactiveCocoa) that may not fit in the core framework.

New development targets RAC 4/Swift 2/Xcode 7. For RAC 3 support [see the 0.5
release](https://github.com/RACCommunity/Rex/releases/tag/v0.5.0).
New development targets RAC 5/Swfit 3/Xcode 8.
* For RAC 4/Swift 2/Xcode 7 support [see the 0.12 release](https://github.com/RACCommunity/Rex/releases/tag/0.12.0)
* For RAC 3 support [see the 0.5 release](https://github.com/RACCommunity/Rex/releases/tag/v0.5.0).

## Signal
All `Signal` operators are available for `SignaProducer`s too via explicit `lift`ing.
Expand Down Expand Up @@ -47,20 +48,13 @@ Partitions values from `producer` into new producer groups based on the key retu
func groupBy<K: Hashable>(grouping: T -> K) -> SignalProducer<(K, SignalProducer<T, E>), E>
```

## UIKit Extensions
## UIKit / AppKit Extensions

##### `UIButton.rex_pressed`

Flexible way to bind `CocoaAction` to the press of button. In addition the button will be disabled during the `Action` executing. Such behavior is convenient for tasks that require some time, like a download process in the example below.
As of RAC 5, UIKit and AppKit Extensions have been moved from REX [to RAC](https://github.com/ReactiveCocoa/ReactiveCocoa/releases/tag/5.0.0-alpha.1).
They are now accessible via `reactive` with pure RAC, e.g:

```swift
let downloadAction = Action<UIButton, NSData, NSError> { _ in
let url = NSURL(string: "https://github.com/RACCommunity/Rex/archive/master.zip")
let request = NSURLRequest(URL: url!)
return NSURLSession.sharedSession().rac_dataWithRequest(request).map { $0.0 }
}

downloadButton.rex_pressed.value = downloadAction.unsafeCocoaAction
imageView.reactive.image <~ SignalProducer(value: image)
```

## License
Expand Down
199 changes: 75 additions & 124 deletions Rex.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Rex.xcodeproj/xcshareddata/xcschemes/Rex-Mac.xcscheme
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0700"
LastUpgradeVersion = "0810"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
2 changes: 1 addition & 1 deletion Rex.xcodeproj/xcshareddata/xcschemes/Rex-iOS.xcscheme
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0700"
LastUpgradeVersion = "0810"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
2 changes: 1 addition & 1 deletion Rex.xcodeproj/xcshareddata/xcschemes/Rex-tvOS.xcscheme
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0720"
LastUpgradeVersion = "0810"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
2 changes: 1 addition & 1 deletion Rex.xcodeproj/xcshareddata/xcschemes/Rex-watchOS.xcscheme
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0720"
LastUpgradeVersion = "0810"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
19 changes: 5 additions & 14 deletions Source/Action.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,27 @@
// Copyright (c) 2015 Neil Pankey. All rights reserved.
//

import ReactiveSwift
import ReactiveCocoa
import enum Result.NoError

extension Action {
/// Creates an always disabled action.
public static var rex_disabled: Action {
return Action(enabledIf: ConstantProperty(false)) { _ in .empty }
public static var rex_disabled: Action<Input, Output, Error> {
return Action(enabledIf: Property(value: false)) { _ in .empty }
}

/// Whether the action execution was started.
public var rex_started: Signal<Void, NoError> {
return self.executing.signal
return self.isExecuting.signal
.filterMap { $0 ? () : nil }
}

/// Whether the action execution was completed successfully.
public var rex_completed: Signal<Void, NoError> {
return events
.filterMap { event -> Void? in
if case .Completed = event {
if case .completed = event {
return ()
} else {
return nil
Expand All @@ -40,14 +41,4 @@ extension CocoaAction {
public static var rex_disabled: CocoaAction {
return CocoaAction(Action<Any?, (), NoError>.rex_disabled, input: nil)
}

/// Creates a producer for the `enabled` state of a CocoaAction.
public var rex_enabledProducer: SignalProducer<Bool, NoError> {
return rex_producerForKeyPath("enabled")
}

/// Creates a producer for the `executing` state of a CocoaAction.
public var rex_executingProducer: SignalProducer<Bool, NoError> {
return rex_producerForKeyPath("executing")
}
}
22 changes: 0 additions & 22 deletions Source/AppKit/NSTextField.swift

This file was deleted.

136 changes: 136 additions & 0 deletions Source/Deprecations+Removals.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
//
// Deprecations+Removals.swift
// Rex
//
// Created by Markus Chmelar on 30/10/2016.
// Copyright © 2016 Neil Pankey. All rights reserved.
//

import ReactiveSwift
import ReactiveCocoa
import enum Result.NoError
#if os(OSX)
import AppKit
extension NSTextField {
@available(*, unavailable, renamed:"reactive.continuousStringValues")
public var rex_textSignal: SignalProducer<String, NoError> { fatalError() }
}
#endif

extension NSObject {
@available(*, unavailable, renamed:"reactive.lifetime.ended")
public var rex_willDealloc: Signal<(), NoError> { fatalError() }

@available(*, unavailable, renamed:"reactive.values(forKeyPath:)")
public func rex_producerForKeyPath<T>(_ keyPath: String) -> SignalProducer<T, NoError> { fatalError() }
}

#if os(iOS)
import UIKit
//@available(*, unavailable, message: "Reusable protocol has been moved to ReactiveCocoa in RAC 5.0. UI Extensions have been moved to RAC 5.0")
//public protocol Reusable {
// @available(*, unavailable, renamed:"reactive.prepareForReuse")
// var rac_prepareForReuseSignal: RACSignal! { get }
//}

extension Reusable {
@available(*, unavailable, renamed:"reactive.prepareForReuse")
public var rex_prepareForReuse: Signal<Void, NoError> { fatalError() }
}

extension CocoaAction {
@available(*, unavailable, renamed:"isEnabled")
public var rex_enabledProducer: SignalProducer<Bool, NoError> { fatalError() }
@available(*, unavailable, renamed:"isExecuting")
public var rex_executingProducer: SignalProducer<Bool, NoError> { fatalError() }
}

extension UIActivityIndicatorView {
@available(*, unavailable, renamed:"reactive.isAnimating")
public var rex_animating: MutableProperty<Bool> { fatalError() }

}

extension UIBarButtonItem {
@available(*, unavailable, renamed:"reactive.pressed")
public var rex_action: MutableProperty<CocoaAction<Any>> { fatalError() }
}

extension UIBarItem {
@available(*, unavailable, renamed:"reactive.isEnabled")
public var rex_enabled: MutableProperty<Bool> { fatalError() }
}

extension UIButton {
@available(*, unavailable, renamed:"reactive.pressed")
public var rex_pressed: MutableProperty<CocoaAction<Any>> { fatalError() }
@available(*, unavailable, renamed:"reactive.title")
public var rex_title: MutableProperty<String> { fatalError() }
}

extension UIDatePicker {
@available(*, unavailable, renamed:"reactive.date")
public var rex_date: MutableProperty<NSDate> { fatalError() }
}

extension UIImageView {
@available(*, unavailable, renamed:"reactive.image")
public var rex_image: MutableProperty<UIImage?> { fatalError() }
@available(*, unavailable, renamed:"reactive.highlightedImage")
public var rex_highlightedImage: MutableProperty<UIImage?> { fatalError() }
}

extension UILabel {
@available(*, unavailable, renamed:"reactive.text")
public var rex_text: MutableProperty<String?> { fatalError() }
@available(*, unavailable, renamed:"reactive.attributedText")
public var rex_attributedText: MutableProperty<NSAttributedString?> { fatalError() }
@available(*, unavailable, renamed:"reactive.textColor")
public var rex_textColor: MutableProperty<UIColor> { fatalError() }
}

extension UIControl {
@available(*, unavailable, renamed:"reactive.trigger(for:)")
public func rex_controlEvents(_ events: UIControlEvents) -> SignalProducer<UIControl?, NoError> { fatalError() }
@available(*, unavailable, renamed:"reactive.isEnabled")
public var rex_enabled: MutableProperty<Bool> { fatalError() }
@available(*, unavailable, renamed:"reactive.isSelected")
public var rex_selected: MutableProperty<Bool> { fatalError() }
@available(*, unavailable, renamed:"reactive.isHighlighted")
public var rex_highlighted: MutableProperty<Bool> { fatalError() }
}

extension UIProgressView {
@available(*, unavailable, renamed:"reactive.progress")
public var rex_progress: MutableProperty<Float> { fatalError() }
}

extension UISegmentedControl {
@available(*, unavailable, renamed:"reactive.selectedSegmentIndex")
public var rex_selectedSegmentIndex: MutableProperty<Int> { fatalError() }
}

extension UISwitch {
@available(*, unavailable, renamed:"reactive.isOn")
public var rex_on: MutableProperty<Bool> { fatalError() }
}

extension UITextField {
@available(*, unavailable, renamed:"reactive.text")
public var rex_text: MutableProperty<String?> { fatalError() }
}

extension UITextView {
@available(*, unavailable, renamed:"reactive.text")
public var rex_text: SignalProducer<String, NoError> { fatalError() }
}

extension UIView {
@available(*, unavailable, renamed:"reactive.alpha")
public var rex_alpha: MutableProperty<CGFloat> { fatalError() }
@available(*, unavailable, renamed:"reactive.isHidden")
public var rex_hidden: MutableProperty<Bool> { fatalError() }
@available(*, unavailable, renamed:"reactive.isUserInteractionEnabled")
public var rex_userInteractionEnabled: MutableProperty<Bool> { fatalError() }
}
#endif
27 changes: 13 additions & 14 deletions Source/Foundation/Association.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// Copyright (c) 2015 Neil Pankey. All rights reserved.
//

import ReactiveCocoa
import ReactiveSwift

/// Attaches a `MutableProperty` value to the `host` object using KVC to get the initial
/// value and write subsequent updates from the property's producer. Note that `keyPath`
Expand All @@ -15,13 +15,13 @@ import ReactiveCocoa
///
/// This can be used as an alternative to `DynamicProperty` for creating strongly typed
/// bindings on Cocoa objects.
@warn_unused_result(message="Did you forget to use the property?")
public func associatedProperty(host: AnyObject, keyPath: StaticString) -> MutableProperty<String> {
let initial: AnyObject -> String = { host in
host.valueForKeyPath(keyPath.stringValue) as? String ?? ""

public func associatedProperty(_ host: AnyObject, keyPath: StaticString) -> MutableProperty<String> {
let initial: (AnyObject) -> String = { host in
host.value(forKeyPath: keyPath.description) as? String ?? ""
}
let setter: (AnyObject, String) -> () = { host, newValue in
host.setValue(newValue, forKeyPath: keyPath.stringValue)
host.setValue(newValue, forKeyPath: keyPath.description)
}
return associatedProperty(host, key: keyPath.utf8Start, initial: initial, setter: setter)
}
Expand All @@ -33,13 +33,13 @@ public func associatedProperty(host: AnyObject, keyPath: StaticString) -> Mutabl
///
/// This can be used as an alternative to `DynamicProperty` for creating strongly typed
/// bindings on Cocoa objects.
@warn_unused_result(message="Did you forget to use the property?")
public func associatedProperty<T: AnyObject>(host: AnyObject, keyPath: StaticString, @noescape placeholder: () -> T) -> MutableProperty<T> {
public func associatedProperty<T>(_ host: AnyObject, keyPath: StaticString, placeholder: () -> T) -> MutableProperty<T> {
let setter: (AnyObject, T) -> () = { host, newValue in
host.setValue(newValue, forKeyPath: keyPath.stringValue)
host.setValue(newValue, forKeyPath: keyPath.description)
}

return associatedProperty(host, key: keyPath.utf8Start, initial: { host in
host.valueForKeyPath(keyPath.stringValue) as? T ?? placeholder()
host.value(forKeyPath: keyPath.description) as? T ?? placeholder()
}, setter: setter)
}

Expand All @@ -49,14 +49,13 @@ public func associatedProperty<T: AnyObject>(host: AnyObject, keyPath: StaticStr
///
/// This can be used as an alternative to `DynamicProperty` for creating strongly typed
/// bindings on Cocoa objects.
@warn_unused_result(message="Did you forget to use the property?")
public func associatedProperty<Host: AnyObject, T>(host: Host, key: UnsafePointer<()>, @noescape initial: Host -> T, setter: (Host, T) -> (), @noescape setUp: MutableProperty<T> -> () = { _ in }) -> MutableProperty<T> {
public func associatedProperty<Host: AnyObject, T>(_ host: Host, key: UnsafeRawPointer, initial: (Host) -> T, setter: @escaping (Host, T) -> (), setUp: (MutableProperty<T>) -> () = { _ in }) -> MutableProperty<T> {
return associatedObject(host, key: key) { host in
let property = MutableProperty(initial(host))

setUp(property)

property.producer.startWithNext { [weak host] next in
property.producer.startWithValues { [weak host] next in
if let host = host {
setter(host, next)
}
Expand All @@ -69,7 +68,7 @@ public func associatedProperty<Host: AnyObject, T>(host: Host, key: UnsafePointe
/// On first use attaches the object returned from `initial` to the `host` object using
/// `key` via `objc_setAssociatedObject`. On subsequent usage, returns said object via
/// `objc_getAssociatedObject`.
public func associatedObject<Host: AnyObject, T: AnyObject>(host: Host, key: UnsafePointer<()>, @noescape initial: Host -> T) -> T {
public func associatedObject<Host: AnyObject, T>(_ host: Host, key: UnsafeRawPointer, initial: (Host) -> T) -> T {
var value = objc_getAssociatedObject(host, key) as? T
if value == nil {
value = initial(host)
Expand Down
13 changes: 6 additions & 7 deletions Source/Foundation/NSData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,18 @@
// Copyright (c) 2015 Neil Pankey. All rights reserved.
//

import ReactiveCocoa
import ReactiveSwift

extension NSData {
extension Data {
/// Read the data at the URL, sending the result or an error.
@warn_unused_result(message="Did you forget to call `start` on the producer?")
public class func rex_dataWithContentsOfURL(url: NSURL, options: NSDataReadingOptions = NSDataReadingOptions()) -> SignalProducer<NSData, NSError> {
public static func rex_dataWithContentsOfURL(_ url: NSURL, options: NSData.ReadingOptions = NSData.ReadingOptions()) -> SignalProducer<NSData, NSError> {
return SignalProducer<NSData, NSError> { observer, disposable in
do {
let data = try NSData(contentsOfURL: url, options: options)
observer.sendNext(data)
let data = try NSData(contentsOf: url as URL, options: options)
observer.send(value: data)
observer.sendCompleted()
} catch {
observer.sendFailed(error as NSError)
observer.send(error: error as NSError)
}
}
}
Expand Down
Loading