Oleksandr Matrosov
Oleksandr Matrosov

Reputation: 27113

KVO or how to listen for a property changes from outside in Swift

I have a instance with a property which I want to listen for updates from other instance.

For example class Menu has a property badgeCount, I want to listen for any updates for badgeCount for example when badgeCount is changed. I want my ViewController to have callback after badgeCount is modified to know actual data.

In objective was KVO that I can use for listed property, how can I use KVO in Swift. I am new in Swift.

Upvotes: 2

Views: 1927

Answers (1)

tomahh
tomahh

Reputation: 13651

If you want to use KVO in swift, there are two requirements :

  • The class you want to do KVO on must inherit from NSObject (or any NSObject subclass)
  • The property you need to observe must be marked as dynamic

a code example would be:

class Menu: NSObject {
  dynamic var badgeCount: Int = 0
}

And then, you can use the usual menuInstance.addObserver(self, forKeyPath: "badgeCount", options: NSKeyValueObservingOptions(), context: nil)

But this solution is not very much swifty.


Better solutions are (not an exhaustive list):

Use swift's didSet/willSet to call some callback

class Menu {
  var badgeCount: Int = 0 {
     didSet {
        badgeCountChangedListener(badgeCount)
     }
  }

  init(badgeCountChangedListener: (Int -> Void)) {
    self.badgeCountChangedListener = badgeCountChangedListener
  }

  private let badgeCountChangedListener: (Int -> Void)
}

Use RxSwift's Variable type

class Menu {
   let badgeCount = Variable(0)
}

// and from where you observe
menuInstance.badgeCount.subscribeNext { badgeCount in
    print(badgeCount)
}

Upvotes: 3

Related Questions