KVC – Implementation

We can use the same project that we used for the previous section and create a new class called KVCObject.swift; this class is a subclass of NSObject. For now, leave the class as empty and move over to the main.swift file.

We will now create a new instance of kvcObject and then write a print statement that tries to print the request of KVO for a value associated with the stringToFind key, as shown:

var kvcObject = KVCObject()
print("KVC value = \(kvcObject.value(forKey: "stringToFind"))")

After building and running the project, you will note that the program crashes with a console log error message, as illustrated:

That happened because we did not provide any source for the key that it's asking for.

Now let's switch back to KVCObject, and let's implement the valueForUndefinedKey() method; this method will be a net for catching requests for keys that we have no value for, and the implementation of our method will be as follows:

override func value(forUndefinedKey key: String) -> Any? {
print("we do not have any key for \(key)")
return nil
}

As a result of the implementation, you will note that the console logs reflect the function that was invoked:

This function will catch the execution if someone requests a key that we don't have. As you might have noted, this method also provides us with an opportunity to return a default value for that key, so we have returned nil as a string in our case.

Now, let's make things a little more interesting—switch back to the main.swift file and add another print statement for another key, as follows:

print("KVC vallue of Second Key = \(String(describing: kvcObject.value(forKey: "numberToFind")!))")

Building and running again will result in the following console log, and as you might have guessed, our function will again be invoked to provide a default value, as you can see here:

Let's add an instance variable called stringToFind to KVCObject, and now we will need an initializer as well to give it an initial value, as follows:

@objc dynamic var stringToFind: String
public override init() {
self.stringToFind = "First value"
super.init()
}

This will replace the value for the stringToFind key with "First value", as shown: