Unmanaged issues in Swift Beta 5

The following Unmanaged call breaks in Swift Beta 5.

import Foundation

var obj = NSObject()
var unretainedRefToObject = Unmanaged.passUnretained(obj)

Apparently, the compiler is unhappy:

Stored value type does not match pointer operand type!
  store %CSo8NSObject* %0, %objc_object** %.targetPtr._value, align 8, !dbg !879
 %objc_object*LLVM ERROR: Broken function found, compilation aborted!
Command /Applications/Xcode6-Beta5.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc failed with exit code 1

Workaround (hack)

We’re using this workaround which stores a COpaquePointer:

import Foundation

var obj = NSObject()
var opaquePointerToUnretainedRefToObj = Unmanaged.passUnretained(obj).toOpaque()

Using the reference now requires one more step (and associated type bookkeeping):

var value = Unmanaged<NSObject>.fromOpaque(opaquePointerToUnretainedRefToObj).takeUnretainedValue()

Key Value Observation in Swift Beta 5

The recently released beta 5 of XCode includes the sizable number of breaking changes. Its now easier to get key value observation (KVO) working with Swift.

Suppose we have a class Publisher that inherits from NSObject and we want to observe changes to it’s property someProperty, we need to use the new keyword dynamic on the property to get KVO to work:

 class Publisher : NSObject {
    dynamic var someProperty : Int = 100 { 
      didSet { println("didSet \(someProperty)") } 
    }

    override var description: String { 
      return "Publisher:{someProperty: \(someProperty)}" 
    }
}

Let’s define a Subscriber which will listen to property changes:

class Subscriber : NSObject  {
    var callback: ()->()

    init(callback: ()->()) {
      self.callback = callback
    }

    override func observeValueForKeyPath(keyPath: String!,
      ofObject object: AnyObject!,
      change: [NSObject : AnyObject]!, 
      context: UnsafeMutablePointer<()>) {
        println("Subscriber: observeValueForKey: \(keyPath), \(object)")
        self.callback()
    }
  }

Hook up and test (full listing here):

func testCallbackOnChange() {
    var called = false
    var pub = Publisher()
    var sub = Subscriber(callback: { called = true } )
    pub.addObserver(sub, forKeyPath: "someProperty", 
      options: NSKeyValueObservingOptions.New, context: nil)
    XCTAssert(called == false, "Shouldn't receive initial callback")
    pub.someProperty = 101
    XCTAssert(called, "Should receive callback on new value")
    println("printing pub: \(pub)") //this prints nothing!!
    println("printing pub.description: \(pub.description)") //sure, this works
    pub.removeObserver(sub, forKeyPath: "someProperty")
}

What happened to .description?

Oddly enough, after an initial KVO trigger (pub.someProperty=101), println refuses to invoke Publisher.description. Bug?

Swift Builders

Similar to languages such as Groovy, Swift has special syntax support for lists (Array) and maps (Dictionary) which results in a compact representation of what’s being defined, inline with the code that is using it. e.g.

println([1,2,3,4,5].count) //Output: 5

or

var x = 0
[1,2,3,4,5].each { x += $0 }

where:

extension Array {
  func each (block: (T) -> ()) {
    for item in self { block(item) }
  }

Tree Based Syntax

In this article, we extend the concept of syntactic support to defining (somewhat) arbitrary nested tree structures.

Let’s say we want to programmatically generate HTML, an imperative solution for which likely requires lengthy code with templates engines / variable substitution, interspaced with loops and branching, and associated glue code.

Syntactic builders can offer an elegant alternative:

html {
  head {
    title( "Page Title" ) {}
  }

  body(["class":"bodyClass"]) {
    for i in 0..3 {
      div(["id":"div_(i)"]) {
        p("Click ") {
          a(["href":"http://www.example.com/link(i).html"], 
             "link (i+1)") {}
        }
      }
    }
  }
}

The above example is valid Swift code and generates the following HTML code:

