Skip to content

Commit

Permalink
Merge pull request #98 from jcavar/master
Browse files Browse the repository at this point in the history
Add async wait methods that support custom timeout
  • Loading branch information
erichoracek authored May 8, 2017
2 parents 709c938 + df25325 commit 11e068d
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 3 deletions.
29 changes: 29 additions & 0 deletions ReactiveObjC/RACSignal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.**
Expand Down
14 changes: 11 additions & 3 deletions ReactiveObjC/RACSignal.m
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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

0 comments on commit 11e068d

Please sign in to comment.