Logo 61e73bc61c0e1780102320e879dc3cac0e29303ea8894dd8f10c942f3ba8120f

otters.io

An adorable little blog

Swift and C Together in Perfect Harmony

Saturday — April 23rd, 2016

Nutella and peanut butter

If you’ve had to deal with any C-based frameworks or API’s in your Swift, you may have noticed that it is ever so slightly terrible. It's certainly wonderful that you can use C-based API’s in Swift but they do not fit the mold. Especially when interspersed with other Swift or Objective-C based frameworks.

Take, for example, CoreGraphics. If you use CoreGraphics in Objective-C you accept that it’s just one of the C API’s, grin, and bear it. In Swift, the references and austere global functions stick out like a sore thumb.

For example, here is snippet you could use to draw an X with CGPaths.

let context = UIGraphicsGetCurrentContext()
let path = CGPathCreateMutable()

CGPathMoveToPoint(path, nil, 0, 0)
CGPathAddLineToPoint(path, nil, 10, 10)
CGPathMoveToPoint(path, nil, 10, 0)
CGPathAddLineToPoint(path, nil, 0, 10)
CGContextAddPath(context, path)

(Full code you can paste into a playground available here)

Swift 3 has set out to improve these interactions with the old world. C API and framework designers can manually specify how Swift will interact with their projects via annotations. On top of this, Swift 3 will have a system to scan over C-based API’s and automatically infer how Swift code can interact with the API if the developer opts-in. This system will map directly onto the C-based API without any mucking around in a bridge or middle-layer. Which all sounds very magical.

How does this actually look from the Swift 3 side of things? Compare the code below, which uses the proposed style:

let context = UIGraphicsGetCurrentContext()
let path = CGMutablePath()

path.move(transform: nil, x: 0, y: 0)
path.addLine(transform: nil, x: 10, y: 10)
path.move(transform: nil, x: 10, y: 0)
path.addLine(transform: nil, x: 0, y: 10)
context.addPath(path)

This style is much more Swift-esque and pleasant to read. Bit by bit, the cruft is being converted and it’s nice to see that the C-based API’s aren’t being spared.