Intermediate 
Swift 
@ColinEberhardt 
ShinobiControls
How would you 
describe Swift 
in three words?
Java 
Boring 
Simple 
Gang of Four
C# 
Expressive 
Fun 
Java++
JavaScript 
Rapid 
Simple 
Broken!
Objective-C 
Powerful 
Ugly
Swift 
????
Swift hates nil
Value 
Types 
Reference 
Types 
nill-able 
references 
Objective-C ✓ ✓ ✓ 
† 
Java ✓ ✓ ✓ 
† 
JavaScript ✓ ✓ ✓ 
C# ✓ ✓ ✓ 
Swift ✓ ✓ ✗ 
† Non extensible
nil is a bad thing
RACSignal *signal = [[self.services getFlickrSearchService] 
flickrImageMetadata:self.photo.identifier];
RACSignal *signal = [[self.services getFlickrSearchService] 
flickrImageMetadata:self.photo.identifier]; 
RACSignal *signal; 
if (self.services && self.photo && self.photo.identifier) { 
id<RWTFlickrSearch> searchService = [self.services getFlickrSearchService]; 
if (searchService) { 
signal = [searchService flickrImageMetadata:self.photo.identifier]; 
} 
}
Opt-in with Optionals
var person: String? 
! 
! 
var car: String? = "Porsche"
var car: String? // car is nil 
car = "Porsche" 
! 
// checked 
if let actuallyACar = car { 
if actuallyACar.hasPrefix("P") { 
println("It's a 'P'") 
} 
} 
! 
// unchecked 
// fatal error: unexpectedly found nil while 
// unwrapping an Optional value 
if car!.hasPrefix("P") { 
println("It's a 'P'") 
} 
! 
// chaining 
if let hasPrefix = car?.hasPrefix("P") { 
if hasPrefix { 
println("It's a 'P'") 
} 
}
Swift likes sugar
var car: String? 
! 
! 
var car: Optional<String> = "Porsche"
enum Optional<T> : Reflectable, NilLiteralConvertible { 
case None 
case Some(T) 
init() 
var hasValue: Bool { get } 
! 
static func convertFromNilLiteral() -> T? 
}
// checked 
if let actuallyACar = car { 
if actuallyACar.hasPrefix("P") { 
println("It's a 'P'") 
} 
} 
// sugar free 
var car: Optional<String> = "Porsche" 
! 
switch car { 
case .None: 
println("nothing here") 
case .Some(let actuallyACar): 
if actuallyACar.hasPrefix("P") { 
println("It's a 'P'") 
} 
}
Opt-out of unwrapping with 
implicit optionals
var car: String! = "Porsche" 
! 
// unchecked - minus the unwrapping 
if car.hasPrefix("P") { 
println("It's a 'P'") 
}
Swift meets Objective-C
Objective-C permits nil 
… as a result anything returned by the 
APIs could be a nil reference
AnyObject!
Variables are always 
surprised! or 
confused?
Swift initialisation 
is strict
Swift initialisation 
is really strict
The Commandments
Thou shalt initialise all properties of your type! 
Thou shalt not call super init before properties are initialised! 
Thou shalt not call class methods until all properties are initialised! 
Thou shalt not use super properties before super.init! 
Thou shalt only call designated initialisers on the superclass! 
Thou shalt not call super initialisers from convenience initialisers! 
Thou shalt not call class methods before super.init ! 
Thou shalt not kill
Thou shalt initialise all properties of your type! 
Thou shalt not call super init before properties are initialised! 
Thou shalt not call class methods until all properties are initialised! 
Thou shalt not use super properties before super.init! 
Thou shalt only call designated initialisers on the superclass! 
Thou shalt not call super initialisers from convenience initialisers! 
Thou shalt not call class methods before super.init ! 
Thou shalt not kill
Thou shalt initialise all properties of your type! 
Thou shalt not call super init before properties are initialised! 
Thou shalt not call class methods until all properties are initialised! 
Thou shalt not use super properties before super.init! 
Thou shalt only call designated initialisers on the superclass! 
Thou shalt not call super initialisers from convenience initialisers! 
Thou shalt not call class methods before super.init ! 
Thou shalt not kill
Thou shalt initialise all properties of your type! 
Thou shalt not call super init before properties are initialised! 
Thou shalt not call class methods until all properties are initialised! 
Thou shalt not use super properties before super.init! 
Thou shalt only call designated initialisers on the superclass! 
Thou shalt not call super initialisers from convenience initialisers! 
Thou shalt not call class methods before super.init ! 
Thou shalt not kill
Thou shalt initialise all properties of your type! 
Thou shalt not call super init before properties are initialised! 
Thou shalt not call class methods until all properties are initialised! 
Thou shalt not use super properties before super.init! 
Thou shalt only call designated initialisers on the superclass! 
Thou shalt not call super initialisers from convenience initialisers! 
Thou shalt not call class methods before super.init ! 
Thou shalt not kill
Thou shalt initialise all properties of your type! 
Thou shalt not call super init before properties are initialised! 
Thou shalt not call class methods until all properties are initialised! 
Thou shalt not use super properties before super.init! 
Thou shalt only call designated initialisers on the superclass! 
Thou shalt not call super initialisers from convenience initialisers! 
Thou shalt not call class methods before super.init ! 
Thou shalt not kill
Thou shalt initialise all properties of your type! 
Thou shalt not call super init before properties are initialised! 
Thou shalt not call class methods until all properties are initialised! 
Thou shalt not use super properties before super.init! 
Thou shalt only call designated initialisers on the superclass! 
Thou shalt not call super initialisers from convenience initialisers! 
Thou shalt not call class methods before super.init ! 
Thou shalt not kill
Thou shalt initialise all properties of your type! 
Thou shalt not call super init before properties are initialised! 
Thou shalt not call class methods until all properties are initialised! 
Thou shalt not use super properties before super.init! 
Thou shalt only call designated initialisers on the superclass! 
Thou shalt not call super initialisers from convenience initialisers! 
Thou shalt not call class methods before super.init ! 
Thou shalt not kill
class Cat: Animal { 
... 
init(name: String, isLongHaired: Bool) { 
// initialize *all* class properties 
// no calls to 'self' methods here 
super.init(name: name) 
// perform initialisation that requires self & super 
// possibly update superclass properties 
} 
convenience init() { 
// can only call designated initializers on self 
self.init(name: "kitty", isLongHaired: false) 
} 
}
Strictness bites
import Foundation 
! 
class Animal { 
let name: String 
init(name: String) { 
self.name = name.capitalizedString 
} 
} 
! 
class Cat: Animal { 
let catName: String 
override init(name: String) { 
super.init(name: name) 
! 
// error: property 'self.catName' not 
// initialized at super.init call 
self.catName = self.name + "-kins" 
} 
}
Solution - make catName 
surprised! 
class Cat: Animal { 
let catName: String! 
override init(name: String) { 
super.init(name: name) 
self.catName = self.name + "-kins" 
} 
}
Spot the 
semicolon!
Swift is a bit 
muddled up!
! 
class Cat { 
... 
init(name: String) { 
... 
} 
func updateWithName(name: String, isLongHaired: Bool) { 
... 
} 
} 
! 
func updateTheCatsName(cat: Cat, newName: String, isLongHaired: Bool) { 
... 
} 
!! 
// initializers - named parameters 
let cat = Cat(name: "molly") 
! 
// global functions - no named parameters 
updateTheCatsName(cat, "frank", true) 
! 
// methods - second and subsequent parameters are named 
cat.updateWithName("frank", isLongHaired: true); 
!
! 
class Cat { 
... 
init(_ name: String) { 
... 
} 
func updateWithName(#name: String, isLongHaired: Bool) { 
... 
} 
} 
! 
func updateTheCatsName(meow cat: Cat, newName: String, isLongHaired: Bool) { 
... 
} 
!! 
// initializers 
let cat = Cat("molly") 
! 
// global functions 
updateTheCatsName(meow: cat, "frank", true) 
! 
// methods 
cat.updateWithName(name: "frank", isLongHaired: true)
Delegation pattern 
class ViewController: UIViewController, UITableViewDelegate { 
! 
... 
! 
func tableView(tableView: UITableView!, didDeselectRowAtIndexPath indexPath: 
NSIndexPath!) { 
} 
func tableView(tableView: UITableView!, didEndDisplayingFooterView view: UIView!, 
forSection section: Int) { 
} 
! 
func tableView(tableView: UITableView!, canPerformAction action: Selector, 
forRowAtIndexPath indexPath: NSIndexPath!, withSender sender: AnyObject!) -> Bool { 
} 
}
Method naming 
tableView:canPerformAction:forRowAtIndexPath:withSender: 
tableView(_:canPerformAction:forRowAtIndexPath:withSender:)
Swift likes 
immutability!
Immutability - C# 
const 
readonly 
ReadOnlyCollection 
ArrayList
Immutability - Objective-C 
const 
#define 
NSArray 
NSMutableArray
Immutability is a first-class 
concept in Swift 
var is a variable, it can be re-assigned 
let is a constant, it cannot be re-assigned
Constants are everywhere 
for i in 0...5 { 
// error 
i = 27 
} 
! 
! 
! 
func square(number: Double) { 
// error 
number = number * number 
}
Mutability in practice
A variable class 
class Coordinate { 
var x: Int = 0, y: Int = 0 
} 
! 
var coord = Coordinate() 
coord.x = 56 
! 
coord = Coordinate() 
coord.y = 57; 
Class variable, you 
can change properties 
and re-assign
A constant class (almost) 
class Coordinate { 
var x: Int = 0, y: Int = 0 
} 
! 
let coord = Coordinate() 
coord.x = 56 
! 
// fails here 
coord = Coordinate() 
coord.y = 57 
A constant class can 
be mutated 
A constant class 
cannot be re-assigned
A variable struct 
struct Coordinate { 
var x: Int = 0, y: Int = 0 
} 
! 
var coord = Coordinate() 
coord.x = 56 
! 
coord = Coordinate() 
coord.y = 57 
Variable struct, you 
can change properties 
and re-assign 
Just like variable 
classes!
Constant structs are 
immutable :-) 
struct Coordinate { 
var x: Int = 0, y: Int = 0 
} 
! 
let coord = Coordinate() 
// error: fails here 
coord.x = 56 
! 
coord = Coordinate() 
coord.y = 57 
! 
Constant struct, you 
cannot mutate it! 
This is super-awesome, 
by changing a keyword, 
you change the 
mutability of the entire 
object.
Strings, Arrays and 
Dictionaries are structs 
// a variable array 
var coord = [1,2,3,4] 
! 
// can be mutated! 
coord[1] = 5 // “[1, 4, 3, 4]” 
// a constant array 
let coord = [1,2,3,4] 
! 
// error: ’@lvalue $T5' is not identical to 'Int' 
coord[1] = 5;
Creating Immutable Types 
struct Coordinate { 
var x = 0, y = 0 
func transpose() { 
let temp = x 
// error: cannot assign to ‘x’ in ‘self’ 
x = y 
y = temp 
} 
}
Mutating Functions 
struct Coordinate { 
var x = 0, y = 0 
mutating func transpose() { 
let temp = x 
// no error! 
x = y 
y = temp 
} 
}
Mutating Functions 
// a variable coordinate 
var coord = Coordinate() 
coord.transpose() 
! 
! 
! 
// a constant coordinate 
let constCoord = Coordinate() 
! 
// error: immutable value of type ‘Coordinate' 
// only has mutating members named 'transpose' 
constCoord.transpose()
Structs are value-types 
func trimArrayToLength<T>(array: [T], length: Int) { 
while array.count > length { 
// error: immutable value of type '[T]' only 
// has mutating members named 'removeLast' 
array.removeLast() 
} 
}
Structs are value-types 
func trimArrayToLength<T>(inout array: [T], length: Int) { 
while array.count > length { 
array.removeLast() 
} 
} 
! 
var myArray = [1,3,5,3,8,9] 
trimArrayToLength(&myArray, 3) 
println(myArray) // [1,3,5]
Whenever you start typing var, 
type let instead, only changing it 
back to var if it does not compile!
Swift is 
Functional
First-class functions 
import Foundation 
! 
func square(number: Double) -> Double { 
return number * number 
} 
! 
let a = 3.0, b = 4.0 
let c = sqrt(square(a) + square(b)) 
println(c) // 5.0
import Foundation 
! 
func square(number: Double) -> Double { 
return number * number 
} 
! 
let operation = square 
! 
let a = 3.0, b = 4.0 
let c = sqrt(operation(a) + operation(b)) 
println(c) // 5.0
Function types 
let operation = square 
The type of 
operation is being 
inferred 
But what *is* the 
type?
Function types 
let operation:(Double) -> Double = square
Functions can be: 
Assigned to variables or 
constants 
Passed to / from other functions
Fun with functions 
func * (fn: () -> (), times: Int) { 
for _ in 0..<times { 
fn() 
} 
} 
! 
{ println("Swift rocks!") } * 3 
! 
// Swift rocks! 
// Swift rocks! 
// Swift rocks! 
http://ijoshsmith.com/2014/07/05/custom-threading-operator-in-swift/
More functional fun …
// non functional 
var evens = [Int]() 
for i in 1...10 { 
if i % 2 == 0 { 
evens += [i] 
} 
} 
! 
var evenSum = 0 
for i in evens { 
evenSum += i 
} 
// functional 
evenSum = Array(1...10) 
the sum of all 
even numbers 
between 1 and 10 
.filter { (number) in number % 2 == 0 } 
.reduce(0) { (total, number) in total + number }
Partial application 
func createSplitter(separator:String) -> (String -> [String]) { 
func split(source:String) -> [String] { 
return source.componentsSeparatedByString(separator) 
} 
return split 
} 
let data = "5,7;3,4;55,6" 
let commaSplitter = createSplitter(",") 
commaSplitter(data) 
! 
let semiColonSplitter = createSplitter(";") 
semiColonSplitter(data)
Curried functions 
func createSplitter(separator:String) -> (String -> [String]) { 
func split(source:String) -> [String] { 
return source.componentsSeparatedByString(separator) 
} 
return split 
} 
func createSplitter(separator:String)(source:String) -> [String] { 
return source.componentsSeparatedByString(separator) 
}
class Person { 
let name: String; 
init(name: String) { 
self.name = name 
} 
func greeting() { 
println("Hello (name)") 
} 
} 
! 
let speaker = Person(name: "Colin") 
speaker.greeting() // "Hello Colin" 
! 
let speakFunction = speaker.greeting 
speakFunction() // "Hello Colin" 
! 
let curriedFunc = Person.greeting 
curriedFunc(speaker)() // "Hello Colin"
Swift is 
concise
Sorting an array 
let animals = ["fish", "cat" , "chicken", "dog"] 
! 
func isBefore(one: String, two:String) -> Bool { 
return one < two 
} 
! 
let sortedStrings = animals.sorted(isBefore) 
! 
println(sortedStrings) // [cat, chicken, dog, fish] 
! 
!
Closure expressions as 
anonymous functions 
let sorted = animals.sorted({ 
(one: String, two: String) -> Bool in 
return one > two 
})
let sorted = animals.sorted({ 
(one: String, two: String) -> Bool in 
return one > two 
}) 
46 characters
let sorted = animals.sorted({ 
(one, two) -> Bool in 
return one > two 
}) 
32 characters
let sorted = animals.sorted({ 
(one, two) in 
return one > two 
}) 
26 characters
let sorted = animals.sorted({ 
one, two in 
return one > two 
}) 
24 characters
let sorted = animals.sorted({ 
one, two in 
one > two 
}) 
19 characters
50% smaller 
let sorted = animals.sorted({ 
(one: String, two: String) -> Bool in 
return one > two 
}) 
let sorted = animals.sorted({ 
one, two in 
one > two 
})
let sorted = animals.sorted({ $0 > $1 }) 
7 characters
let sorted = animals.sorted() { $0 > $1 } 
7 characters
let sorted = animals.sorted { $0 > $1 } 
7 characters
let sorted = animals.sorted(>) 
1 character!
Swift is clear
Swift still uses ARC
Swift still has retain cycles
Objective-C syntax 
__weak typeof(self)weakSelf = self; 
[self.context performBlock:^{ 
__strong typeof(weakSelf)strongSelf = weakSelf; 
// do something with strongSelf 
}];
Swift syntax 
closure = { 
[unowned self] () -> () in 
// do something with self 
}
Swift is ‘open’
for-in and sequence 
class Fibonacci: SequenceType { 
func generate() -> GeneratorOf<Int> { 
var current = 0, next = 1 
return GeneratorOf<Int> { 
var ret = current 
current = next 
next = next + ret 
return ret 
} 
} 
} 
! 
for num in Fibonacci() { 
println(num) // 0, 1, 1, 2, 3, 5, 8, 13 
} 
! 
http://www.scottlogic.com/blog/2014/06/26/swift-sequences.html
Literal conversion 
class Person: StringLiteralConvertible { 
let name: String 
required init(name: String) { 
self.name = name 
} 
class func convertFromStringLiteral(value: StringLiteralType) -> Self { 
return self(name: value) 
} 
class func convertFromExtendedGraphemeClusterLiteral(value: String) -> Self { 
return self(name: value) 
} 
} 
! 
var people: [Person] = ["Bob", "Frank", "Brian"]
How would you 
describe Swift 
in three words?
Safe
Swift hates nil 
Swift initialisation is really strict 
Swift likes immutable types
Muddled
Swift parameter naming is 
muddled up 
Swift variables are often dazed! 
or confused?
Modern
Swift is functional 
Swift likes sugar 
Swift is clear and concise
Swift 
Safe 
Muddled 
Modern
Swift wish-list 
Some form of reflection 
Exceptions (try / catch / throw) 
A re-write of Foundation, UIKit, 
CoreData …