  <html>
    <head>
      <title>Page Title
      </title>
    </head>
    <body "class"="bodyClass">
      <div "id"="div_0">
        <p>Click 
          <a "href"="http://www.example.com/link0.html">link 1
          </a>
        </p>
      </div>
      <div "id"="div_1">
        <p>Click 
          <a "href"="http://www.example.com/link1.html">link 2
          </a>
        </p>
      </div>
      <div "id"="div_2">
        <p>Click 
          <a "href"="http://www.example.com/link2.html">link 3
          </a>
        </p>
      </div>
    </body>
  </html>

Builder Methods

The builder operates by invoking several custom methods on a underlying Builder class where method names parallel html tag names. e.g. the div tag:

func div(block: ()->()) { div(nil, nil, block) }
func div(attr: Builder.Attributes?, block: ()->()) { div(attr, nil, block) }
func div(value: AnyObject?, block: ()->()) { div(nil, value, block) }
func div(attr: Builder.Attributes?, value: AnyObject?, block: ()->()) { Builder.node("div", attr: attr, value: value, block) }

All builder methods follow the same syntax and accept

  • an optional map of attribute name/value pairs
  • an optional tag value and
  • a closure for configuring the tag.

Internally, the Builder creates a tree of Node objects which parallels the Swift tree.

class Node {
    var name : String
    var parent: Node? { didSet { level = parent!.level + 1} }
    var children = Node[]()
    var attr = Attributes()
    var block: Block?
    var level = 0
    var value : AnyObject?

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

    func visit(before: Visitor?, after: Visitor?) {
      if let v = before { v(self) }
      for c in children { c.visit( before, after ) }
      if let v = after { v(self) }
    }
  }

Traversing with Visitors

A visitor method on the Builder allows for customized traversal of the object tree:

func visit(before: Builder.Visitor?, after: Builder.Visitor?  = nil) {
  Builder.visit(before, after)
}

visit accepts two closures which are applied before and after visiting a node’s children, respectively. Here is a simplified visitor for generating HTML markup:

visit( {
  let node = $0
  let r = repeat(" ", node.level*2)
  var tag = "(r)<(node.name)"
  for a in node.attr { tag += " "(a.0)"="(a.1)"" }
  tag += ">"
  if let v:AnyObject = node.value { tag += "(v)" }
  println(tag)
  },
  {
    let node = $0
    let r = repeat(" ", node.level*2)
    var tag = "(r)</(node.name)>"
    println(tag)
  } )

Notes

  1. Swift closures aren’t dynamic in that variables and methods in a closure are bound at compile time. This is in contrast with dynamic closures in Groovy for example, where methods calls within closures are’t checked at compile time and an exception can be thrown at runtime. Further, references to instance members are required to be explicit with a self. prefix, which only adds to verbosity.

  2. In this example, tree node methods such as div are kept in the global namespace to avoid self. prefix clutter.

Source

The full source listing can be found here.

Key Value Observation in Swift

With XCode Beta 5, this article is outdated. See updated article .

Documentation for KVO in Swift is listed as information forthcoming.

We favor KVO as a means for MVVM / reactive binding so we poked under the hood to see what it takes to support KVO with the current release of Swift.

Let’s start with defining a Publisher object with a property someProperty which we will observe from a Subscriber object.

import Foundation

class Publisher : NSObject {
  var someProperty = 100

