RACSignal+Operations.h 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725
  1. //
  2. // RACSignal+Operations.h
  3. // ReactiveCocoa
  4. //
  5. // Created by Justin Spahr-Summers on 2012-09-06.
  6. // Copyright (c) 2012 GitHub, Inc. All rights reserved.
  7. //
  8. #import <Foundation/Foundation.h>
  9. #import "RACSignal.h"
  10. /// The domain for errors originating in RACSignal operations.
  11. extern NSString * const RACSignalErrorDomain;
  12. /// The error code used with -timeout:.
  13. extern const NSInteger RACSignalErrorTimedOut;
  14. /// The error code used when a value passed into +switch:cases:default: does not
  15. /// match any of the cases, and no default was given.
  16. extern const NSInteger RACSignalErrorNoMatchingCase;
  17. @class RACCommand;
  18. @class RACDisposable;
  19. @class RACMulticastConnection;
  20. @class RACScheduler;
  21. @class RACSequence;
  22. @class RACSubject;
  23. @class RACTuple;
  24. @protocol RACSubscriber;
  25. @interface RACSignal (Operations)
  26. /// Do the given block on `next`. This should be used to inject side effects into
  27. /// the signal.
  28. - (RACSignal *)doNext:(void (^)(id x))block;
  29. /// Do the given block on `error`. This should be used to inject side effects
  30. /// into the signal.
  31. - (RACSignal *)doError:(void (^)(NSError *error))block;
  32. /// Do the given block on `completed`. This should be used to inject side effects
  33. /// into the signal.
  34. - (RACSignal *)doCompleted:(void (^)(void))block;
  35. /// Sends `next`s only if we don't receive another `next` in `interval` seconds.
  36. ///
  37. /// If a `next` is received, and then another `next` is received before
  38. /// `interval` seconds have passed, the first value is discarded.
  39. ///
  40. /// After `interval` seconds have passed since the most recent `next` was sent,
  41. /// the most recent `next` is forwarded on the scheduler that the value was
  42. /// originally received on. If +[RACScheduler currentScheduler] was nil at the
  43. /// time, a private background scheduler is used.
  44. ///
  45. /// Returns a signal which sends throttled and delayed `next` events. Completion
  46. /// and errors are always forwarded immediately.
  47. - (RACSignal *)throttle:(NSTimeInterval)interval;
  48. /// Throttles `next`s for which `predicate` returns YES.
  49. ///
  50. /// When `predicate` returns YES for a `next`:
  51. ///
  52. /// 1. If another `next` is received before `interval` seconds have passed, the
  53. /// prior value is discarded. This happens regardless of whether the new
  54. /// value will be throttled.
  55. /// 2. After `interval` seconds have passed since the value was originally
  56. /// received, it will be forwarded on the scheduler that it was received
  57. /// upon. If +[RACScheduler currentScheduler] was nil at the time, a private
  58. /// background scheduler is used.
  59. ///
  60. /// When `predicate` returns NO for a `next`, it is forwarded immediately,
  61. /// without any throttling.
  62. ///
  63. /// interval - The number of seconds for which to buffer the latest value that
  64. /// passes `predicate`.
  65. /// predicate - Passed each `next` from the receiver, this block returns
  66. /// whether the given value should be throttled. This argument must
  67. /// not be nil.
  68. ///
  69. /// Returns a signal which sends `next` events, throttled when `predicate`
  70. /// returns YES. Completion and errors are always forwarded immediately.
  71. - (RACSignal *)throttle:(NSTimeInterval)interval valuesPassingTest:(BOOL (^)(id next))predicate;
  72. /// Forwards `next` and `completed` events after delaying for `interval` seconds
  73. /// on the current scheduler (on which the events were delivered).
  74. ///
  75. /// If +[RACScheduler currentScheduler] is nil when `next` or `completed` is
  76. /// received, a private background scheduler is used.
  77. ///
  78. /// Returns a signal which sends delayed `next` and `completed` events. Errors
  79. /// are always forwarded immediately.
  80. - (RACSignal *)delay:(NSTimeInterval)interval;
  81. /// Resubscribes when the signal completes.
  82. - (RACSignal *)repeat;
  83. /// Executes the given block each time a subscription is created.
  84. ///
  85. /// block - A block which defines the subscription side effects. Cannot be `nil`.
  86. ///
  87. /// Example:
  88. ///
  89. /// // Write new file, with backup.
  90. /// [[[[fileManager
  91. /// rac_createFileAtPath:path contents:data]
  92. /// initially:^{
  93. /// // 2. Second, backup current file
  94. /// [fileManager moveItemAtPath:path toPath:backupPath error:nil];
  95. /// }]
  96. /// initially:^{
  97. /// // 1. First, acquire write lock.
  98. /// [writeLock lock];
  99. /// }]
  100. /// finally:^{
  101. /// [writeLock unlock];
  102. /// }];
  103. ///
  104. /// Returns a signal that passes through all events of the receiver, plus
  105. /// introduces side effects which occur prior to any subscription side effects
  106. /// of the receiver.
  107. - (RACSignal *)initially:(void (^)(void))block;
  108. /// Executes the given block when the signal completes or errors.
  109. - (RACSignal *)finally:(void (^)(void))block;
  110. /// Divides the receiver's `next`s into buffers which deliver every `interval`
  111. /// seconds.
  112. ///
  113. /// interval - The interval in which values are grouped into one buffer.
  114. /// scheduler - The scheduler upon which the returned signal will deliver its
  115. /// values. This must not be nil or +[RACScheduler
  116. /// immediateScheduler].
  117. ///
  118. /// Returns a signal which sends RACTuples of the buffered values at each
  119. /// interval on `scheduler`. When the receiver completes, any currently-buffered
  120. /// values will be sent immediately.
  121. - (RACSignal *)bufferWithTime:(NSTimeInterval)interval onScheduler:(RACScheduler *)scheduler;
  122. /// Collects all receiver's `next`s into a NSArray. Nil values will be converted
  123. /// to NSNull.
  124. ///
  125. /// This corresponds to the `ToArray` method in Rx.
  126. ///
  127. /// Returns a signal which sends a single NSArray when the receiver completes
  128. /// successfully.
  129. - (RACSignal *)collect;
  130. /// Takes the last `count` `next`s after the receiving signal completes.
  131. - (RACSignal *)takeLast:(NSUInteger)count;
  132. /// Combines the latest values from the receiver and the given signal into
  133. /// RACTuples, once both have sent at least one `next`.
  134. ///
  135. /// Any additional `next`s will result in a new RACTuple with the latest values
  136. /// from both signals.
  137. ///
  138. /// signal - The signal to combine with. This argument must not be nil.
  139. ///
  140. /// Returns a signal which sends RACTuples of the combined values, forwards any
  141. /// `error` events, and completes when both input signals complete.
  142. - (RACSignal *)combineLatestWith:(RACSignal *)signal;
  143. /// Combines the latest values from the given signals into RACTuples, once all
  144. /// the signals have sent at least one `next`.
  145. ///
  146. /// Any additional `next`s will result in a new RACTuple with the latest values
  147. /// from all signals.
  148. ///
  149. /// signals - The signals to combine. If this collection is empty, the returned
  150. /// signal will immediately complete upon subscription.
  151. ///
  152. /// Returns a signal which sends RACTuples of the combined values, forwards any
  153. /// `error` events, and completes when all input signals complete.
  154. + (RACSignal *)combineLatest:(id<NSFastEnumeration>)signals;
  155. /// Combines signals using +combineLatest:, then reduces the resulting tuples
  156. /// into a single value using -reduceEach:.
  157. ///
  158. /// signals - The signals to combine. If this collection is empty, the
  159. /// returned signal will immediately complete upon subscription.
  160. /// reduceBlock - The block which reduces the latest values from all the
  161. /// signals into one value. It must take as many arguments as the
  162. /// number of signals given. Each argument will be an object
  163. /// argument. The return value must be an object. This argument
  164. /// must not be nil.
  165. ///
  166. /// Example:
  167. ///
  168. /// [RACSignal combineLatest:@[ stringSignal, intSignal ] reduce:^(NSString *string, NSNumber *number) {
  169. /// return [NSString stringWithFormat:@"%@: %@", string, number];
  170. /// }];
  171. ///
  172. /// Returns a signal which sends the results from each invocation of
  173. /// `reduceBlock`.
  174. + (RACSignal *)combineLatest:(id<NSFastEnumeration>)signals reduce:(id (^)())reduceBlock;
  175. /// Merges the receiver and the given signal with `+merge:` and returns the
  176. /// resulting signal.
  177. - (RACSignal *)merge:(RACSignal *)signal;
  178. /// Sends the latest `next` from any of the signals.
  179. ///
  180. /// Returns a signal that passes through values from each of the given signals,
  181. /// and sends `completed` when all of them complete. If any signal sends an error,
  182. /// the returned signal sends `error` immediately.
  183. + (RACSignal *)merge:(id<NSFastEnumeration>)signals;
  184. /// Merges the signals sent by the receiver into a flattened signal, but only
  185. /// subscribes to `maxConcurrent` number of signals at a time. New signals are
  186. /// queued and subscribed to as other signals complete.
  187. ///
  188. /// If an error occurs on any of the signals, it is sent on the returned signal.
  189. /// It completes only after the receiver and all sent signals have completed.
  190. ///
  191. /// This corresponds to `Merge<TSource>(IObservable<IObservable<TSource>>, Int32)`
  192. /// in Rx.
  193. ///
  194. /// maxConcurrent - the maximum number of signals to subscribe to at a
  195. /// time. If 0, it subscribes to an unlimited number of
  196. /// signals.
  197. - (RACSignal *)flatten:(NSUInteger)maxConcurrent;
  198. /// Ignores all `next`s from the receiver, waits for the receiver to complete,
  199. /// then subscribes to a new signal.
  200. ///
  201. /// block - A block which will create or obtain a new signal to subscribe to,
  202. /// executed only after the receiver completes. This block must not be
  203. /// nil, and it must not return a nil signal.
  204. ///
  205. /// Returns a signal which will pass through the events of the signal created in
  206. /// `block`. If the receiver errors out, the returned signal will error as well.
  207. - (RACSignal *)then:(RACSignal * (^)(void))block;
  208. /// Concats the inner signals of a signal of signals.
  209. - (RACSignal *)concat;
  210. /// Aggregates the `next` values of the receiver into a single combined value.
  211. ///
  212. /// The algorithm proceeds as follows:
  213. ///
  214. /// 1. `start` is passed into the block as the `running` value, and the first
  215. /// element of the receiver is passed into the block as the `next` value.
  216. /// 2. The result of the invocation (`running`) and the next element of the
  217. /// receiver (`next`) is passed into `reduceBlock`.
  218. /// 3. Steps 2 and 3 are repeated until all values have been processed.
  219. /// 4. The last result of `reduceBlock` is sent on the returned signal.
  220. ///
  221. /// This method is similar to -scanWithStart:reduce:, except that only the
  222. /// final result is sent on the returned signal.
  223. ///
  224. /// start - The value to be combined with the first element of the
  225. /// receiver. This value may be `nil`.
  226. /// reduceBlock - The block that describes how to combine values of the
  227. /// receiver. If the receiver is empty, this block will never be
  228. /// invoked. Cannot be nil.
  229. ///
  230. /// Returns a signal that will send the aggregated value when the receiver
  231. /// completes, then itself complete. If the receiver never sends any values,
  232. /// `start` will be sent instead.
  233. - (RACSignal *)aggregateWithStart:(id)start reduce:(id (^)(id running, id next))reduceBlock;
  234. /// Aggregates the `next` values of the receiver into a single combined value.
  235. /// This is indexed version of -aggregateWithStart:reduce:.
  236. ///
  237. /// start - The value to be combined with the first element of the
  238. /// receiver. This value may be `nil`.
  239. /// reduceBlock - The block that describes how to combine values of the
  240. /// receiver. This block takes zero-based index value as the last
  241. /// parameter. If the receiver is empty, this block will never be
  242. /// invoked. Cannot be nil.
  243. ///
  244. /// Returns a signal that will send the aggregated value when the receiver
  245. /// completes, then itself complete. If the receiver never sends any values,
  246. /// `start` will be sent instead.
  247. - (RACSignal *)aggregateWithStart:(id)start reduceWithIndex:(id (^)(id running, id next, NSUInteger index))reduceBlock;
  248. /// Aggregates the `next` values of the receiver into a single combined value.
  249. ///
  250. /// This invokes `startFactory` block on each subscription, then calls
  251. /// -aggregateWithStart:reduce: with the return value of the block as start value.
  252. ///
  253. /// startFactory - The block that returns start value which will be combined
  254. /// with the first element of the receiver. Cannot be nil.
  255. /// reduceBlock - The block that describes how to combine values of the
  256. /// receiver. If the receiver is empty, this block will never be
  257. /// invoked. Cannot be nil.
  258. ///
  259. /// Returns a signal that will send the aggregated value when the receiver
  260. /// completes, then itself complete. If the receiver never sends any values,
  261. /// the return value of `startFactory` will be sent instead.
  262. - (RACSignal *)aggregateWithStartFactory:(id (^)(void))startFactory reduce:(id (^)(id running, id next))reduceBlock;
  263. /// Invokes -setKeyPath:onObject:nilValue: with `nil` for the nil value.
  264. ///
  265. /// WARNING: Under certain conditions, this method is known to be thread-unsafe.
  266. /// See the description in -setKeyPath:onObject:nilValue:.
  267. - (RACDisposable *)setKeyPath:(NSString *)keyPath onObject:(NSObject *)object;
  268. /// Binds the receiver to an object, automatically setting the given key path on
  269. /// every `next`. When the signal completes, the binding is automatically
  270. /// disposed of.
  271. ///
  272. /// WARNING: Under certain conditions, this method is known to be thread-unsafe.
  273. /// A crash can result if `object` is deallocated concurrently on
  274. /// another thread within a window of time between a value being sent
  275. /// on this signal and immediately prior to the invocation of
  276. /// -setValue:forKeyPath:, which sets the property. To prevent this,
  277. /// ensure `object` is deallocated on the same thread the receiver
  278. /// sends on, or ensure that the returned disposable is disposed of
  279. /// before `object` deallocates.
  280. /// See https://github.com/ReactiveCocoa/ReactiveCocoa/pull/1184
  281. ///
  282. /// Sending an error on the signal is considered undefined behavior, and will
  283. /// generate an assertion failure in Debug builds.
  284. ///
  285. /// A given key on an object should only have one active signal bound to it at any
  286. /// given time. Binding more than one signal to the same property is considered
  287. /// undefined behavior.
  288. ///
  289. /// keyPath - The key path to update with `next`s from the receiver.
  290. /// object - The object that `keyPath` is relative to.
  291. /// nilValue - The value to set at the key path whenever `nil` is sent by the
  292. /// receiver. This may be nil when binding to object properties, but
  293. /// an NSValue should be used for primitive properties, to avoid an
  294. /// exception if `nil` is sent (which might occur if an intermediate
  295. /// object is set to `nil`).
  296. ///
  297. /// Returns a disposable which can be used to terminate the binding.
  298. - (RACDisposable *)setKeyPath:(NSString *)keyPath onObject:(NSObject *)object nilValue:(id)nilValue;
  299. /// Sends NSDate.date every `interval` seconds.
  300. ///
  301. /// interval - The time interval in seconds at which the current time is sent.
  302. /// scheduler - The scheduler upon which the current NSDate should be sent. This
  303. /// must not be nil or +[RACScheduler immediateScheduler].
  304. ///
  305. /// Returns a signal that sends the current date/time every `interval` on
  306. /// `scheduler`.
  307. + (RACSignal *)interval:(NSTimeInterval)interval onScheduler:(RACScheduler *)scheduler;
  308. /// Sends NSDate.date at intervals of at least `interval` seconds, up to
  309. /// approximately `interval` + `leeway` seconds.
  310. ///
  311. /// The created signal will defer sending each `next` for at least `interval`
  312. /// seconds, and for an additional amount of time up to `leeway` seconds in the
  313. /// interest of performance or power consumption. Note that some additional
  314. /// latency is to be expected, even when specifying a `leeway` of 0.
  315. ///
  316. /// interval - The base interval between `next`s.
  317. /// scheduler - The scheduler upon which the current NSDate should be sent. This
  318. /// must not be nil or +[RACScheduler immediateScheduler].
  319. /// leeway - The maximum amount of additional time the `next` can be deferred.
  320. ///
  321. /// Returns a signal that sends the current date/time at intervals of at least
  322. /// `interval seconds` up to approximately `interval` + `leeway` seconds on
  323. /// `scheduler`.
  324. + (RACSignal *)interval:(NSTimeInterval)interval onScheduler:(RACScheduler *)scheduler withLeeway:(NSTimeInterval)leeway;
  325. /// Takes `next`s until the `signalTrigger` sends `next` or `completed`.
  326. ///
  327. /// Returns a signal which passes through all events from the receiver until
  328. /// `signalTrigger` sends `next` or `completed`, at which point the returned signal
  329. /// will send `completed`.
  330. - (RACSignal *)takeUntil:(RACSignal *)signalTrigger;
  331. /// Takes `next`s until the `replacement` sends an event.
  332. ///
  333. /// replacement - The signal which replaces the receiver as soon as it sends an
  334. /// event.
  335. ///
  336. /// Returns a signal which passes through `next`s and `error` from the receiver
  337. /// until `replacement` sends an event, at which point the returned signal will
  338. /// send that event and switch to passing through events from `replacement`
  339. /// instead, regardless of whether the receiver has sent events already.
  340. - (RACSignal *)takeUntilReplacement:(RACSignal *)replacement;
  341. /// Subscribes to the returned signal when an error occurs.
  342. - (RACSignal *)catch:(RACSignal * (^)(NSError *error))catchBlock;
  343. /// Subscribes to the given signal when an error occurs.
  344. - (RACSignal *)catchTo:(RACSignal *)signal;
  345. /// Returns a signal that will either immediately send the return value of
  346. /// `tryBlock` and complete, or error using the `NSError` passed out from the
  347. /// block.
  348. ///
  349. /// tryBlock - An action that performs some computation that could fail. If the
  350. /// block returns nil, the block must return an error via the
  351. /// `errorPtr` parameter.
  352. ///
  353. /// Example:
  354. ///
  355. /// [RACSignal try:^(NSError **error) {
  356. /// return [NSJSONSerialization JSONObjectWithData:someJSONData options:0 error:error];
  357. /// }];
  358. + (RACSignal *)try:(id (^)(NSError **errorPtr))tryBlock;
  359. /// Runs `tryBlock` against each of the receiver's values, passing values
  360. /// until `tryBlock` returns NO, or the receiver completes.
  361. ///
  362. /// tryBlock - An action to run against each of the receiver's values.
  363. /// The block should return YES to indicate that the action was
  364. /// successful. This block must not be nil.
  365. ///
  366. /// Example:
  367. ///
  368. /// // The returned signal will send an error if data values cannot be
  369. /// // written to `someFileURL`.
  370. /// [signal try:^(NSData *data, NSError **errorPtr) {
  371. /// return [data writeToURL:someFileURL options:NSDataWritingAtomic error:errorPtr];
  372. /// }];
  373. ///
  374. /// Returns a signal which passes through all the values of the receiver. If
  375. /// `tryBlock` fails for any value, the returned signal will error using the
  376. /// `NSError` passed out from the block.
  377. - (RACSignal *)try:(BOOL (^)(id value, NSError **errorPtr))tryBlock;
  378. /// Runs `mapBlock` against each of the receiver's values, mapping values until
  379. /// `mapBlock` returns nil, or the receiver completes.
  380. ///
  381. /// mapBlock - An action to map each of the receiver's values. The block should
  382. /// return a non-nil value to indicate that the action was successful.
  383. /// This block must not be nil.
  384. ///
  385. /// Example:
  386. ///
  387. /// // The returned signal will send an error if data cannot be read from
  388. /// // `fileURL`.
  389. /// [signal tryMap:^(NSURL *fileURL, NSError **errorPtr) {
  390. /// return [NSData dataWithContentsOfURL:fileURL options:0 error:errorPtr];
  391. /// }];
  392. ///
  393. /// Returns a signal which transforms all the values of the receiver. If
  394. /// `mapBlock` returns nil for any value, the returned signal will error using
  395. /// the `NSError` passed out from the block.
  396. - (RACSignal *)tryMap:(id (^)(id value, NSError **errorPtr))mapBlock;
  397. /// Returns the first `next`. Note that this is a blocking call.
  398. - (id)first;
  399. /// Returns the first `next` or `defaultValue` if the signal completes or errors
  400. /// without sending a `next`. Note that this is a blocking call.
  401. - (id)firstOrDefault:(id)defaultValue;
  402. /// Returns the first `next` or `defaultValue` if the signal completes or errors
  403. /// without sending a `next`. If an error occurs success will be NO and error
  404. /// will be populated. Note that this is a blocking call.
  405. ///
  406. /// Both success and error may be NULL.
  407. - (id)firstOrDefault:(id)defaultValue success:(BOOL *)success error:(NSError **)error;
  408. /// Blocks the caller and waits for the signal to complete.
  409. ///
  410. /// error - If not NULL, set to any error that occurs.
  411. ///
  412. /// Returns whether the signal completed successfully. If NO, `error` will be set
  413. /// to the error that occurred.
  414. - (BOOL)waitUntilCompleted:(NSError **)error;
  415. /// Defers creation of a signal until the signal's actually subscribed to.
  416. ///
  417. /// This can be used to effectively turn a hot signal into a cold signal.
  418. + (RACSignal *)defer:(RACSignal * (^)(void))block;
  419. /// Every time the receiver sends a new RACSignal, subscribes and sends `next`s and
  420. /// `error`s only for that signal.
  421. ///
  422. /// The receiver must be a signal of signals.
  423. ///
  424. /// Returns a signal which passes through `next`s and `error`s from the latest
  425. /// signal sent by the receiver, and sends `completed` when both the receiver and
  426. /// the last sent signal complete.
  427. - (RACSignal *)switchToLatest;
  428. /// Switches between the signals in `cases` as well as `defaultSignal` based on
  429. /// the latest value sent by `signal`.
  430. ///
  431. /// signal - A signal of objects used as keys in the `cases` dictionary.
  432. /// This argument must not be nil.
  433. /// cases - A dictionary that has signals as values. This argument must
  434. /// not be nil. A RACTupleNil key in this dictionary will match
  435. /// nil `next` events that are received on `signal`.
  436. /// defaultSignal - The signal to pass through after `signal` sends a value for
  437. /// which `cases` does not contain a signal. If nil, any
  438. /// unmatched values will result in
  439. /// a RACSignalErrorNoMatchingCase error.
  440. ///
  441. /// Returns a signal which passes through `next`s and `error`s from one of the
  442. /// the signals in `cases` or `defaultSignal`, and sends `completed` when both
  443. /// `signal` and the last used signal complete. If no `defaultSignal` is given,
  444. /// an unmatched `next` will result in an error on the returned signal.
  445. + (RACSignal *)switch:(RACSignal *)signal cases:(NSDictionary *)cases default:(RACSignal *)defaultSignal;
  446. /// Switches between `trueSignal` and `falseSignal` based on the latest value
  447. /// sent by `boolSignal`.
  448. ///
  449. /// boolSignal - A signal of BOOLs determining whether `trueSignal` or
  450. /// `falseSignal` should be active. This argument must not be nil.
  451. /// trueSignal - The signal to pass through after `boolSignal` has sent YES.
  452. /// This argument must not be nil.
  453. /// falseSignal - The signal to pass through after `boolSignal` has sent NO. This
  454. /// argument must not be nil.
  455. ///
  456. /// Returns a signal which passes through `next`s and `error`s from `trueSignal`
  457. /// and/or `falseSignal`, and sends `completed` when both `boolSignal` and the
  458. /// last switched signal complete.
  459. + (RACSignal *)if:(RACSignal *)boolSignal then:(RACSignal *)trueSignal else:(RACSignal *)falseSignal;
  460. /// Adds every `next` to an array. Nils are represented by NSNulls. Note that
  461. /// this is a blocking call.
  462. ///
  463. /// **This is not the same as the `ToArray` method in Rx.** See -collect for
  464. /// that behavior instead.
  465. ///
  466. /// Returns the array of `next` values, or nil if an error occurs.
  467. - (NSArray *)toArray;
  468. /// Adds every `next` to a sequence. Nils are represented by NSNulls.
  469. ///
  470. /// This corresponds to the `ToEnumerable` method in Rx.
  471. ///
  472. /// Returns a sequence which provides values from the signal as they're sent.
  473. /// Trying to retrieve a value from the sequence which has not yet been sent will
  474. /// block.
  475. @property (nonatomic, strong, readonly) RACSequence *sequence;
  476. /// Creates and returns a multicast connection. This allows you to share a single
  477. /// subscription to the underlying signal.
  478. - (RACMulticastConnection *)publish;
  479. /// Creates and returns a multicast connection that pushes values into the given
  480. /// subject. This allows you to share a single subscription to the underlying
  481. /// signal.
  482. - (RACMulticastConnection *)multicast:(RACSubject *)subject;
  483. /// Multicasts the signal to a RACReplaySubject of unlimited capacity, and
  484. /// immediately connects to the resulting RACMulticastConnection.
  485. ///
  486. /// Returns the connected, multicasted signal.
  487. - (RACSignal *)replay;
  488. /// Multicasts the signal to a RACReplaySubject of capacity 1, and immediately
  489. /// connects to the resulting RACMulticastConnection.
  490. ///
  491. /// Returns the connected, multicasted signal.
  492. - (RACSignal *)replayLast;
  493. /// Multicasts the signal to a RACReplaySubject of unlimited capacity, and
  494. /// lazily connects to the resulting RACMulticastConnection.
  495. ///
  496. /// This means the returned signal will subscribe to the multicasted signal only
  497. /// when the former receives its first subscription.
  498. ///
  499. /// Returns the lazily connected, multicasted signal.
  500. - (RACSignal *)replayLazily;
  501. /// Sends an error after `interval` seconds if the source doesn't complete
  502. /// before then.
  503. ///
  504. /// The error will be in the RACSignalErrorDomain and have a code of
  505. /// RACSignalErrorTimedOut.
  506. ///
  507. /// interval - The number of seconds after which the signal should error out.
  508. /// scheduler - The scheduler upon which any timeout error should be sent. This
  509. /// must not be nil or +[RACScheduler immediateScheduler].
  510. ///
  511. /// Returns a signal that passes through the receiver's events, until the stream
  512. /// finishes or times out, at which point an error will be sent on `scheduler`.
  513. - (RACSignal *)timeout:(NSTimeInterval)interval onScheduler:(RACScheduler *)scheduler;
  514. /// Creates and returns a signal that delivers its events on the given scheduler.
  515. /// Any side effects of the receiver will still be performed on the original
  516. /// thread.
  517. ///
  518. /// This is ideal when the signal already performs its work on the desired
  519. /// thread, but you want to handle its events elsewhere.
  520. ///
  521. /// This corresponds to the `ObserveOn` method in Rx.
  522. - (RACSignal *)deliverOn:(RACScheduler *)scheduler;
  523. /// Creates and returns a signal that executes its side effects and delivers its
  524. /// events on the given scheduler.
  525. ///
  526. /// Use of this operator should be avoided whenever possible, because the
  527. /// receiver's side effects may not be safe to run on another thread. If you just
  528. /// want to receive the signal's events on `scheduler`, use -deliverOn: instead.
  529. - (RACSignal *)subscribeOn:(RACScheduler *)scheduler;
  530. /// Creates and returns a signal that delivers its events on the main thread.
  531. /// If events are already being sent on the main thread, they may be passed on
  532. /// without delay. An event will instead be queued for later delivery on the main
  533. /// thread if sent on another thread, or if a previous event is already being
  534. /// processed, or has been queued.
  535. ///
  536. /// Any side effects of the receiver will still be performed on the original
  537. /// thread.
  538. ///
  539. /// This can be used when a signal will cause UI updates, to avoid potential
  540. /// flicker caused by delayed delivery of events, such as the first event from
  541. /// a RACObserve at view instantiation.
  542. - (RACSignal *)deliverOnMainThread;
  543. /// Groups each received object into a group, as determined by calling `keyBlock`
  544. /// with that object. The object sent is transformed by calling `transformBlock`
  545. /// with the object. If `transformBlock` is nil, it sends the original object.
  546. ///
  547. /// The returned signal is a signal of RACGroupedSignal.
  548. - (RACSignal *)groupBy:(id<NSCopying> (^)(id object))keyBlock transform:(id (^)(id object))transformBlock;
  549. /// Calls -[RACSignal groupBy:keyBlock transform:nil].
  550. - (RACSignal *)groupBy:(id<NSCopying> (^)(id object))keyBlock;
  551. /// Sends an [NSNumber numberWithBool:YES] if the receiving signal sends any
  552. /// objects.
  553. - (RACSignal *)any;
  554. /// Sends an [NSNumber numberWithBool:YES] if the receiving signal sends any
  555. /// objects that pass `predicateBlock`.
  556. ///
  557. /// predicateBlock - cannot be nil.
  558. - (RACSignal *)any:(BOOL (^)(id object))predicateBlock;
  559. /// Sends an [NSNumber numberWithBool:YES] if all the objects the receiving
  560. /// signal sends pass `predicateBlock`.
  561. ///
  562. /// predicateBlock - cannot be nil.
  563. - (RACSignal *)all:(BOOL (^)(id object))predicateBlock;
  564. /// Resubscribes to the receiving signal if an error occurs, up until it has
  565. /// retried the given number of times.
  566. ///
  567. /// retryCount - if 0, it keeps retrying until it completes.
  568. - (RACSignal *)retry:(NSInteger)retryCount;
  569. /// Resubscribes to the receiving signal if an error occurs.
  570. - (RACSignal *)retry;
  571. /// Sends the latest value from the receiver only when `sampler` sends a value.
  572. /// The returned signal could repeat values if `sampler` fires more often than
  573. /// the receiver. Values from `sampler` are ignored before the receiver sends
  574. /// its first value.
  575. ///
  576. /// sampler - The signal that controls when the latest value from the receiver
  577. /// is sent. Cannot be nil.
  578. - (RACSignal *)sample:(RACSignal *)sampler;
  579. /// Ignores all `next`s from the receiver.
  580. ///
  581. /// Returns a signal which only passes through `error` or `completed` events from
  582. /// the receiver.
  583. - (RACSignal *)ignoreValues;
  584. /// Converts each of the receiver's events into a RACEvent object.
  585. ///
  586. /// Returns a signal which sends the receiver's events as RACEvents, and
  587. /// completes after the receiver sends `completed` or `error`.
  588. - (RACSignal *)materialize;
  589. /// Converts each RACEvent in the receiver back into "real" RACSignal events.
  590. ///
  591. /// Returns a signal which sends `next` for each value RACEvent, `error` for each
  592. /// error RACEvent, and `completed` for each completed RACEvent.
  593. - (RACSignal *)dematerialize;
  594. /// Inverts each NSNumber-wrapped BOOL sent by the receiver. It will assert if
  595. /// the receiver sends anything other than NSNumbers.
  596. ///
  597. /// Returns a signal of inverted NSNumber-wrapped BOOLs.
  598. - (RACSignal *)not;
  599. /// Performs a boolean AND on all of the RACTuple of NSNumbers in sent by the receiver.
  600. ///
  601. /// Asserts if the receiver sends anything other than a RACTuple of one or more NSNumbers.
  602. ///
  603. /// Returns a signal that applies AND to each NSNumber in the tuple.
  604. - (RACSignal *)and;
  605. /// Performs a boolean OR on all of the RACTuple of NSNumbers in sent by the receiver.
  606. ///
  607. /// Asserts if the receiver sends anything other than a RACTuple of one or more NSNumbers.
  608. ///
  609. /// Returns a signal that applies OR to each NSNumber in the tuple.
  610. - (RACSignal *)or;
  611. /// Sends the result of calling the block with arguments as packed in each RACTuple
  612. /// sent by the receiver.
  613. ///
  614. /// The receiver must send tuple values, where the first element of the tuple is
  615. /// a block, taking a number of parameters equal to the count of the remaining
  616. /// elements of the tuple, and returning an object. Each block must take at least
  617. /// one argument, so each tuple must contain at least 2 elements.
  618. ///
  619. /// Example:
  620. ///
  621. /// RACSignal *adder = [RACSignal return:^(NSNumber *a, NSNumber *b) {
  622. /// return @(a.intValue + b.intValue);
  623. /// }];
  624. /// RACSignal *sums = [[RACSignal
  625. /// combineLatest:@[ adder, as, bs ]]
  626. /// reduceApply];
  627. ///
  628. /// Returns a signal of the result of applying the first element of each tuple
  629. /// to the remaining elements.
  630. - (RACSignal *)reduceApply;
  631. @end
  632. @interface RACSignal (UnavailableOperations)
  633. - (RACSignal *)windowWithStart:(RACSignal *)openSignal close:(RACSignal * (^)(RACSignal *start))closeBlock __attribute__((unavailable("See https://github.com/ReactiveCocoa/ReactiveCocoa/issues/587")));
  634. - (RACSignal *)buffer:(NSUInteger)bufferCount __attribute__((unavailable("See https://github.com/ReactiveCocoa/ReactiveCocoa/issues/587")));
  635. - (RACSignal *)let:(RACSignal * (^)(RACSignal *sharedSignal))letBlock __attribute__((unavailable("Use -publish instead")));
  636. + (RACSignal *)interval:(NSTimeInterval)interval __attribute__((unavailable("Use +interval:onScheduler: instead")));
  637. + (RACSignal *)interval:(NSTimeInterval)interval withLeeway:(NSTimeInterval)leeway __attribute__((unavailable("Use +interval:onScheduler:withLeeway: instead")));
  638. - (RACSignal *)bufferWithTime:(NSTimeInterval)interval __attribute__((unavailable("Use -bufferWithTime:onScheduler: instead")));
  639. - (RACSignal *)timeout:(NSTimeInterval)interval __attribute__((unavailable("Use -timeout:onScheduler: instead")));
  640. - (RACDisposable *)toProperty:(NSString *)keyPath onObject:(NSObject *)object __attribute__((unavailable("Renamed to -setKeyPath:onObject:")));
  641. - (RACSignal *)ignoreElements __attribute__((unavailable("Renamed to -ignoreValues")));
  642. - (RACSignal *)sequenceNext:(RACSignal * (^)(void))block __attribute__((unavailable("Renamed to -then:")));
  643. - (RACSignal *)aggregateWithStart:(id)start combine:(id (^)(id running, id next))combineBlock __attribute__((unavailable("Renamed to -aggregateWithStart:reduce:")));
  644. - (RACSignal *)aggregateWithStartFactory:(id (^)(void))startFactory combine:(id (^)(id running, id next))combineBlock __attribute__((unavailable("Renamed to -aggregateWithStartFactory:reduce:")));
  645. - (RACDisposable *)executeCommand:(RACCommand *)command __attribute__((unavailable("Use -flattenMap: or -subscribeNext: instead")));
  646. @end