← Back to list

Combine and KVO

In this Short post we are reading about how we can use KVO in relation with Combine Framework in Swift. This article is one of a series of…

Ario Liyan in Dev Genius · 2024-04-16 06:01 · 4 claps · 2.2 min read
#kvo #combine-framework #swift-programming #observableobject #reactive-programming
Open on Medium ↗
Wiki topics: 💻 · Programming 🌐 · Web Development 📱 · Mobile Development 📚 · Books & Reading

Combine and KVO

In this Short post we are reading about how we can use KVO in relation with Combine Framework in Swift. This article is one of a series of articles on Combine.

[embed]Combine and Timers In this short reading we go through RunLoops and Timer class in Combine Framework.medium.com

Photo by Jorge Salvador on Unsplash

Photo by Jorge Salvador on Unsplash

Table of contents

  • KVO and its relation to Combine
  • Creating KVO compatible properties
  • publisher(for:,option:) function
  • Observable object and @published decorator

KVO and its relation to Combine

Combine in its essense is about dealing with changes, and in certain scenarios it comes to observing a changes of a single value. When it is about observing the changes of single values, there are couple of approaches that we can take, one of which is KVO with Combine. It’s very important because KVO is at the heart of OBJC and it can bridge between Combine, Swift and OBJC.

A good quantity of properties from UIKit and Foundation classes etc are KVO Compatible. As result, we can observe their changes through KVO.

let operationQueue = OperationQueue()

let subscription = queue.publisher(for: \.qualityOfService)
  .sink {
    print("The quality of service is: \($0)")
  }

//Console output
//The quality of service is: NSQualityOfService(rawValue: -1)

Note that we can easily use “publisher(for:)” with a key path to KVO compatible property to get a publisher capable of emitting values. (Of course not all properties are KVO compatible).

Creating KVO compatible properties

We also can create our own KVO compatible properties to observe but there is catch to it.

  • We should use classes that inherits from NSObject.
  • Decorate the properties with: “@objc dynamic”

When we do this the property marked with @objc dynamic becomes KVO-Compatible.

Let’s implement an example:

class User: NSObject {
        @objc dynamic var name: String = ""
        @objc dynamic var age: Int = 0
}

let user = User()

let subscription = user.publisher(for: \.age)
  .sink {
    print("Age set to \($0)")
  }

user.age = 29

//Console Output
//Age set to 0 // for the initial value
//Age set to 29

Note that all Swift types bridged into OBJC such as all primitive data types works fine with KVO compatible property type.

It also worth mention that when observing changes to system frameworks objects we should make sure the documentation mentions the property is observable.

publisher(for:,option:) function

The option argument in publisher function signature is for determining what value we are observing:

• .initial emits the initial value.

• .prior emits both the previous and the new value when a change occurs.

• .old and .new let the new value through

Observable object and @published decorator

As we mentioned before using KVO for observing values is only one approach that we can take.

In combine we can make our classes of type ObservableObject by conforming to it, and then mark the property we want to observe with @Published decorator.

class User: ObservableObject {
     @Published var name: String = ""
     @Published var age: Int = 0
}

let user = User()

let subscription = user.publisher(for: \.age)
  .sink {
    print("Age set to \($0)")
  }

user.age = 29

Next

[embed]Combine resource management In a series of article I’m writing around the Combine framework, in this post we mainly focus on resource management…medium.com


메타데이터
post_id
2f8bcdfd4663
slug
combine-and-kvo-2f8bcdfd4663
url
https://blog.devgenius.io/combine-and-kvo-2f8bcdfd4663
canonical_url
https://blog.devgenius.io/combine-and-kvo-2f8bcdfd4663
author_url
https://medium.com/@Ariobarxan
status
ok
fetched_at
2026-06-27 23:56:40