Skip to content
Closed
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
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
language: objective-c
matrix:
include:
- osx_image: xcode7.3
- osx_image: xcode8

env:
global:
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.1
github "ReactiveCocoa/ReactiveCocoa" "RAC5-swift3"
4 changes: 2 additions & 2 deletions Cartfile.resolved
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
github "antitypical/Result" "2.1.1"
github "ReactiveCocoa/ReactiveCocoa" "v4.2.1"
github "antitypical/Result" "2fe88d1d41615ed060489e8cd06fc1b3e8f0ca53"
github "ReactiveCocoa/ReactiveCocoa" "3073a487acd53008a41b89ef6512040a1347212d"
45 changes: 45 additions & 0 deletions Deprecations+Removals.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// MARK: Renamed APIs in Swift 3.0
import ReactiveCocoa
import enum Result.NoError

extension SignalProtocol {
@available(*, unavailable, renamed:"mute(for:clock:)")
public func muteFor(_ interval: TimeInterval, clock: DateSchedulerProtocol) -> Signal<Value, Error> { fatalError() }

@available(*, unavailable, renamed:"timeout(after:with:on:)")
public func timeoutAfter(_ interval: TimeInterval, withEvent event: Event<Value, Error>, onScheduler scheduler: DateSchedulerProtocol) -> Signal<Value, Error> { fatalError() }
}

extension SignalProducerProtocol {
@available(*, unavailable, renamed:"mute(for:clock:)")
public func muteFor(_ interval: TimeInterval, clock: DateSchedulerProtocol) -> SignalProducer<Value, Error> { fatalError() }

@available(*, unavailable, renamed:"timeout(after:with:on:)")
public func timeoutAfter(_ interval: TimeInterval, withEvent event: Event<Value, Error>, onScheduler scheduler: DateSchedulerProtocol) -> SignalProducer<Value, Error> { fatalError() }

@available(*, unavailable, renamed:"group(by:)")
public func groupBy<Key: Hashable>(_ grouping: (Value) -> Key) -> SignalProducer<(Key, SignalProducer<Value, Error>), Error> { fatalError() }

@available(*, unavailable, renamed:"defer(by:on:)")
public func deferred(_ interval: TimeInterval, onScheduler scheduler: DateSchedulerProtocol) -> SignalProducer<Value, Error> { fatalError() }
}

extension UserDefaults {
@available(*, unavailable, renamed:"rex_value(forKey:)")
public func rex_valueForKey(_ key: String) -> SignalProducer<AnyObject?, NoError> { fatalError() }
}

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

extension Data {
@available(*, unavailable, renamed:"rex_data(contentsOf:options:)")
public static func rex_dataWithContentsOfURL(_ url: URL, options: Data.ReadingOptions = []) -> SignalProducer<Data, NSError> { fatalError() }
}

extension NSData {
@available(*, unavailable, renamed:"rex_data(contentsOf:options:)")
public static func rex_dataWithContentsOfURL(_ url: URL, options: NSData.ReadingOptions = []) -> SignalProducer<NSData, NSError> { fatalError() }
}
131 changes: 81 additions & 50 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 = "0800"
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 = "0800"
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 = "0800"
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 = "0800"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
8 changes: 4 additions & 4 deletions Source/Action.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ extension Action {

/// 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 @@ -43,11 +43,11 @@ extension CocoaAction {

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

/// Creates a producer for the `executing` state of a CocoaAction.
public var rex_executingProducer: SignalProducer<Bool, NoError> {
return rex_producerForKeyPath("executing")
return rex_producer(forKeyPath: #keyPath(CocoaAction.isExecuting))
}
}
4 changes: 2 additions & 2 deletions Source/AppKit/NSTextField.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import enum Result.NoError
extension NSTextField {
/// Sends the field's string value whenever it changes.
public var rex_textSignal: SignalProducer<String, NoError> {
return NSNotificationCenter.defaultCenter()
.rac_notifications(NSControlTextDidChangeNotification, object: self)
return NotificationCenter.default
.rac_notifications(forName: .NSControlTextDidChange, object: self)
.map { notification in
(notification.object as! NSTextField).stringValue
}
Expand Down
16 changes: 16 additions & 0 deletions Source/Bindings.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
public protocol BindingsProtocol {
associatedtype Owner: AnyObject

var owner: Owner { get }
}

public protocol BindablesProviding: class {}
extension BindablesProviding {
public var bindables: Bindables<Self> {
return Bindables(owner: self)
}
}

public struct Bindables<Owner: AnyObject>: BindingsProtocol {
public let owner: Owner
}
21 changes: 9 additions & 12 deletions Source/Foundation/Association.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,12 @@ 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: String(keyPath)) as? String ?? ""
}
let setter: (AnyObject, String) -> () = { host, newValue in
host.setValue(newValue, forKeyPath: keyPath.stringValue)
host.setValue(newValue, forKeyPath: String(keyPath))
}
return associatedProperty(host, key: keyPath.utf8Start, initial: initial, setter: setter)
}
Expand All @@ -33,13 +32,12 @@ 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: AnyObject>(_ host: AnyObject, keyPath: StaticString, placeholder: @noescape () -> T) -> MutableProperty<T> {
let setter: (AnyObject, T) -> () = { host, newValue in
host.setValue(newValue, forKeyPath: keyPath.stringValue)
host.setValue(newValue, forKeyPath: String(keyPath))
}
return associatedProperty(host, key: keyPath.utf8Start, initial: { host in
host.valueForKeyPath(keyPath.stringValue) as? T ?? placeholder()
host.value(forKeyPath: String(keyPath)) as? T ?? placeholder()
}, setter: setter)
}