  override var description: String { return "Publisher:{someProperty: (someProperty)}" }
}

As an aside, since we’re inheriting from NSObject overriding the description property gives us pretty printing abilities with println.

var pub = Publisher()
println("(pub)")

We’ll use an instance of the Subscriber class to listen for changes on Publisher.someProperty.

class Subscriber : NSObject  {
  override func observeValueForKeyPath(keyPath: String!, ofObject object: AnyObject!, change: NSDictionary!, context: CMutableVoidPointer) {
    println("observeValueForKey: (object)")
  }
}

var sub = Subscriber()

pub.addObserver(sub, forKeyPath: "someProperty", options: nil, context: nil)

Ordinarily the call addObserver should succeed and our subscriber should start receiving messages from the publisher. Instead, the REPL spits out the following error:

objc[17599]: no class for metaclass 0x10286f410
Playground execution failed: error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).
The process has been left at the point where it was interrupted, use "thread return -x" to return to the state before expression evaluation.
* thread #1: tid = 0xa8623, 0x00007fff8569375b libobjc.A.dylib`_objc_trap(), queue = 'com.apple.main-thread', stop reason = EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
  * frame #0: 0x00007fff8569375b libobjc.A.dylib`_objc_trap()
    frame #1: 0x00007fff8569389b libobjc.A.dylib`_objc_fatal + 195
    frame #2: 0x00007fff8568c6a1 libobjc.A.dylib`_class_getNonMetaClass + 454
    frame #3: 0x00007fff8568d1f8 libobjc.A.dylib`_class_resolveMethod + 99
    frame #4: 0x00007fff856982c8 libobjc.A.dylib`lookUpImpOrForward + 286
    frame #5: 0x00007fff8568acb8 libobjc.A.dylib`class_getInstanceMethod + 52
    frame #6: 0x00007fff866bc277 Foundation`+[NSObject(NSKeyValueObservingCustomization) keyPathsForValuesAffectingValueForKey:] + 213
    frame #7: 0x00007fff866bbf21 Foundation`-[NSKeyValueUnnestedProperty _givenPropertiesBeingInitialized:getAffectingProperties:] + 141
    frame #8: 0x00007fff866bbc26 Foundation`-[NSKeyValueUnnestedProperty _initWithContainerClass:key:propertiesBeingInitialized:] + 145
    frame #9: 0x00007fff866bb7d9 Foundation`NSKeyValuePropertyForIsaAndKeyPathInner + 281
    frame #10: 0x00007fff866bb47b Foundation`NSKeyValuePropertyForIsaAndKeyPath + 169
    frame #11: 0x00007fff866e16d7 Foundation`-[NSObject(NSKeyValueObserverRegistration) addObserver:forKeyPath:options:context:] + 80

Apparently, even through our Publisher object inherits from NSObject, two class methods required for KVO are missing, namely keyPathsForValuesAffectingValueForKey and automaticallyNotifiesObserversForKey.

Let’s add these methods to Publisher with a default implementation:

extension Publisher {
  override class func keyPathsForValuesAffectingValueForKey(key: String!) -> NSSet! {
    return nil
  }

  override class func automaticallyNotifiesObserversForKey(key: String!) -> Bool {
    return true
  }
}

Now our subscriber receives change notifications from the publisher:

println("Changing value to 101")
pub.someProperty = 101

//Output
Changing value to 101
observeValueForKey: Publisher:{someProperty: 101}

Syntactic Sugar

With a little bit of syntactic sugar, we can clean up the subscription code to look like this:

pub.addSubscriber("someProperty") { println("callback: ($0), ($1)") }
println("Changing value to 102")
pub.someProperty = 102

//Output
Changing value to 102
callback: someProperty, Publisher:{someProperty: 102}

And the code:

typealias ObserverCallback = (String, AnyObject) -> ()

class SimpleSubscriber: NSObject {
  var callback: ObserverCallback

  init( cb: ObserverCallback ){
    self.callback = cb
  }

  override func observeValueForKeyPath(path: String!, ofObject object: AnyObject!, change: NSDictionary!, context: CMutableVoidPointer) {
    callback(path!, object!)
  }
}

extension Publisher {
  func addSubscriber(path: String, sub: NSObject) {
    self.addObserver(sub, forKeyPath: path, options: nil, context: nil)
  }

  func addSubscriber(path: String, sub: ObserverCallback ) {
    var wrapped = SimpleSubscriber(sub)
    self.addObserver(wrapped, forKeyPath: path, options: nil, context: nil)
  }
}

Regular Expressions in Switch Statements

