Swift Programming

Introduction to KVO and KVC in Swift

Observing and getting notified when properties changes

Anurag Ajwani
4 min readFeb 16, 2021
Photo by Erik Mclean on Unsplash

KVO and KVC or Key-Value Observing and Key-Value Coding are mechanisms originally built and provided by Objective-C that allows us to locate and interact with the underlying properties of a class that inherits NSObject at runtime. In short this mean that you can interact with a property through a stringly typed key instead of your usual dot syntax which is checked at compile time.

In this post I will explain how to use KVC and KVO through an example that will further explain the terms. Then I will answer why you’d need to know KVC and KVO in Swift being that it is an Objective-C feature.

How to use KVC and KVO in Swift

Let’s say you have a class to represent a Pokemon:

class Pokemon {
var name: String

init(name: String) {
self.name = name
}
}

You start your Pokemon journey with Charmander:

let myFirstPokemon = Pokemon(name: "Charmander")

However Charmanders evolve into Charmeleons after some battle experience.

Charmander evolving to Charmeleon
myFirstPokemon.name = "Charmeleon" // setting value using dot syntax

Note above we used the .name to interact or access and set the property. If we had a typo i.e. .named then the code would not compile.

myFirstPokemon changes state however it is in essence the same instance of the Pokemon with a different name. Additionally we are not able to observe that Charmander has changed to Charmeleon. Others are not able to observe that either. How can one observe a change in Charmander’s name? Let’s use KVC and KVO to answer that:

class Pokemon: NSObject {
@objc dynamic var name: String

init(name: String) {
self.pokemon = pokemon
}
}

Notice how we need to inherit NSObject. This makes the properties key-value coding complaint. And thus we can do generic operations supplied through KVC on the pokemon instance such as the following:

let pokemonName = myFirstPokemon.value(forKey: "name")
myFirstPokemon.setValue("Charmeleon", forKey: "name")

KVC offers additional features other than the generic way of accessing and setting properties depicted above. You can read the full documentation here.

Swift objects that inherit from NSObject or one of its subclasses are key-value coding compliant for their properties by default.
- Apple docs

We also preppended the @objc dynamic to the name property. This makes the property automatically Key-Value observable.

Mark properties that you want to observe through key-value observing with both the @objcattribute and the dynamic modifier.
- Apple docs

Now we are able to observe changes. The last thing to do is to add an observer for the changes in the Pokemon instance name. This is how you do it:

myFirstPokemon.observe(\.name, options: [.old, .new]) { (pokemon, value) in
print("old name \(value.oldValue!)")
print("new name \(value.newValue!)")
}

On observation not only you can receive the new value but also the old value.

Why should you understand KVC and KVO in Swift?

Swift was first introduced in 2014 and nearly 7 years have elapsed since (at the time of writing). However many of the libraries, frameworks and tools we use in our Swift code are in fact written in Objective-C or have an Objective-C interface but not a Swift one. I’ll give you two examples with which you might need to interact or understand these today in your Swift code:

  1. Interface Builders or Storyboards
  2. Foundation framework

1. Interface Builders or Storyboards

One major example of where we interact with KVC is in UIKit when using Interface Builder (IB) or Storyboards. Have you ever asked yourself how a view in your Interface Builder can then link to a property in your UIViewController marked with @IBOutlet?

UIViewController’s inherit NSObject and thus are by default Key-Value Coding complaint. The Interface Builder does not know the property exists at compile time and uses KVC to set the properties on your linked UIViewController.

Try removing a connected @IBOutlet from your view controller. The code will compile however you’ll get an exception at runtime.

2. Foundation framework

Another example where KVC and KVO are still used is in the Foundation framework. One example within Foundation where we’d need to understand KVC and KVO is the Operation class. I won’t delve into Operation into this post. For this post it is important to highlight that in order to use some of its functionality we need to know and understand KVC and KVO.

Summary

In this post we have learnt:

  • What is KVC and KVO
  • How to use KVC and KVO
  • Why learn KVC and KVO in Swift

Final thoughts

Objective-C dynamism is still a strong feature which Swift does not yet offer. They can help build tools such as Interface Builder and even Core Data Editor. Interface Builder may no longer be as relevant though with the introduction of SwiftUI. However the average iOS developer will not building tools such as those anyhow. More importantly for the average iOS developer is being able to consume Apple frameworks API for which one might need to know and understand KVC and KVO.

For more on iOS development follow me on Twitter or Medium!

--

--

Anurag Ajwani

Senior iOS Engineer at Travelperk. 7+ years experience with iOS and Swift. Blogging my knowledge and experience.