Skip to content
Go back

Implementing observable in Swift

KVO has been integral part of Cocoa programming, yet it’s not available for pure Swift classes.

Is there a way to implement your own implementation of native KVO?

API Design

When I thought of how I want to implement Observable properties, I’ve had few things in mind:

  1. Distinct closures for Will/Did set.
  2. Ability to access current value and old/new one.
  3. Observable property should work as non-observable one, if function takes int as argument it should work with both cases.

1 and 2 can be satisfied with just API design, sample code for usage of Observable looks like this:

object.property.addObserver(.WillSet) {
  println("Will set value to \($0) curValue \($1)”)
}

What I meant by point 3 is best explained with some sample code. Let’s say we have a class Foo in our Library/Module:

struct Foo {
  var rawInt = 2
  var observableInt = Observable(2)
}

Let’s say user of our library has a function that processes ints:

func processInt(value : Int)

Now I want the users of my module to be able to just use my code, regardless of it beining observable or not:

let object = Foo()
processInt(object.rawInt)
processInt(object.observableInt)

Having a code like this would mean that you as an user of my code doesn’t need to care if it’s observable or not, yet you could leverage that power if you needed/wanted.

Swift Types and Implict conversions

Implementing compliance with above requirement (3rd) wouldn’t be possible in Swift because of Type difference if not for a little known function called __conversion(), conversion as the name clearly states gives you implicit conversion between types, this is how we can use it for our Observable properties:

struct Observable<T> {
  var raw : T
// other code...
  func __conversion() -> T {
  	return raw
  }
}

Now each time a parameter of T is required, we can use Observable instead.

Swift issues and Wish-list

When I was playing with the idea of Observables I’ve found few things that either crashed the compiler (Ouch) or just didn’t work in language (yet?).

Issues:

Wish list:

  1. Would be nice to have a way to define behaviour/mutability for compound collections
  2. Ability to create extensions from a generic scope or overload assigment = operator, right now to be able to modify Observable we need to use rawValue accessor which is far from perfect.

Hopefully Apple is working on at least some of those points.


Share this post on:

Previous Post
Improving development speed
Next Post
Behaviours and Xcode 6