Expression Patterns in Swift appear in switch statement case labels. The expression represented by the expression pattern is compared with the value of the switch statement input using the Swift standard library ~= operator. The matches succeeds if the ~= operator returns true. By default, the ~= operator compares two values of the same type using the == operator. It can also match an integer value with a range of integers in an Range object. The ~= operator can be extended to provide custom expression matching behavior.

In this post, we will extend the ~= operator to match the String type with regular expressions (specifically NSRegularExpression). Combined with bit of syntactic sugar, we will be able to write compact pattern expressions like this:

switch("apple"){
  case "appl": println("string")        
  case ~/"a..le": println("regex")  // Match!
  default: println("none")
}

//Output: regex

In this example, the switch statement matches the second case which is a regular expression a..pl.

Extending the ~= Operator

We can extend the ~= Operator to match NSRegularExpression:

func ~=(pattern: NSRegularExpression, str: NSString) -> Bool {
  return pattern.numberOfMatchesInString(str, options: nil, range: NSRange(location: 0,  length: str.length)) > 0
}

The pattern matching ~= operator is not commutative. A reverse matcher must be defined for cases where the input to the switch statement is a regular expression and is being compared to string via a case statement.

We can now introduce a regular expression in a switch statement to and check for matches:

switch("apple"){
  case "appl": println("string")
  case NSRegularExpression(pattern: "a..le", options: nil, error: nil): println("regex")
  default: println("none")
}

//Output: regex

Regex Creating Operator

Borrowing from Groovy et al., we can define a regex creating operator which accepts a string and returns a NSRegularExpression object (using default options, for now).

operator prefix ~/ {}

@prefix func ~/(pattern: String) -> NSRegularExpression {
  return NSRegularExpression(pattern: pattern, options: nil, error: nil)
}

This lets us create regex objects with the compact notation from the first example.

~/"\\wpple" ~= "apple is a fruit"     //Boolean: true

Note that the regex group \w is escaped in the string literal.

In Swift, custom prefix and postfix operators cannot specify precedence, requiring the use of parenthesis: (~/”a..pl”).numberOfMatchesInString(…)

List Traversal with Discriminated Unions in Swift

… by decoupling how a function recurses over data from what the function actually does, we reduce cognitive overhead and can focus entirely on the core behavior of our recursive functions. No matter the structures in question—lists, directory hierarchies, control flow graphs, database records—recursion schemes bring us an orderly and predictable way to traverse them.
Link

Swift supports Discriminated Unions as first class citizens within the language. This creates interesting possibilities especially with respect to pattern matching. Here is an example of recursive traversal of a native Array with a discriminated union:

let list = [1,2,3,4,5]

func sum( l : Array<Int> ) -> Int {
  switch( l as Structure ) {
  case let .Cons(head, tail) : return head + sum(tail)
  case .Empty: return 0
  }
}

println(sum(list))  //Output: 15

Here the enum Structure is representation of contents of the list as a head::tail structure.

enum Structure<T>{
  case Cons( T, Array<T> )
  case Empty
}

The enumeration has two cases:

  • Empty: represents a list with no elements.
  • Cons: represents a list as two parts: a head element for the first element in the list and a tail list comprising the remaining list elements.

Finally, an Array extension provides type conversion between a list and its corresponding Structure representation:

extension Array {
  func __conversion() -> Structure<T> {
    switch(count) {
    case 0: return Structure.Empty
    case 1: return Structure.Cons(head, [])
    default: return Structure.Cons(head, tail)
    }
  }

  //Returns the tail of this list using copy semantics
  var tail : Array<T> {
  var t = Array<T>()
    for x in self[1..count] { t.append(x) }
    return t
  }

  //Returns the head element of the list (count must be >=1)  
  var head : T { return self[0] }
}

Opt-in Type Conversion Method in Swift

Swift supports opt-in to convert an object to a type via the instance method __conversion(). This method can used through the as operator and is overloadable to support conversion to multiple types:

class X {
  func __conversion() -> String { return "as a string!" }
  func __conversion() -> Double { return 101.2 }
}

println( X() as String )  //Output: as a string!

var d : Double = X()      
println( d )              //Output: 101.2