diff --git a/ReactiveObjC/RACSignal.h b/ReactiveObjC/RACSignal.h index 51acc6f3d..6fb5e03fe 100644 --- a/ReactiveObjC/RACSignal.h +++ b/ReactiveObjC/RACSignal.h @@ -447,6 +447,23 @@ typedef RACSignal * _Nullable (^RACSignalBindBlock)(ValueType _Nullable value, B /// **These methods should never ship in production code.** @interface RACSignal<__covariant ValueType> (Testing) +/// Spins the main run loop for a short while, waiting for the receiver to send a `next` +/// or the provided timeout to elapse. +/// +/// **Because this method executes the run loop recursively, it should only be used +/// on the main thread, and only from a unit test.** +/// +/// defaultValue - Returned if the receiver completes or errors before sending +/// a `next`, or if the method times out. This argument may be +/// nil. +/// success - If not NULL, set to whether the receiver completed +/// successfully. +/// error - If not NULL, set to any error that occurred. +/// +/// Returns the first value received, or `defaultValue` if no value is received +/// before the signal finishes or the method times out. +- (nullable ValueType)asynchronousFirstOrDefault:(nullable ValueType)defaultValue success:(nullable BOOL *)success error:(NSError * _Nullable * _Nullable)error timeout:(NSTimeInterval)timeout; + /// Spins the main run loop for a short while, waiting for the receiver to send a `next`. /// /// **Because this method executes the run loop recursively, it should only be used @@ -464,6 +481,18 @@ typedef RACSignal * _Nullable (^RACSignalBindBlock)(ValueType _Nullable value, B - (nullable ValueType)asynchronousFirstOrDefault:(nullable ValueType)defaultValue success:(nullable BOOL *)success error:(NSError * _Nullable * _Nullable)error; /// Spins the main run loop for a short while, waiting for the receiver to complete. +/// or the provided timeout to elapse. +/// +/// **Because this method executes the run loop recursively, it should only be used +/// on the main thread, and only from a unit test.** +/// +/// error - If not NULL, set to any error that occurs. +/// +/// Returns whether the signal completed successfully before timing out. If NO, +/// `error` will be set to any error that occurred. +- (BOOL)asynchronouslyWaitUntilCompleted:(NSError * _Nullable * _Nullable)error timeout:(NSTimeInterval)timeout; + +/// Spins the main run loop for a short while, waiting for the receiver to complete /// /// **Because this method executes the run loop recursively, it should only be used /// on the main thread, and only from a unit test.** diff --git a/ReactiveObjC/RACSignal.m b/ReactiveObjC/RACSignal.m index 89f125952..84607f681 100644 --- a/ReactiveObjC/RACSignal.m +++ b/ReactiveObjC/RACSignal.m @@ -356,6 +356,10 @@ @implementation RACSignal (Testing) static const NSTimeInterval RACSignalAsynchronousWaitTimeout = 10; - (id)asynchronousFirstOrDefault:(id)defaultValue success:(BOOL *)success error:(NSError **)error { + return [self asynchronousFirstOrDefault:defaultValue success:success error:error timeout:RACSignalAsynchronousWaitTimeout]; +} + +- (id)asynchronousFirstOrDefault:(id)defaultValue success:(BOOL *)success error:(NSError **)error timeout:(NSTimeInterval)timeout { NSCAssert([NSThread isMainThread], @"%s should only be used from the main thread", __func__); __block id result = defaultValue; @@ -367,7 +371,7 @@ - (id)asynchronousFirstOrDefault:(id)defaultValue success:(BOOL *)success error: [[[[self take:1] - timeout:RACSignalAsynchronousWaitTimeout onScheduler:[RACScheduler scheduler]] + timeout:timeout onScheduler:[RACScheduler scheduler]] deliverOn:RACScheduler.mainThreadScheduler] subscribeNext:^(id x) { result = x; @@ -392,10 +396,14 @@ - (id)asynchronousFirstOrDefault:(id)defaultValue success:(BOOL *)success error: return result; } -- (BOOL)asynchronouslyWaitUntilCompleted:(NSError **)error { +- (BOOL)asynchronouslyWaitUntilCompleted:(NSError **)error timeout:(NSTimeInterval)timeout { BOOL success = NO; - [[self ignoreValues] asynchronousFirstOrDefault:nil success:&success error:error]; + [[self ignoreValues] asynchronousFirstOrDefault:nil success:&success error:error timeout:timeout]; return success; } +- (BOOL)asynchronouslyWaitUntilCompleted:(NSError **)error { + return [self asynchronouslyWaitUntilCompleted:error timeout:RACSignalAsynchronousWaitTimeout]; +} + @end