Skip to content

Instantly share code, notes, and snippets.

@russbishop
Created August 7, 2015 00:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save russbishop/3849a724dea01236262f to your computer and use it in GitHub Desktop.
Save russbishop/3849a724dea01236262f to your computer and use it in GitHub Desktop.
RAC 3.0 Swift Extensions
//
// 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
})
}
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