Created
August 7, 2015 00:42
-
-
Save russbishop/3849a724dea01236262f to your computer and use it in GitHub Desktop.
RAC 3.0 Swift Extensions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ReactiveCocoa+PlanGrid.swift | |
// PlanGrid | |
// | |
// Created by Russ Bishop on 7/28/15. | |
// Copyright (c) 2015 PlanGrid. All rights reserved. | |
// | |
import Foundation | |
import ReactiveCocoa | |
/// Wraps the function as a producer; typically the function calls another function | |
/// that takes an error pointer and returns false or nil if it fails. This is convenient for | |
/// avoiding boilerplate. | |
/// :param: background if true, function is run asynchronously in the background and events are delivered on the UI thread. | |
/// :param: f The function to execute; must return a value OR return nil and set the error pointer to a valid NSError. | |
/// Failure to follow this rule will result in a crash. | |
func asProducer<T>(background: Bool = false, f:(NSErrorPointer)->T?) -> SignalProducer<T, NSError> { | |
let exec = background ? { (g:()->Void) in dispatch_background { g() } } : { g in g() } | |
var producer = SignalProducer<T, NSError> { sink, disposable in | |
exec({ | |
var error: NSErrorPointer = nil | |
if let nextValue = f(error) { | |
sendNext(sink, nextValue) | |
sendCompleted(sink) | |
} else if let error = error.memory { | |
sendError(sink, error) | |
} else { | |
assert(false, "On failure expected an error") | |
sendError(sink, PlanGridErrors.EmptyData.error()) | |
} | |
}) | |
} | |
if background { | |
producer = producer |> observeOn(uiScheduler) | |
} | |
return producer | |
} | |
/// Wraps the function as a producer; typically the function calls another function | |
/// that takes an error pointer and returns true if it succeeds or false if it fails | |
/// :param: background if true, function is run asynchronously in the background and events are delivered on the UI thread. | |
/// :param: f The function to execute; must (return true) OR (return false and set the error pointer to a valid NSError). | |
/// Failure to follow this rule will result in a crash. | |
func asProducer(background: Bool = false, f:(NSErrorPointer)->Bool) -> SignalProducer<Void, NSError> { | |
return asProducer(background: background, { errPtr in | |
return f(errPtr) ? () : nil | |
}) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
import XCTest | |
import ReactiveCocoa | |
func failOnError<T, E>(file: String = __FILE__, line: Int = __LINE__) -> SignalProducer<T, E> -> SignalProducer<T, E> { | |
return { | |
$0 |> on(error: { err in XCTAssert(false, "[\(file):\(line)] Signal error: \(err)") }) | |
} | |
} | |
func failOnInterrupted<T, E>(file: String = __FILE__, line: Int = __LINE__) -> SignalProducer<T, E> -> SignalProducer<T, E> { | |
return { | |
$0 |> on(interrupted: { XCTAssert(false, "[\(file):\(line)] Signal interrupted!") }) | |
} | |
} | |
func fulfillOnComplete<T, E>(expectation: XCTestExpectation) -> SignalProducer<T, E> -> SignalProducer<T, E> { | |
return { | |
$0 |> on(completed: { expectation.fulfill() }) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment