At the WWDC 2014, Apple unveiled Swift as a complete replacement for Objective-C, the recommended programming language for developing for the Mac OS X and iOS platforms since Apple bought NextStep in 1997.
While you can still use Objective-C for all development, knowing Apple, it makes sense to start using Swift as soon as possible.

Apple has provided excellent documentation for the new language on The main Swift page, but reading through all that may take some time. The point of these two articles is to enable you to jump in and start using Swift right away, while still knowing about some of the more interesting features. Where applicable, we will point you to Apple’s documentation for further insights.
Swift Example
let π = 3.14159 // NOTE: Unicode identifiers. 'let' defines a constant func circleArea(radius r: Double) -> Double { // NOTE: Named argument: 'r' internally, 'radius' for clients return π*r*r } let area = circleArea(radius: 1) // NOTE: 'radius:' is required println("Circle area is \(area)") // NOTE: "String interpolation": You can include expressions in Strings with \(...) class Circle { var r: Double // NOTE: An instance property. 'var' defines a variable init(radius: Double) { r = radius } init(diameter d: Double) { r = d/2 } func circumference() -> Double { return 2*π*r } } let circle = Circle(radius: 1) println("Circle circumference is \(circle.circumference())") let circumferences = [1, 2].map { r in Circle(radius: r).circumference() } println("Circumferences: \(circumferences)")
Result:
Circle area is 3.14159 Circle circumference is 6.28318 Circumferences: [6.28, 12.56]
Swift Migration
The above may look strange to Objective-C programmers, but Swift can look familiar too, like this code for a custom UIButton:
import UIKit class RoundButton: UIButton { override func drawRect(rect: CGRect) { // NOTE: Explicitly state your intention to override methods UIColor.whiteColor().setFill() let width = CGRectGetWidth(self.bounds) let height = CGRectGetHeight(self.bounds) let capRadius = height / 2 var p = CGPointZero let path = UIBezierPath() p = CGPointMake(capRadius, 0) path.moveToPoint(p) p = CGPointMake(width-capRadius, 0) path.addLineToPoint(p) path.addArcWithCenter(CGPointMake(p.x, p.y+capRadius), radius:capRadius, startAngle:-M_PI_2, endAngle:M_PI_2, clockwise:true) p = CGPointMake(capRadius, 2*capRadius) path.addLineToPoint(p) path.addArcWithCenter(CGPointMake(p.x, p.y-capRadius), radius:capRadius, startAngle:M_PI_2, endAngle:-M_PI_2, clockwise:true) path.fill() } }
The same drawRect(), utilizing more Swift features:
override func drawRect(rect: CGRect) { UIColor.whiteColor().setFill() let width = self.bounds.width let height = self.bounds.height let capRadius = height / 2 var p = CGPoint.zeroPoint let path = UIBezierPath() p = CGPoint(x: capRadius, y: 0) path.moveToPoint(p) p = CGPoint(x: width-capRadius, y: 0) path.addLineToPoint(p) path.addArcWithCenter(CGPoint(x: p.x, y: p.y+capRadius), radius:capRadius, startAngle:-M_PI_2, endAngle:M_PI_2, clockwise:true) p = CGPoint(x: capRadius, y: 2*capRadius) path.addLineToPoint(p) path.addArcWithCenter(CGPoint(x: p.x, y: p.y-capRadius), radius:capRadius, startAngle:M_PI_2, endAngle:-M_PI_2, clockwise:true) path.fill() }
Going a bit overboard:
let π = M_PI // Add a tuple to a CGPoint func +(p: CGPoint, t: (Double, Double)) -> CGPoint { // NOTE: Override the '+' operator return CGPoint(x: p.x+t.0, y: p.y+t.1) } // Assign a tuple to a CGPoint (NOTE: you cannot overload '=') infix operator << { associativity right precedence 90 } // Introduce a new operator, having the same associativity and precedence as '=' func <<(inout p: CGPoint, t: (Double, Double)) { p = CGPoint(x: t.0, y: t.1) } override func drawRect(rect: CGRect) { UIColor.whiteColor().setFill() let (width, height) = (self.bounds.width, self.bounds.height) // NOTE: Initialize two constants simultaneously let capRadius = height / 2 var p = CGPoint.zeroPoint let path = UIBezierPath() p << (capRadius, 0) path.moveToPoint(p) p << (width-capRadius, 0) path.addLineToPoint(p) path.addArcWithCenter(p+(0,capRadius), radius:capRadius, startAngle:-π/2, endAngle:π/2, clockwise:true) p << (capRadius, 2*capRadius) path.addLineToPoint(p) path.addArcWithCenter(p+(0,-capRadius), radius:capRadius, startAngle:π/2, endAngle:-π/2, clockwise:true) path.fill() }
For a list of associativity and precedence for the built in infix operators, see Binary Expressions.
Moving to Swift
So, I’m not going to waste too much of your time showing off random Swift code. The deal is to get you started writing your own fancy Swift code in a short while.
The Playground
Xcode 6 includes a file type called a Playground, where you can play with Swift as if it was a scripting language. You can create as many playgrounds in a project as you like.
A couple of tips:
- Writing e.g. map([1,2,3]) {$0*2} will probably not give you what you want. The result column just states “(4 times”), as something on the line was evaluated four times. Just assign it to something, and evaluate that:
let myList = map([1,2,3]) {$0*2} myList
- Do not call -[NSObject addObserver] in the Playground. It will crash.
- To get a nice graph in the Timeline, hover over the result column (with text like “4 times”) and click the small circle.
Using Swift from Objective-C
Besides playgrounds, you may of course add real Swift source files to projects in Xcode 6. If you create a useful class in Swift that you would like to use from Objective-C, you should add the @objc attribute in front of the class declaration (if the parent wasn’t already Objective-C compatible, as e.g. imported UIKit classes), like so:
@objc class Circle { var r: Double init(radius: Double) { r = radius } init(diameter d: Double) { r = d/2 } func circumference() -> Double { return 2*π*r } }
All applicable Swift stuff can then be used from your Objective-C code by including the project Swift header, named after your project:
#import "MyProject-Swift.h" class ObjCCirle : Circle { }
And that’s all there is to it!
For more info, see Swift and Objective-C in the Same Project.
Using Objective-C from Swift
A bit more fun, and probably something you will use a lot more often, is accessing Objective-C (and C) stuff from your Swift source code.
A lot of existing Objective-C APIs are readily available. You just have to import it, like e.g.
import UIKit
For project specific APIs, you need the Bridging Header, which Xcode 6 will offer to create for you when you first add either a Swift file to an Objective-C project, of an Objective-C file to a Swift project. The header file is named after your project, like “MyProject-Bridging-Header.h” and should include all the #imports (and possibly declarations) that you want to be accessible from Swift.
For more information please refer to Using Swift with Cocoa and Objective-C.
Optionals
When working with Objective-C APIs, you will often have to interact with Optionals. These are needed as Swift is happily devoid of pointers, so denoting that a variable may point to nothing is achieved using a type that may either be nil or an actual value.
To work with Optionals, you use ?, !, and the “if let” statement:
var possiblyNil: Circle? possiblyNil = Circle(radius: 5) possiblyNil!.circumference() // Throws if nil possiblyNil?.circumference() // A new optional that may be either nil or a Double if let notNil = possiblyNil { notNil.circumference() // notNil is not an optional } let certainlyNil: Circle? certainlyNil?.circumference() // nil if let notNil = certainlyNil { notNil.circumference() // Never executed } var shouldntBeNil: Circle! // Shouldn't ever be nil shouldntBeNil = Circle(radius: 5) shouldntBeNil.circumference() // Treat as normal variable
When designing your own Swift APIs, you should of course only use Optionals when necessary.
For more information, please see Optional Chaining and The Optional Type.
Next up…
The next article will show you the main features of Swift, enabling you to read and understand Swift code like a pro.
Continue reading Swift Goodies…