FoundationExtensions.swift 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. //
  2. // FoundationExtensions.swift
  3. // ReactiveCocoa
  4. //
  5. // Created by Justin Spahr-Summers on 2014-10-19.
  6. // Copyright (c) 2014 GitHub. All rights reserved.
  7. //
  8. import Foundation
  9. import enum Result.NoError
  10. extension NSNotificationCenter {
  11. /// Returns a SignalProducer to observe posting of the specified
  12. /// notification.
  13. ///
  14. /// - parameters:
  15. /// - name: name of the notification to observe
  16. /// - object: an instance which sends the notifications
  17. ///
  18. /// - returns: A SignalProducer of notifications posted that match the given
  19. /// criteria.
  20. ///
  21. /// - note: If the `object` is deallocated before starting the producer, it
  22. /// will terminate immediately with an `Interrupted` event.
  23. /// Otherwise, the producer will not terminate naturally, so it must
  24. /// be explicitly disposed to avoid leaks.
  25. public func rac_notifications(name: String? = nil, object: AnyObject? = nil) -> SignalProducer<NSNotification, NoError> {
  26. // We're weakly capturing an optional reference here, which makes destructuring awkward.
  27. let objectWasNil = (object == nil)
  28. return SignalProducer { [weak object] observer, disposable in
  29. guard object != nil || objectWasNil else {
  30. observer.sendInterrupted()
  31. return
  32. }
  33. let notificationObserver = self.addObserverForName(name, object: object, queue: nil) { notification in
  34. observer.sendNext(notification)
  35. }
  36. disposable += {
  37. self.removeObserver(notificationObserver)
  38. }
  39. }
  40. }
  41. }
  42. private let defaultSessionError = NSError(domain: "org.reactivecocoa.ReactiveCocoa.rac_dataWithRequest", code: 1, userInfo: nil)
  43. extension NSURLSession {
  44. /// Returns a SignalProducer which performs the work associated with an
  45. /// `NSURLSession`
  46. ///
  47. /// - parameters:
  48. /// - request: A request that will be performed when the producer is
  49. /// started
  50. ///
  51. /// - returns: A producer that will execute the given request once for each
  52. /// invocation of `start()`.
  53. ///
  54. /// - note: This method will not send an error event in the case of a server
  55. /// side error (i.e. when a response with status code other than
  56. /// 200...299 is received).
  57. public func rac_dataWithRequest(request: NSURLRequest) -> SignalProducer<(NSData, NSURLResponse), NSError> {
  58. return SignalProducer { observer, disposable in
  59. let task = self.dataTaskWithRequest(request) { data, response, error in
  60. if let data = data, response = response {
  61. observer.sendNext((data, response))
  62. observer.sendCompleted()
  63. } else {
  64. observer.sendFailed(error ?? defaultSessionError)
  65. }
  66. }
  67. disposable += {
  68. task.cancel()
  69. }
  70. task.resume()
  71. }
  72. }
  73. }