Expand All @@ -49,8 +47,7 @@ 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: UnsafePointer<()>, initial: @noescape (Host) -> T, setter: (Host, T) -> (), setUp: @noescape (MutableProperty<T>) -> () = { _ in }) -> MutableProperty<T> {
return associatedObject(host, key: key) { host in
let property = MutableProperty(initial(host))

Expand All @@ -69,7 +66,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: AnyObject>(_ host: Host, key: UnsafePointer<()>, initial: @noescape (Host) -> T) -> T {
var value = objc_getAssociatedObject(host, key) as? T
if value == nil {
value = initial(host)
Expand Down
39 changes: 39 additions & 0 deletions Source/Foundation/Data.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//
// Data.swift
// Rex
//
// Created by Ilya Laryionau on 10/05/15.
// Copyright (c) 2015 Neil Pankey. All rights reserved.
//

import ReactiveCocoa

extension Data {
/// Read the data at the URL, sending the result or an error.
public static func rex_data(contentsOf url: URL, options: Data.ReadingOptions = []) -> SignalProducer<Data, NSError> {
return SignalProducer<Data, NSError> { observer, disposable in
do {
let data = try Data(contentsOf: url, options: options)
observer.sendNext(data)
observer.sendCompleted()
} catch {
observer.sendFailed(error as NSError)
}
}
}
}

extension NSData {
/// Read the data at the URL, sending the result or an error.
public static func rex_data(contentsOf url: URL, options: NSData.ReadingOptions = []) -> SignalProducer<NSData, NSError> {
return SignalProducer<NSData, NSError> { observer, disposable in
do {
let data = try NSData(contentsOf: url, options: options)
observer.sendNext(data)
observer.sendCompleted()
} catch {
observer.sendFailed(error as NSError)
}
}
}
}
7 changes: 3 additions & 4 deletions Source/Foundation/NSObject.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,15 @@ extension NSObject {
///
/// Swift classes deriving `NSObject` must declare properties as `dynamic` for
/// them to work with KVO. However, this is not recommended practice.
@warn_unused_result(message="Did you forget to call `start` on the producer?")
public func rex_producerForKeyPath<T>(keyPath: String) -> SignalProducer<T, NoError> {
return self.rac_valuesForKeyPath(keyPath, observer: nil)
public func rex_producer<T>(forKeyPath keyPath: String) -> SignalProducer<T, NoError> {
return self.rac_values(forKeyPath: keyPath, observer: nil)
.toSignalProducer()
.map { $0 as! T }
.flatMapError { error in
// Errors aren't possible, but the compiler doesn't know that.
assertionFailure("Unexpected error from KVO signal: \(error)")
return .empty
}
}
}

/// Creates a signal that will be triggered when the object
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,20 @@
import ReactiveCocoa
import enum Result.NoError

extension NSUserDefaults {
extension UserDefaults {
/// Sends value of `key` whenever it changes. Attempts to filter out repeats
/// by casting to NSObject and checking for equality. If the values aren't
/// convertible this will generate events whenever _any_ value in NSUserDefaults
/// changes.
@warn_unused_result(message="Did you forget to call `start` on the producer?")
public func rex_valueForKey(key: String) -> SignalProducer<AnyObject?, NoError> {
let center = NSNotificationCenter.defaultCenter()
let initial = objectForKey(key)
public func rex_value(forKey key: String) -> SignalProducer<AnyObject?, NoError> {
let center = NotificationCenter.default
let initial = object(forKey: key)

let changes = center.rac_notifications(NSUserDefaultsDidChangeNotification)
let changes = center.rac_notifications(forName: UserDefaults.didChangeNotification)
.map { _ in
// The notification doesn't provide what changed so we have to look
// it up every time
self.objectForKey(key)
self.object(forKey: key)
}

return SignalProducer<AnyObject?, NoError>(value: initial)
Expand Down
Loading