john doe
john doe

Reputation: 9660

Key-Value Observing in Swift 4

I have the following code in my Swift 4 project.

class DishesTableViewController : UITableViewController {


    private var token :NSKeyValueObservation?

    @objc dynamic private(set) var dishes :[Dish] = []

    override func viewDidLoad() {
        super.viewDidLoad()

        // configure the observation
        token = self.observe(\.dishes) { object, change in

            // change is always nil
            print(object)
            print(change)
        }

        updateTableView()
    }

Whenever the dishes array is changed, the observation is triggered. But my question is how can I get the actual changes that happened, that is, how can I access the actual Dish object that triggered the change?

Upvotes: 5

Views: 3044

Answers (1)

Pranav Kasetti
Pranav Kasetti

Reputation: 9925

I think the reason change is coming up with nil is because you haven't specified options.

Rewrite as follows:

override func viewDidLoad() {
    super.viewDidLoad()

    // configure the observation
    token = self.observe(\.dishes, options: [.new,.old]) { object, change in

        print(object)
        let set1 = Set(change.newArray!)
        let set2 = Set(change.oldArray!)

        let filter = Array(set1.subtract(set2))
        print(filter)

    }

    updateTableView()
}

Note that I have done a bit of guesswork here about your Dish object. I am assuming you have made it conform to the Equatable protocol, and this is a necessary step for the solution to work.

UPDATE: This requirement has now been reflected in the official Apple documentation here.

If you don't need to know how a property has changed, omit the options parameter. Omitting the options parameter forgoes storing the new and old property values, which causes the oldValue and newValue properties to be nil.

Upvotes: 6

Related Questions