6

I'm trying to adopt ReactiveCocoa in my iOS application written in Swift. Unfortunately, it looks like rac_valuesForKeyPath doesn't work as expected. Here's the example:

class Source: NSObject {
    var observable: String = "<Original>"

    override init() {
        super.init()

        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), { () -> Void in
            self.observable = "<Updated>"
            println("Updated value to \(self.observable)");
        })
    }
}

class Observer: NSObject {
    init(source: Source) {
        super.init()

        source.rac_valuesForKeyPath("observable", observer: self).subscribeNext { (value: AnyObject!) -> Void in
            println(">>> Observable value changed: \(value)")
        }
    }
}

The example produces the following output:

>>> Observable value changed: <Original>
Updated value to <Updated>

This means subcribeNext block wasn't called.

The expected input is:

>>> Observable value changed: <Original>
Updated value to <Updated>
>>> Observable value changed: <Updated>

Any clue how to fix the issue?

mindz_eye
  • 73
  • 6

1 Answers1

9

The observable needs to be dynamic

I got your sample to work with the following code

class Source: NSObject {
  dynamic var string:String = "Initial Value"

  override init() {
    super.init()
  }
}

class Observer: NSObject {

  init(source:Source) {
    super.init()
    source.rac_valuesForKeyPath("string", observer: self).subscribeNext { (newVal:AnyObject!) -> Void in
      println(newVal)
    }
  }
}

class ViewController: UIViewController {
  var source:Source!
  var obs:Observer!

  override func viewDidLoad() {
    super.viewDidLoad()
    source = Source()
    obs = Observer(source: source)
    source.string = "Another Value"
  }
}
chrs
  • 5,906
  • 10
  • 43
  • 74
  • 1
    seems to work when you add 'dynamic' modifier to the first example – Edward Ashak Mar 09 '15 at 17:25
  • Key-value observing is a mechanism that allows objects to be notified of changes to specified properties of other objects. You can use key-value observing with a Swift class, as long as the class inherits from the NSObject class. You can use these three steps to implement key-value observing in Swift. https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/AdoptingCocoaDesignPatterns.html – Edward Ashak Mar 09 '15 at 17:28