Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trouble using swift 4's KVO "observe" instead of addObserver

I'm having some trouble getting the new KVO syntax right. According to the Apple documentation:

Create an observer for the key path and call the observe(_:options:changeHandler) method. For more information on key paths, see Keys and Key Paths.

class MyObserver: NSObject {
    @objc var objectToObserve: MyObjectToObserve
    var observation: NSKeyValueObservation?

    init(object: MyObjectToObserve) {
        objectToObserve = object
        super.init()

        observation = observe(\.objectToObserve.myDate) { object, change in
            print("Observed a change to \(object.objectToObserve).myDate, updated to: \(object.objectToObserve.myDate)")
        }
    }
}

let observed = MyObjectToObserve()
let observer = MyObserver(object: observed)

observed.updateDate()

I'm initializing my observation like so:

self.observation = self.webView!.observe(\.webView.isLoading, changeHandler: { (webView, observedChange) in
    //code
})

but am getting this error:

enter image description here

like image 341
Eden Avatar asked Mar 29 '18 18:03

Eden


People also ask

What is KVO key-value observation )?

KVO, which stands for Key-Value Observing, is one of the techniques for observing the program state changes available in Objective-C and Swift. The concept is simple: when we have an object with some instance variables, KVO allows other objects to establish surveillance on changes for any of those instance variables.

Can you explain KVO and how it's used on Apple's platforms?

Key-value observing is a Cocoa programming pattern you use to notify objects about changes to properties of other objects. It's useful for communicating changes between logically separated parts of your app—such as between models and views. You can only use key-value observing with classes that inherit from NSObject .

How do you observe property in Swift?

Swift property observers For example, you could add a @WrappedDefault property to a view controller. To make use of the property observers within a centralized class like AppSettings , you would need to pass in a closure to execute in the observers or post a Notification — neither of which are ideal.


2 Answers

Turns out the syntax needs to be like this, using the object Type rather than the object instance name:

self.observation = self.webView!.observe(\WKWebView.isLoading, changeHandler: { (webView, observedChange) in
    //code
})

Misread the documentation ¯\_(ツ)_/¯

like image 128
Eden Avatar answered Sep 23 '22 11:09

Eden


If you use the \. syntax the root element is the observed object so it's simply

self.observation = self.webView!.observe(\.isLoading, ...

The compiler treats your syntax as webView.webView.isLoading which is obviously not intended.

like image 41
vadian Avatar answered Sep 22 '22 11:09

vadian