How would you describe Swift in three words?

  • 1.
  • 3.
    How would you describe Swift in three words?
  • 4.
    Java Boring Simple Gang of Four
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
    Value Types Reference Types nill-able references Objective-C ✓ ✓ ✓ † Java ✓ ✓ ✓ † JavaScript ✓ ✓ ✓ C# ✓ ✓ ✓ Swift ✓ ✓ ✗ † Non extensible
  • 11.
    nil is abad thing
  • 12.
    RACSignal *signal =[[self.services getFlickrSearchService] flickrImageMetadata:self.photo.identifier];
  • 13.
    RACSignal *signal =[[self.services getFlickrSearchService] flickrImageMetadata:self.photo.identifier]; RACSignal *signal; if (self.services && self.photo && self.photo.identifier) { id<RWTFlickrSearch> searchService = [self.services getFlickrSearchService]; if (searchService) { signal = [searchService flickrImageMetadata:self.photo.identifier]; } }
  • 14.
  • 15.
    var person: String? ! ! var car: String? = "Porsche"
  • 16.
    var car: String?// car is nil car = "Porsche" ! // checked if let actuallyACar = car { if actuallyACar.hasPrefix("P") { println("It's a 'P'") } } ! // unchecked // fatal error: unexpectedly found nil while // unwrapping an Optional value if car!.hasPrefix("P") { println("It's a 'P'") } ! // chaining if let hasPrefix = car?.hasPrefix("P") { if hasPrefix { println("It's a 'P'") } }
  • 17.
  • 18.
    var car: String? ! ! var car: Optional<String> = "Porsche"
  • 19.
    enum Optional<T> :Reflectable, NilLiteralConvertible { case None case Some(T) init() var hasValue: Bool { get } ! static func convertFromNilLiteral() -> T? }
  • 20.
    // checked iflet actuallyACar = car { if actuallyACar.hasPrefix("P") { println("It's a 'P'") } } // sugar free var car: Optional<String> = "Porsche" ! switch car { case .None: println("nothing here") case .Some(let actuallyACar): if actuallyACar.hasPrefix("P") { println("It's a 'P'") } }
  • 21.
    Opt-out of unwrappingwith implicit optionals
  • 22.
    var car: String!= "Porsche" ! // unchecked - minus the unwrapping if car.hasPrefix("P") { println("It's a 'P'") }
  • 23.
  • 24.
    Objective-C permits nil … as a result anything returned by the APIs could be a nil reference
  • 25.
  • 26.
    Variables are always surprised! or confused?
  • 27.
  • 28.
  • 29.
  • 30.
    Thou shalt initialiseall properties of your type! Thou shalt not call super init before properties are initialised! Thou shalt not call class methods until all properties are initialised! Thou shalt not use super properties before super.init! Thou shalt only call designated initialisers on the superclass! Thou shalt not call super initialisers from convenience initialisers! Thou shalt not call class methods before super.init ! Thou shalt not kill
  • 31.
    Thou shalt initialiseall properties of your type! Thou shalt not call super init before properties are initialised! Thou shalt not call class methods until all properties are initialised! Thou shalt not use super properties before super.init! Thou shalt only call designated initialisers on the superclass! Thou shalt not call super initialisers from convenience initialisers! Thou shalt not call class methods before super.init ! Thou shalt not kill
  • 32.
    Thou shalt initialiseall properties of your type! Thou shalt not call super init before properties are initialised! Thou shalt not call class methods until all properties are initialised! Thou shalt not use super properties before super.init! Thou shalt only call designated initialisers on the superclass! Thou shalt not call super initialisers from convenience initialisers! Thou shalt not call class methods before super.init ! Thou shalt not kill
  • 33.
    Thou shalt initialiseall properties of your type! Thou shalt not call super init before properties are initialised! Thou shalt not call class methods until all properties are initialised! Thou shalt not use super properties before super.init! Thou shalt only call designated initialisers on the superclass! Thou shalt not call super initialisers from convenience initialisers! Thou shalt not call class methods before super.init ! Thou shalt not kill
  • 34.
    Thou shalt initialiseall properties of your type! Thou shalt not call super init before properties are initialised! Thou shalt not call class methods until all properties are initialised! Thou shalt not use super properties before super.init! Thou shalt only call designated initialisers on the superclass! Thou shalt not call super initialisers from convenience initialisers! Thou shalt not call class methods before super.init ! Thou shalt not kill
  • 35.
    Thou shalt initialiseall properties of your type! Thou shalt not call super init before properties are initialised! Thou shalt not call class methods until all properties are initialised! Thou shalt not use super properties before super.init! Thou shalt only call designated initialisers on the superclass! Thou shalt not call super initialisers from convenience initialisers! Thou shalt not call class methods before super.init ! Thou shalt not kill
  • 36.
    Thou shalt initialiseall properties of your type! Thou shalt not call super init before properties are initialised! Thou shalt not call class methods until all properties are initialised! Thou shalt not use super properties before super.init! Thou shalt only call designated initialisers on the superclass! Thou shalt not call super initialisers from convenience initialisers! Thou shalt not call class methods before super.init ! Thou shalt not kill
  • 37.
    Thou shalt initialiseall properties of your type! Thou shalt not call super init before properties are initialised! Thou shalt not call class methods until all properties are initialised! Thou shalt not use super properties before super.init! Thou shalt only call designated initialisers on the superclass! Thou shalt not call super initialisers from convenience initialisers! Thou shalt not call class methods before super.init ! Thou shalt not kill
  • 38.
    class Cat: Animal{ ... init(name: String, isLongHaired: Bool) { // initialize *all* class properties // no calls to 'self' methods here super.init(name: name) // perform initialisation that requires self & super // possibly update superclass properties } convenience init() { // can only call designated initializers on self self.init(name: "kitty", isLongHaired: false) } }
  • 40.
  • 41.
    import Foundation ! class Animal { let name: String init(name: String) { self.name = name.capitalizedString } } ! class Cat: Animal { let catName: String override init(name: String) { super.init(name: name) ! // error: property 'self.catName' not // initialized at super.init call self.catName = self.name + "-kins" } }
  • 42.
    Solution - makecatName surprised! class Cat: Animal { let catName: String! override init(name: String) { super.init(name: name) self.catName = self.name + "-kins" } }
  • 43.
  • 44.
    Swift is abit muddled up!
  • 45.
    ! class Cat{ ... init(name: String) { ... } func updateWithName(name: String, isLongHaired: Bool) { ... } } ! func updateTheCatsName(cat: Cat, newName: String, isLongHaired: Bool) { ... } !! // initializers - named parameters let cat = Cat(name: "molly") ! // global functions - no named parameters updateTheCatsName(cat, "frank", true) ! // methods - second and subsequent parameters are named cat.updateWithName("frank", isLongHaired: true); !
  • 46.
    ! class Cat{ ... init(_ name: String) { ... } func updateWithName(#name: String, isLongHaired: Bool) { ... } } ! func updateTheCatsName(meow cat: Cat, newName: String, isLongHaired: Bool) { ... } !! // initializers let cat = Cat("molly") ! // global functions updateTheCatsName(meow: cat, "frank", true) ! // methods cat.updateWithName(name: "frank", isLongHaired: true)
  • 47.
    Delegation pattern classViewController: UIViewController, UITableViewDelegate { ! ... ! func tableView(tableView: UITableView!, didDeselectRowAtIndexPath indexPath: NSIndexPath!) { } func tableView(tableView: UITableView!, didEndDisplayingFooterView view: UIView!, forSection section: Int) { } ! func tableView(tableView: UITableView!, canPerformAction action: Selector, forRowAtIndexPath indexPath: NSIndexPath!, withSender sender: AnyObject!) -> Bool { } }
  • 48.
    Method naming tableView:canPerformAction:forRowAtIndexPath:withSender: tableView(_:canPerformAction:forRowAtIndexPath:withSender:)
  • 49.
  • 50.
    Immutability - C# const readonly ReadOnlyCollection ArrayList
  • 51.
    Immutability - Objective-C const #define NSArray NSMutableArray
  • 52.
    Immutability is afirst-class concept in Swift var is a variable, it can be re-assigned let is a constant, it cannot be re-assigned
  • 53.
    Constants are everywhere for i in 0...5 { // error i = 27 } ! ! ! func square(number: Double) { // error number = number * number }
  • 54.
  • 55.
    A variable class class Coordinate { var x: Int = 0, y: Int = 0 } ! var coord = Coordinate() coord.x = 56 ! coord = Coordinate() coord.y = 57; Class variable, you can change properties and re-assign
  • 56.
    A constant class(almost) class Coordinate { var x: Int = 0, y: Int = 0 } ! let coord = Coordinate() coord.x = 56 ! // fails here coord = Coordinate() coord.y = 57 A constant class can be mutated A constant class cannot be re-assigned
  • 57.
    A variable struct struct Coordinate { var x: Int = 0, y: Int = 0 } ! var coord = Coordinate() coord.x = 56 ! coord = Coordinate() coord.y = 57 Variable struct, you can change properties and re-assign Just like variable classes!
  • 58.
    Constant structs are immutable :-) struct Coordinate { var x: Int = 0, y: Int = 0 } ! let coord = Coordinate() // error: fails here coord.x = 56 ! coord = Coordinate() coord.y = 57 ! Constant struct, you cannot mutate it! This is super-awesome, by changing a keyword, you change the mutability of the entire object.
  • 59.
    Strings, Arrays and Dictionaries are structs // a variable array var coord = [1,2,3,4] ! // can be mutated! coord[1] = 5 // “[1, 4, 3, 4]” // a constant array let coord = [1,2,3,4] ! // error: ’@lvalue $T5' is not identical to 'Int' coord[1] = 5;
  • 60.
    Creating Immutable Types struct Coordinate { var x = 0, y = 0 func transpose() { let temp = x // error: cannot assign to ‘x’ in ‘self’ x = y y = temp } }
  • 61.
    Mutating Functions structCoordinate { var x = 0, y = 0 mutating func transpose() { let temp = x // no error! x = y y = temp } }
  • 62.
    Mutating Functions //a variable coordinate var coord = Coordinate() coord.transpose() ! ! ! // a constant coordinate let constCoord = Coordinate() ! // error: immutable value of type ‘Coordinate' // only has mutating members named 'transpose' constCoord.transpose()
  • 63.
    Structs are value-types func trimArrayToLength<T>(array: [T], length: Int) { while array.count > length { // error: immutable value of type '[T]' only // has mutating members named 'removeLast' array.removeLast() } }
  • 64.
    Structs are value-types func trimArrayToLength<T>(inout array: [T], length: Int) { while array.count > length { array.removeLast() } } ! var myArray = [1,3,5,3,8,9] trimArrayToLength(&myArray, 3) println(myArray) // [1,3,5]
  • 65.
    Whenever you starttyping var, type let instead, only changing it back to var if it does not compile!
  • 66.
  • 67.
    First-class functions importFoundation ! func square(number: Double) -> Double { return number * number } ! let a = 3.0, b = 4.0 let c = sqrt(square(a) + square(b)) println(c) // 5.0
  • 68.
    import Foundation ! func square(number: Double) -> Double { return number * number } ! let operation = square ! let a = 3.0, b = 4.0 let c = sqrt(operation(a) + operation(b)) println(c) // 5.0
  • 69.
    Function types letoperation = square The type of operation is being inferred But what *is* the type?
  • 70.
    Function types letoperation:(Double) -> Double = square
  • 71.
    Functions can be: Assigned to variables or constants Passed to / from other functions
  • 72.
    Fun with functions func * (fn: () -> (), times: Int) { for _ in 0..<times { fn() } } ! { println("Swift rocks!") } * 3 ! // Swift rocks! // Swift rocks! // Swift rocks! http://ijoshsmith.com/2014/07/05/custom-threading-operator-in-swift/
  • 73.
  • 74.
    // non functional var evens = [Int]() for i in 1...10 { if i % 2 == 0 { evens += [i] } } ! var evenSum = 0 for i in evens { evenSum += i } // functional evenSum = Array(1...10) the sum of all even numbers between 1 and 10 .filter { (number) in number % 2 == 0 } .reduce(0) { (total, number) in total + number }
  • 75.
    Partial application funccreateSplitter(separator:String) -> (String -> [String]) { func split(source:String) -> [String] { return source.componentsSeparatedByString(separator) } return split } let data = "5,7;3,4;55,6" let commaSplitter = createSplitter(",") commaSplitter(data) ! let semiColonSplitter = createSplitter(";") semiColonSplitter(data)
  • 76.
    Curried functions funccreateSplitter(separator:String) -> (String -> [String]) { func split(source:String) -> [String] { return source.componentsSeparatedByString(separator) } return split } func createSplitter(separator:String)(source:String) -> [String] { return source.componentsSeparatedByString(separator) }
  • 77.
    class Person { let name: String; init(name: String) { self.name = name } func greeting() { println("Hello (name)") } } ! let speaker = Person(name: "Colin") speaker.greeting() // "Hello Colin" ! let speakFunction = speaker.greeting speakFunction() // "Hello Colin" ! let curriedFunc = Person.greeting curriedFunc(speaker)() // "Hello Colin"
  • 78.
  • 79.
    Sorting an array let animals = ["fish", "cat" , "chicken", "dog"] ! func isBefore(one: String, two:String) -> Bool { return one < two } ! let sortedStrings = animals.sorted(isBefore) ! println(sortedStrings) // [cat, chicken, dog, fish] ! !
  • 80.
    Closure expressions as anonymous functions let sorted = animals.sorted({ (one: String, two: String) -> Bool in return one > two })
  • 81.
    let sorted =animals.sorted({ (one: String, two: String) -> Bool in return one > two }) 46 characters
  • 82.
    let sorted =animals.sorted({ (one, two) -> Bool in return one > two }) 32 characters
  • 83.
    let sorted =animals.sorted({ (one, two) in return one > two }) 26 characters
  • 84.
    let sorted =animals.sorted({ one, two in return one > two }) 24 characters
  • 85.
    let sorted =animals.sorted({ one, two in one > two }) 19 characters
  • 86.
    50% smaller letsorted = animals.sorted({ (one: String, two: String) -> Bool in return one > two }) let sorted = animals.sorted({ one, two in one > two })
  • 87.
    let sorted =animals.sorted({ $0 > $1 }) 7 characters
  • 88.
    let sorted =animals.sorted() { $0 > $1 } 7 characters
  • 89.
    let sorted =animals.sorted { $0 > $1 } 7 characters
  • 90.
    let sorted =animals.sorted(>) 1 character!
  • 91.
  • 92.
  • 93.
    Swift still hasretain cycles
  • 94.
    Objective-C syntax __weaktypeof(self)weakSelf = self; [self.context performBlock:^{ __strong typeof(weakSelf)strongSelf = weakSelf; // do something with strongSelf }];
  • 95.
    Swift syntax closure= { [unowned self] () -> () in // do something with self }
  • 96.
  • 97.
    for-in and sequence class Fibonacci: SequenceType { func generate() -> GeneratorOf<Int> { var current = 0, next = 1 return GeneratorOf<Int> { var ret = current current = next next = next + ret return ret } } } ! for num in Fibonacci() { println(num) // 0, 1, 1, 2, 3, 5, 8, 13 } ! http://www.scottlogic.com/blog/2014/06/26/swift-sequences.html
  • 98.
    Literal conversion classPerson: StringLiteralConvertible { let name: String required init(name: String) { self.name = name } class func convertFromStringLiteral(value: StringLiteralType) -> Self { return self(name: value) } class func convertFromExtendedGraphemeClusterLiteral(value: String) -> Self { return self(name: value) } } ! var people: [Person] = ["Bob", "Frank", "Brian"]
  • 99.
    How would you describe Swift in three words?
  • 100.
  • 101.
    Swift hates nil Swift initialisation is really strict Swift likes immutable types
  • 102.
  • 103.
    Swift parameter namingis muddled up Swift variables are often dazed! or confused?
  • 104.
  • 105.
    Swift is functional Swift likes sugar Swift is clear and concise
  • 106.
  • 107.
    Swift wish-list Someform of reflection Exceptions (try / catch / throw) A re-write of Foundation, UIKit, CoreData …