RACSignal.h 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508
  1. //
  2. // RACSignal.h
  3. // ReactiveObjC
  4. //
  5. // Created by Josh Abernathy on 3/1/12.
  6. // Copyright (c) 2012 GitHub, Inc. All rights reserved.
  7. //
  8. #import <Foundation/Foundation.h>
  9. #import "RACAnnotations.h"
  10. #import "RACStream.h"
  11. @class RACDisposable;
  12. @class RACScheduler;
  13. @class RACSubject;
  14. @class RACTuple;
  15. @class RACTwoTuple<__covariant First, __covariant Second>;
  16. @protocol RACSubscriber;
  17. NS_ASSUME_NONNULL_BEGIN
  18. @interface RACSignal<__covariant ValueType> : RACStream
  19. /// Creates a new signal. This is the preferred way to create a new signal
  20. /// operation or behavior.
  21. ///
  22. /// Events can be sent to new subscribers immediately in the `didSubscribe`
  23. /// block, but the subscriber will not be able to dispose of the signal until
  24. /// a RACDisposable is returned from `didSubscribe`. In the case of infinite
  25. /// signals, this won't _ever_ happen if events are sent immediately.
  26. ///
  27. /// To ensure that the signal is disposable, events can be scheduled on the
  28. /// +[RACScheduler currentScheduler] (so that they're deferred, not sent
  29. /// immediately), or they can be sent in the background. The RACDisposable
  30. /// returned by the `didSubscribe` block should cancel any such scheduling or
  31. /// asynchronous work.
  32. ///
  33. /// didSubscribe - Called when the signal is subscribed to. The new subscriber is
  34. /// passed in. You can then manually control the <RACSubscriber> by
  35. /// sending it -sendNext:, -sendError:, and -sendCompleted,
  36. /// as defined by the operation you're implementing. This block
  37. /// should return a RACDisposable which cancels any ongoing work
  38. /// triggered by the subscription, and cleans up any resources or
  39. /// disposables created as part of it. When the disposable is
  40. /// disposed of, the signal must not send any more events to the
  41. /// `subscriber`. If no cleanup is necessary, return nil.
  42. ///
  43. /// **Note:** The `didSubscribe` block is called every time a new subscriber
  44. /// subscribes. Any side effects within the block will thus execute once for each
  45. /// subscription, not necessarily on one thread, and possibly even
  46. /// simultaneously!
  47. + (RACSignal<ValueType> *)createSignal:(RACDisposable * _Nullable (^)(id<RACSubscriber> subscriber))didSubscribe RAC_WARN_UNUSED_RESULT;
  48. /// Returns a signal that immediately sends the given error.
  49. + (RACSignal<ValueType> *)error:(nullable NSError *)error RAC_WARN_UNUSED_RESULT;
  50. /// Returns a signal that never completes.
  51. + (RACSignal<ValueType> *)never RAC_WARN_UNUSED_RESULT;
  52. /// Immediately schedules the given block on the given scheduler. The block is
  53. /// given a subscriber to which it can send events.
  54. ///
  55. /// scheduler - The scheduler on which `block` will be scheduled and results
  56. /// delivered. Cannot be nil.
  57. /// block - The block to invoke. Cannot be NULL.
  58. ///
  59. /// Returns a signal which will send all events sent on the subscriber given to
  60. /// `block`. All events will be sent on `scheduler` and it will replay any missed
  61. /// events to new subscribers.
  62. + (RACSignal<ValueType> *)startEagerlyWithScheduler:(RACScheduler *)scheduler block:(void (^)(id<RACSubscriber> subscriber))block;
  63. /// Invokes the given block only on the first subscription. The block is given a
  64. /// subscriber to which it can send events.
  65. ///
  66. /// Note that disposing of the subscription to the returned signal will *not*
  67. /// dispose of the underlying subscription. If you need that behavior, see
  68. /// -[RACMulticastConnection autoconnect]. The underlying subscription will never
  69. /// be disposed of. Because of this, `block` should never return an infinite
  70. /// signal since there would be no way of ending it.
  71. ///
  72. /// scheduler - The scheduler on which the block should be scheduled. Note that
  73. /// if given +[RACScheduler immediateScheduler], the block will be
  74. /// invoked synchronously on the first subscription. Cannot be nil.
  75. /// block - The block to invoke on the first subscription. Cannot be NULL.
  76. ///
  77. /// Returns a signal which will pass through the events sent to the subscriber
  78. /// given to `block` and replay any missed events to new subscribers.
  79. + (RACSignal<ValueType> *)startLazilyWithScheduler:(RACScheduler *)scheduler block:(void (^)(id<RACSubscriber> subscriber))block RAC_WARN_UNUSED_RESULT;
  80. @end
  81. @interface RACSignal<__covariant ValueType> (RACStream)
  82. /// Returns a signal that immediately sends the given value and then completes.
  83. + (RACSignal<ValueType> *)return:(nullable ValueType)value RAC_WARN_UNUSED_RESULT;
  84. /// Returns a signal that immediately completes.
  85. + (RACSignal<ValueType> *)empty RAC_WARN_UNUSED_RESULT;
  86. /// A block which accepts a value from a RACSignal and returns a new signal.
  87. ///
  88. /// Setting `stop` to `YES` will cause the bind to terminate after the returned
  89. /// value. Returning `nil` will result in immediate termination.
  90. typedef RACSignal * _Nullable (^RACSignalBindBlock)(ValueType _Nullable value, BOOL *stop);
  91. /// Lazily binds a block to the values in the receiver.
  92. ///
  93. /// This should only be used if you need to terminate the bind early, or close
  94. /// over some state. -flattenMap: is more appropriate for all other cases.
  95. ///
  96. /// block - A block returning a RACSignalBindBlock. This block will be invoked
  97. /// each time the bound signal is re-evaluated. This block must not be
  98. /// nil or return nil.
  99. ///
  100. /// Returns a new signal which represents the combined result of all lazy
  101. /// applications of `block`.
  102. - (RACSignal *)bind:(RACSignalBindBlock (^)(void))block RAC_WARN_UNUSED_RESULT;
  103. /// Subscribes to `signal` when the source signal completes.
  104. - (RACSignal *)concat:(RACSignal *)signal RAC_WARN_UNUSED_RESULT;
  105. /// Zips the values in the receiver with those of the given signal to create
  106. /// RACTuples.
  107. ///
  108. /// The first `next` of each signal will be combined, then the second `next`,
  109. /// and so forth, until either signal completes or errors.
  110. ///
  111. /// signal - The signal to zip with. This must not be `nil`.
  112. ///
  113. /// Returns a new signal of RACTuples, representing the combined values of the
  114. /// two signals. Any error from one of the original signals will be forwarded on
  115. /// the returned signal.
  116. - (RACSignal<RACTwoTuple<ValueType, id> *> *)zipWith:(RACSignal *)signal RAC_WARN_UNUSED_RESULT;
  117. @end
  118. /// Redeclarations of operations built on the RACStream primitives with more
  119. /// precise ValueType information.
  120. ///
  121. /// In cases where the ValueType of the result of the operation is not able to
  122. /// be inferred, the ValueType is erased in the result.
  123. ///
  124. /// In cases where instancetype is a valid return type, the operation is not
  125. /// redeclared here.
  126. @interface RACSignal<__covariant ValueType> (RACStreamOperations)
  127. /// Maps `block` across the values in the receiver and flattens the result.
  128. ///
  129. /// Note that operators applied _after_ -flattenMap: behave differently from
  130. /// operators _within_ -flattenMap:. See the Examples section below.
  131. ///
  132. /// This corresponds to the `SelectMany` method in Rx.
  133. ///
  134. /// block - A block which accepts the values in the receiver and returns a new
  135. /// instance of the receiver's class. Returning `nil` from this block is
  136. /// equivalent to returning an empty signal.
  137. ///
  138. /// Examples
  139. ///
  140. /// [signal flattenMap:^(id x) {
  141. /// // Logs each time a returned signal completes.
  142. /// return [[RACSignal return:x] logCompleted];
  143. /// }];
  144. ///
  145. /// [[signal
  146. /// flattenMap:^(id x) {
  147. /// return [RACSignal return:x];
  148. /// }]
  149. /// // Logs only once, when all of the signals complete.
  150. /// logCompleted];
  151. ///
  152. /// Returns a new signal which represents the combined signals resulting from
  153. /// mapping `block`.
  154. - (RACSignal *)flattenMap:(__kindof RACSignal * _Nullable (^)(ValueType _Nullable value))block RAC_WARN_UNUSED_RESULT;
  155. /// Flattens a signal of signals.
  156. ///
  157. /// This corresponds to the `Merge` method in Rx.
  158. ///
  159. /// Returns a signal consisting of the combined signals obtained from the
  160. /// receiver.
  161. - (RACSignal *)flatten RAC_WARN_UNUSED_RESULT;
  162. /// Maps `block` across the values in the receiver.
  163. ///
  164. /// This corresponds to the `Select` method in Rx.
  165. ///
  166. /// Returns a new signal with the mapped values.
  167. - (RACSignal *)map:(id _Nullable (^)(ValueType _Nullable value))block RAC_WARN_UNUSED_RESULT;
  168. /// Replaces each value in the receiver with the given object.
  169. ///
  170. /// Returns a new signal which includes the given object once for each value in
  171. /// the receiver.
  172. - (RACSignal *)mapReplace:(nullable id)object RAC_WARN_UNUSED_RESULT;
  173. /// Filters out values in the receiver that don't pass the given test.
  174. ///
  175. /// This corresponds to the `Where` method in Rx.
  176. ///
  177. /// Returns a new signal with only those values that passed.
  178. - (RACSignal<ValueType> *)filter:(BOOL (^)(ValueType _Nullable value))block RAC_WARN_UNUSED_RESULT;
  179. /// Filters out values in the receiver that equal (via -isEqual:) the provided
  180. /// value.
  181. ///
  182. /// value - The value can be `nil`, in which case it ignores `nil` values.
  183. ///
  184. /// Returns a new signal containing only the values which did not compare equal
  185. /// to `value`.
  186. - (RACSignal<ValueType> *)ignore:(nullable ValueType)value RAC_WARN_UNUSED_RESULT;
  187. /// Unpacks each RACTuple in the receiver and maps the values to a new value.
  188. ///
  189. /// reduceBlock - The block which reduces each RACTuple's values into one value.
  190. /// It must take as many arguments as the number of tuple elements
  191. /// to process. Each argument will be an object argument. The
  192. /// return value must be an object. This argument cannot be nil.
  193. ///
  194. /// Returns a new signal of reduced tuple values.
  195. - (RACSignal *)reduceEach:(RACReduceBlock)reduceBlock RAC_WARN_UNUSED_RESULT;
  196. /// Returns a signal consisting of `value`, followed by the values in the
  197. /// receiver.
  198. - (RACSignal<ValueType> *)startWith:(nullable ValueType)value RAC_WARN_UNUSED_RESULT;
  199. /// Skips the first `skipCount` values in the receiver.
  200. ///
  201. /// Returns the receiver after skipping the first `skipCount` values. If
  202. /// `skipCount` is greater than the number of values in the signal, an empty
  203. /// signal is returned.
  204. - (RACSignal<ValueType> *)skip:(NSUInteger)skipCount RAC_WARN_UNUSED_RESULT;
  205. /// Returns a signal of the first `count` values in the receiver. If `count` is
  206. /// greater than or equal to the number of values in the signal, a signal
  207. /// equivalent to the receiver is returned.
  208. - (RACSignal<ValueType> *)take:(NSUInteger)count RAC_WARN_UNUSED_RESULT;
  209. /// Zips the values in the given signals to create RACTuples.
  210. ///
  211. /// The first value of each signals will be combined, then the second value, and
  212. /// so forth, until at least one of the signals is exhausted.
  213. ///
  214. /// signals - The signals to combine. If this collection is empty, the returned
  215. /// signal will be empty.
  216. ///
  217. /// Returns a new signal containing RACTuples of the zipped values from the
  218. /// signals.
  219. + (RACSignal<RACTuple *> *)zip:(id<NSFastEnumeration>)signals RAC_WARN_UNUSED_RESULT;
  220. /// Zips signals using +zip:, then reduces the resulting tuples into a single
  221. /// value using -reduceEach:
  222. ///
  223. /// signals - The signals to combine. If this collection is empty, the
  224. /// returned signal will be empty.
  225. /// reduceBlock - The block which reduces the values from all the signals
  226. /// into one value. It must take as many arguments as the
  227. /// number of signals given. Each argument will be an object
  228. /// argument. The return value must be an object. This argument
  229. /// must not be nil.
  230. ///
  231. /// Example:
  232. ///
  233. /// [RACSignal zip:@[ stringSignal, intSignal ]
  234. /// reduce:^(NSString *string, NSNumber *number) {
  235. /// return [NSString stringWithFormat:@"%@: %@", string, number];
  236. /// }];
  237. ///
  238. /// Returns a new signal containing the results from each invocation of
  239. /// `reduceBlock`.
  240. + (RACSignal<ValueType> *)zip:(id<NSFastEnumeration>)signals reduce:(RACGenericReduceBlock)reduceBlock RAC_WARN_UNUSED_RESULT;
  241. /// Returns a signal obtained by concatenating `signals` in order.
  242. + (RACSignal<ValueType> *)concat:(id<NSFastEnumeration>)signals RAC_WARN_UNUSED_RESULT;
  243. /// Combines values in the receiver from left to right using the given block.
  244. ///
  245. /// The algorithm proceeds as follows:
  246. ///
  247. /// 1. `startingValue` is passed into the block as the `running` value, and the
  248. /// first element of the receiver is passed into the block as the `next` value.
  249. /// 2. The result of the invocation is added to the returned signal.
  250. /// 3. The result of the invocation (`running`) and the next element of the
  251. /// receiver (`next`) is passed into `block`.
  252. /// 4. Steps 2 and 3 are repeated until all values have been processed.
  253. ///
  254. /// startingValue - The value to be combined with the first element of the
  255. /// receiver. This value may be `nil`.
  256. /// reduceBlock - The block that describes how to combine values of the
  257. /// receiver. If the receiver is empty, this block will never be
  258. /// invoked. Cannot be nil.
  259. ///
  260. /// Examples
  261. ///
  262. /// RACSequence *numbers = @[ @1, @2, @3, @4 ].rac_sequence;
  263. ///
  264. /// // Contains 1, 3, 6, 10
  265. /// RACSequence *sums = [numbers scanWithStart:@0 reduce:^(NSNumber *sum, NSNumber *next) {
  266. /// return @(sum.integerValue + next.integerValue);
  267. /// }];
  268. ///
  269. /// Returns a new signal that consists of each application of `reduceBlock`. If
  270. /// the receiver is empty, an empty signal is returned.
  271. - (RACSignal *)scanWithStart:(nullable id)startingValue reduce:(id _Nullable (^)(id _Nullable running, ValueType _Nullable next))reduceBlock RAC_WARN_UNUSED_RESULT;
  272. /// Combines values in the receiver from left to right using the given block
  273. /// which also takes zero-based index of the values.
  274. ///
  275. /// startingValue - The value to be combined with the first element of the
  276. /// receiver. This value may be `nil`.
  277. /// reduceBlock - The block that describes how to combine values of the
  278. /// receiver. This block takes zero-based index value as the last
  279. /// parameter. If the receiver is empty, this block will never
  280. /// be invoked. Cannot be nil.
  281. ///
  282. /// Returns a new signal that consists of each application of `reduceBlock`. If
  283. /// the receiver is empty, an empty signal is returned.
  284. - (RACSignal *)scanWithStart:(nullable id)startingValue reduceWithIndex:(id _Nullable (^)(id _Nullable running, ValueType _Nullable next, NSUInteger index))reduceBlock RAC_WARN_UNUSED_RESULT;
  285. /// Combines each previous and current value into one object.
  286. ///
  287. /// This method is similar to -scanWithStart:reduce:, but only ever operates on
  288. /// the previous and current values (instead of the whole signal), and does not
  289. /// pass the return value of `reduceBlock` into the next invocation of it.
  290. ///
  291. /// start - The value passed into `reduceBlock` as `previous` for the
  292. /// first value.
  293. /// reduceBlock - The block that combines the previous value and the current
  294. /// value to create the reduced value. Cannot be nil.
  295. ///
  296. /// Examples
  297. ///
  298. /// RACSignal<NSNumber *> *numbers = [@[ @1, @2, @3, @4 ].rac_sequence
  299. /// signalWithScheduler:RACScheduler.immediateScheduler];
  300. ///
  301. /// // Contains 1, 3, 5, 7
  302. /// RACSignal *sums = [numbers combinePreviousWithStart:@0 reduce:^(NSNumber *previous, NSNumber *next) {
  303. /// return @(previous.integerValue + next.integerValue);
  304. /// }];
  305. ///
  306. /// Returns a new signal consisting of the return values from each application of
  307. /// `reduceBlock`.
  308. - (RACSignal *)combinePreviousWithStart:(nullable ValueType)start reduce:(id _Nullable (^)(ValueType _Nullable previous, ValueType _Nullable current))reduceBlock RAC_WARN_UNUSED_RESULT;
  309. /// Takes values until the given block returns `YES`.
  310. ///
  311. /// Returns a signal of the initial values in the receiver that fail `predicate`.
  312. /// If `predicate` never returns `YES`, a signal equivalent to the receiver is
  313. /// returned.
  314. - (RACSignal<ValueType> *)takeUntilBlock:(BOOL (^)(ValueType _Nullable x))predicate RAC_WARN_UNUSED_RESULT;
  315. /// Takes values until the given block returns `NO`.
  316. ///
  317. /// Returns a signal of the initial values in the receiver that pass `predicate`.
  318. /// If `predicate` never returns `NO`, a signal equivalent to the receiver is
  319. /// returned.
  320. - (RACSignal<ValueType> *)takeWhileBlock:(BOOL (^)(ValueType _Nullable x))predicate RAC_WARN_UNUSED_RESULT;
  321. /// Skips values until the given block returns `YES`.
  322. ///
  323. /// Returns a signal containing the values of the receiver that follow any
  324. /// initial values failing `predicate`. If `predicate` never returns `YES`,
  325. /// an empty signal is returned.
  326. - (RACSignal<ValueType> *)skipUntilBlock:(BOOL (^)(ValueType _Nullable x))predicate RAC_WARN_UNUSED_RESULT;
  327. /// Skips values until the given block returns `NO`.
  328. ///
  329. /// Returns a signal containing the values of the receiver that follow any
  330. /// initial values passing `predicate`. If `predicate` never returns `NO`, an
  331. /// empty signal is returned.
  332. - (RACSignal<ValueType> *)skipWhileBlock:(BOOL (^)(ValueType _Nullable x))predicate RAC_WARN_UNUSED_RESULT;
  333. /// Returns a signal of values for which -isEqual: returns NO when compared to the
  334. /// previous value.
  335. - (RACSignal<ValueType> *)distinctUntilChanged RAC_WARN_UNUSED_RESULT;
  336. @end
  337. @interface RACSignal<__covariant ValueType> (Subscription)
  338. /// Subscribes `subscriber` to changes on the receiver. The receiver defines which
  339. /// events it actually sends and in what situations the events are sent.
  340. ///
  341. /// Subscription will always happen on a valid RACScheduler. If the
  342. /// +[RACScheduler currentScheduler] cannot be determined at the time of
  343. /// subscription (e.g., because the calling code is running on a GCD queue or
  344. /// NSOperationQueue), subscription will occur on a private background scheduler.
  345. /// On the main thread, subscriptions will always occur immediately, with a
  346. /// +[RACScheduler currentScheduler] of +[RACScheduler mainThreadScheduler].
  347. ///
  348. /// This method must be overridden by any subclasses.
  349. ///
  350. /// Returns nil or a disposable. You can call -[RACDisposable dispose] if you
  351. /// need to end your subscription before it would "naturally" end, either by
  352. /// completing or erroring. Once the disposable has been disposed, the subscriber
  353. /// won't receive any more events from the subscription.
  354. - (RACDisposable *)subscribe:(id<RACSubscriber>)subscriber;
  355. /// Convenience method to subscribe to the `next` event.
  356. ///
  357. /// This corresponds to `IObserver<T>.OnNext` in Rx.
  358. - (RACDisposable *)subscribeNext:(void (^)(ValueType _Nullable x))nextBlock;
  359. /// Convenience method to subscribe to the `next` and `completed` events.
  360. - (RACDisposable *)subscribeNext:(void (^)(ValueType _Nullable x))nextBlock completed:(void (^)(void))completedBlock;
  361. /// Convenience method to subscribe to the `next`, `completed`, and `error` events.
  362. - (RACDisposable *)subscribeNext:(void (^)(ValueType _Nullable x))nextBlock error:(void (^)(NSError * _Nullable error))errorBlock completed:(void (^)(void))completedBlock;
  363. /// Convenience method to subscribe to `error` events.
  364. ///
  365. /// This corresponds to the `IObserver<T>.OnError` in Rx.
  366. - (RACDisposable *)subscribeError:(void (^)(NSError * _Nullable error))errorBlock;
  367. /// Convenience method to subscribe to `completed` events.
  368. ///
  369. /// This corresponds to the `IObserver<T>.OnCompleted` in Rx.
  370. - (RACDisposable *)subscribeCompleted:(void (^)(void))completedBlock;
  371. /// Convenience method to subscribe to `next` and `error` events.
  372. - (RACDisposable *)subscribeNext:(void (^)(ValueType _Nullable x))nextBlock error:(void (^)(NSError * _Nullable error))errorBlock;
  373. /// Convenience method to subscribe to `error` and `completed` events.
  374. - (RACDisposable *)subscribeError:(void (^)(NSError * _Nullable error))errorBlock completed:(void (^)(void))completedBlock;
  375. @end
  376. /// Additional methods to assist with debugging.
  377. @interface RACSignal<__covariant ValueType> (Debugging)
  378. /// Logs all events that the receiver sends.
  379. - (RACSignal<ValueType> *)logAll RAC_WARN_UNUSED_RESULT;
  380. /// Logs each `next` that the receiver sends.
  381. - (RACSignal<ValueType> *)logNext RAC_WARN_UNUSED_RESULT;
  382. /// Logs any error that the receiver sends.
  383. - (RACSignal<ValueType> *)logError RAC_WARN_UNUSED_RESULT;
  384. /// Logs any `completed` event that the receiver sends.
  385. - (RACSignal<ValueType> *)logCompleted RAC_WARN_UNUSED_RESULT;
  386. @end
  387. /// Additional methods to assist with unit testing.
  388. ///
  389. /// **These methods should never ship in production code.**
  390. @interface RACSignal<__covariant ValueType> (Testing)
  391. /// Spins the main run loop for a short while, waiting for the receiver to send a `next`
  392. /// or the provided timeout to elapse.
  393. ///
  394. /// **Because this method executes the run loop recursively, it should only be used
  395. /// on the main thread, and only from a unit test.**
  396. ///
  397. /// defaultValue - Returned if the receiver completes or errors before sending
  398. /// a `next`, or if the method times out. This argument may be
  399. /// nil.
  400. /// success - If not NULL, set to whether the receiver completed
  401. /// successfully.
  402. /// error - If not NULL, set to any error that occurred.
  403. ///
  404. /// Returns the first value received, or `defaultValue` if no value is received
  405. /// before the signal finishes or the method times out.
  406. - (nullable ValueType)asynchronousFirstOrDefault:(nullable ValueType)defaultValue success:(nullable BOOL *)success error:(NSError * _Nullable * _Nullable)error timeout:(NSTimeInterval)timeout;
  407. /// Spins the main run loop for a short while, waiting for the receiver to send a `next`.
  408. ///
  409. /// **Because this method executes the run loop recursively, it should only be used
  410. /// on the main thread, and only from a unit test.**
  411. ///
  412. /// defaultValue - Returned if the receiver completes or errors before sending
  413. /// a `next`, or if the method times out. This argument may be
  414. /// nil.
  415. /// success - If not NULL, set to whether the receiver completed
  416. /// successfully.
  417. /// error - If not NULL, set to any error that occurred.
  418. ///
  419. /// Returns the first value received, or `defaultValue` if no value is received
  420. /// before the signal finishes or the method times out.
  421. - (nullable ValueType)asynchronousFirstOrDefault:(nullable ValueType)defaultValue success:(nullable BOOL *)success error:(NSError * _Nullable * _Nullable)error;
  422. /// Spins the main run loop for a short while, waiting for the receiver to complete.
  423. /// or the provided timeout to elapse.
  424. ///
  425. /// **Because this method executes the run loop recursively, it should only be used
  426. /// on the main thread, and only from a unit test.**
  427. ///
  428. /// error - If not NULL, set to any error that occurs.
  429. ///
  430. /// Returns whether the signal completed successfully before timing out. If NO,
  431. /// `error` will be set to any error that occurred.
  432. - (BOOL)asynchronouslyWaitUntilCompleted:(NSError * _Nullable * _Nullable)error timeout:(NSTimeInterval)timeout;
  433. /// Spins the main run loop for a short while, waiting for the receiver to complete
  434. ///
  435. /// **Because this method executes the run loop recursively, it should only be used
  436. /// on the main thread, and only from a unit test.**
  437. ///
  438. /// error - If not NULL, set to any error that occurs.
  439. ///
  440. /// Returns whether the signal completed successfully before timing out. If NO,
  441. /// `error` will be set to any error that occurred.
  442. - (BOOL)asynchronouslyWaitUntilCompleted:(NSError * _Nullable * _Nullable)error;
  443. @end
  444. NS_ASSUME_NONNULL_END