Deep Dive Into
Swift
@sarat
Software Architect
A bit of history
Chris Lattner
• Author of the original
LLVM tool chain project
• Started working on Swift
in 2010
• A research intern at
Microsoft Research
• Leads Development Tool
Effort at Apple
Why Swift?
Modern Compilers and
Optimization
Techniques
Influenced by Python,
Ruby, Objective-C, C#
etc.
Productivity
+
Native Performance
easy to learn
Playground & REPL
Playground
REPL (Read-Eval-Print-Loop)
- Write it in lldb when program runs
- Use xcrun swift to run externally
Transparent
interaction with
Objective-C & C
can deploy to previous
version of iOS and OS X
wide adoption in
short time
– The RedMonk Programming Language Rankings: January 2015
“Swift has gone from our 68th ranked
language during Q3 to number 22 this
quarter, a jump of 46 spots.”
Why Swift Performs
better?
Smaller Runtime
generates native
code
Swift Compiler
Architecture
Enumerations
similar to other
languages
enum CompassPoint {
case North
case South
case East
case West
}
enum CompassPoint {
case North
case South
case East
case West
}
var directionToHead = CompassPoint.East;
directionToHead = .East;
enum CompassPoint {
case North
case South
case East
case West
}
var directionToHead = CompassPoint.East;
directionToHead = .East;
switch(directionToHead) {
case .East:
println( "Heading east")
case .West:
println( "Heading West")
case .North:
println( "Heading North")
case .South:
println( "Heading South")
default:
println("Nowhere to go")
}
associated values
Enumerations can store associated
values of any given type.
The type can be different for each
member in the enumeration
// Associated Values Examples
enum Barcode {
case UPCA(Int, Int, Int, Int)
case QRCode(String)
}
// Associated Values Examples
enum Barcode {
case UPCA(Int, Int, Int, Int)
case QRCode(String)
}
var productBarcode = Barcode.UPCA(8, 85909, 51226, 3)
productBarcode = .QRCode("ABCDEFGHIJ")
// Associated Values Examples
enum Barcode {
case UPCA(Int, Int, Int, Int)
case QRCode(String)
}
var productBarcode = Barcode.UPCA(8, 85909, 51226, 3)
productBarcode = .QRCode("ABCDEFGHIJ")
let numberSystem = 8, manufacturer = 85909,
product = 51226, check = 3
switch productBarcode {
case let .UPCA(numberSystem, manufacturer, product, check)
println("UPCA Detected")
case let .QRCode("ABCDEFGHIJ")
println("QRCode detected")
}
switch-case pattern
matching
// Pattern Matching with Switch-Case
let x = 9
switch(x) {
case 1...5: // Closed range operator
println( "Range - 1,2,3,4,5")
case 6..<10: // Half closed range operator
println( "Range - 6,7,8,9")
default:
println("Default")
}
Properties
associates values with
classes, structure or
enumerations
Stored Properties
store constant and
variable values
Lazy Stored Properties
• Initializes on first time access
• Declared with lazy keyword
• Lazy Stored properties can’t be a constant;
for obvious reasons
• Useful when the initial values are depends
on outside factors
// Lazy initialization
class DataImporter {
}
class DataManager {
lazy var importer = DataImporter()
var data = [String]()
}
let m = DataManager()
// importer has not yet been created
m.data.append("Element 1");
m.data.append("Element 2");
m.data.append("Element 3");
// Initialize on first access
m.importer.import();
Computed Properties
computes a value
(rather than store)
// Computed properties
class Rectangle {
var height = 0
var width = 0
var area : Int {
get {
return height * width
}
}
}
Property Observers
// Property Observers
class Temperature {
var current : Int = 26 {
willSet {
println("(newValue)");
// Prints 32
}
didSet {
println("(oldValue)");
// Prints 26
}
}
}
var obj = Temperature()
obj.current = 32;
Override properties
Closures
Self-contained blocks of
functionality that can be
passed around and used in
your code.
Similar to blocks in
Objective-C
Closures
// Closures
var cities = ["New Delhi", "Trivandrum", "Kochi", "Bangalore"]
// Sort with delegates
cities.sort({ (a, b) -> Bool in
a < b
})
Closures - Trailing spaces
// Closures
var cities = ["New Delhi", "Trivandrum", "Kochi", "Bangalore"]
// Sort with delegates
cities.sort({ (a, b) -> Bool in
a < b
})
Closures - Parentheses
// Closures
var cities = ["New Delhi", "Trivandrum", "Kochi", "Bangalore"]
// Sort with delegates
cities.sort { (a, b) -> Bool in
a < b
}
Closures - Type inference
// Closures
var cities = ["New Delhi", "Trivandrum", "Kochi", "Bangalore"]
// Sort with delegates
cities.sort { (a, b) -> Bool in
a < b
}
Closures - Type inference
// Closures
var cities = ["New Delhi", "Trivandrum", "Kochi", "Bangalore"]
// Sort with delegates
cities.sort { a, b -> Bool in
a < b
}
Closures - Implicit return
// Closures
var cities = ["New Delhi", "Trivandrum", "Kochi", "Bangalore"]
// Sort with delegates
cities.sort { a, b in
a < b
}
Closures - Positional
Parameters
// Closures
var cities = ["New Delhi", "Trivandrum", "Kochi", "Bangalore"]
// Sort with delegates — Positional parameters
cities.sort { $0 < $1 }
Closures - Operator as
closure
// Closures
var cities = ["New Delhi", "Trivandrum", "Kochi", "Bangalore"]
// Sounds interesting?
cities.sort( < )
Optionals
represent possible
missing values
stack.pop?
response.parse().age?
// Age can be nil
var age : Int?
age = response.parse()
Unwrapping
var age : Int?
age = response.parse()
let x = age!
// Your program would crash if you unwrap a nil value
Optional Binding
class Person {
var residence : Residence?
}
class Residence {
var address : Address?
}
class Address {
var buildingNumber : String?
var streetName : String?
var apartmentNumber : String?
}
// Optional Binding
if let home = paul.residence {
if let postalAddress = home.address {
if let building = postalAddress.buildingNumber {
// Code
}
}
}
Optional Chaining
// Optional Chaining
let buildingNumber = paul.residence?.address?.buildingNumber
// optional chaining + bind + unwrap
if let buildingNumber = paul.residence?.address?.buildingNumber {
}
Initializer
Convenience &
Designated Initializers
designated initializers are primary
initializers of a class
a class must have at least one
designated initializer
classes tend to have few
designated initializers
convenience initializers
are secondary; supporting
initializers of a class
class Food {
var name: String
// Designated Initializer
init(name: String) {
self.name = name
}
// Convenience Initializer
convenience init() {
self.init(name: "Unnamed")
}
}
class Food {
var name: String
// Designated Initializer
init(name: String) {
self.name = name
}
// Convenience Initializer
convenience init() {
self.init(name: "Unnamed")
}
}
class Food {
var name: String
// Designated Initializer
init(name: String) {
self.name = name
}
// Convenience Initializer
convenience init() {
self.init(name: "Unnamed")
}
}
overriding
initializers
class Vehicle {
let numberOfWheels = 0
}
class Bicycle : Vehicle {
override init() {
super.init()
numberOfWheels = 2
}
}
class Car : Vehicle {
override init() {
super.init()
numberOfWheels = 4
}
}
class Vehicle {
let numberOfWheels = 0
}
class Bicycle : Vehicle {
override init() {
super.init()
numberOfWheels = 2
}
}
class Car : Vehicle {
override init() {
super.init()
numberOfWheels = 4
}
}
class Vehicle {
let numberOfWheels = 0
}
class Bicycle : Vehicle {
override init() {
super.init()
numberOfWheels = 2
}
}
class Car : Vehicle {
override init() {
super.init()
numberOfWheels = 4
}
}
class Vehicle {
let numberOfWheels = 0
}
class Bicycle : Vehicle {
override init() {
super.init()
numberOfWheels = 2
}
}
class Car : Vehicle {
override init() {
super.init()
numberOfWheels = 4
}
}
Extensions
helps you to attach
functionality data types; even
to the ones you didn’t create!
// Extension as instance method
extension Int {
func plusOne() -> Int {
return self + 1
}
}
var i = 5
i.plusOne()
10.plusOne()
// Extension as instance method
extension Int {
func plusOne() -> Int {
return self + 1
}
}
var i = 5
i.plusOne()
10.plusOne()
// Extension as instance method
extension Int {
func plusOne() -> Int {
return self + 1
}
}
var i = 5
i.plusOne()
10.plusOne()
// Extension as property
extension Double {
var km : Double { return self*1000.0 }
var m : Double { return self }
var cm : Double { return self / 100.0 }
var mm : Double { return self / 10000.0 }
var ft : Double { return self / 3.28084 }
}
let threeFeet = 3.ft // Meters
let oneInch = 25.4.mm // Meters
// Extension as property
extension Double {
var km : Double { return self*1000.0 }
var m : Double { return self }
var cm : Double { return self / 100.0 }
var mm : Double { return self / 10000.0 }
var ft : Double { return self / 3.28084 }
}
let threeFeet = 3.ft // Meters
let oneInch = 25.4.mm // Meters
// Extension as property
extension Double {
var km : Double { return self*1000.0 }
var m : Double { return self }
var cm : Double { return self / 100.0 }
var mm : Double { return self / 10000.0 }
var ft : Double { return self / 3.28084 }
}
let threeFeet = 3.ft // Meters
let oneInch = 25.4.mm // Meters
// Extension as class method
extension UIColor {
class func chilliRed() -> UIColor {
return UIColor(red: 94/255, green: 25/255, blue: 33/255,
alpha: 1)
}
}
var chilliRed = UIColor.chilliRed()
// Extension as class method
extension UIColor {
class func chilliRed() -> UIColor {
return UIColor(red: 94/255, green: 25/255, blue: 33/255,
alpha: 1)
}
}
var chilliRed = UIColor.chilliRed()
// Extension as class method
extension UIColor {
class func chilliRed() -> UIColor {
return UIColor(red: 94/255, green: 25/255, blue: 33/255,
alpha: 1)
}
}
var chilliRed = UIColor.chilliRed()
Protocols &
Delegates
Protocols are
interface definitions
class ViewController: UIViewController, FBLoginViewDelegate {
}
class ViewController: UIViewController, FBLoginViewDelegate {
}
Class
class ViewController: UIViewController, FBLoginViewDelegate {
}
ProtocolClass
protocol LoginProtocol {
func loginSuccessful()
func loginFailed()
}
class ViewController : LoginProtocol {
func loginFailed() {
// code
}
func loginSuccessful() {
// code
}
}
protocol LoginProtocol {
var someProperty : Int { get set }
func loginSuccessful()
func loginFailed()
}
class ViewController : LoginProtocol {
func loginFailed() {
// code
}
func loginSuccessful() {
// code
}
var someProperty : Int = 0 {
willSet {
// Update UI with newValue
}
didSet {
// code
}
}
}
protocol LoginProtocol {
var someProperty : Int { get set }
func loginSuccessful()
func loginFailed()
}
class ViewController : LoginProtocol {
func loginFailed() {
// code
}
func loginSuccessful() {
// code
}
var someProperty : Int = 0 {
willSet {
// Update UI with newValue
}
didSet {
// code
}
}
}
protocol LoginProtocol {
var someProperty : Int { get set }
func loginSuccessful()
func loginFailed()
}
class ViewController : LoginProtocol {
func loginFailed() {
// code
}
func loginSuccessful() {
// code
}
var someProperty : Int = 0 {
willSet {
// Update UI with newValue
}
didSet {
// code
}
}
}
protocol LoginProtocol {
var someProperty : Int { get set }
func loginSuccessful()
func loginFailed()
}
class ViewController : LoginProtocol {
func loginFailed() {
// code
}
func loginSuccessful() {
// code
}
var someProperty : Int = 0 {
willSet {
// Update UI with newValue
}
didSet {
// code
}
}
}
Generics
func swapInt(inout a:Int, inout b:Int) {
let t = a; a = b; b = t
}
func swapString(inout a:String, inout b:String) {
let t = a; a = b; b = t
}
var a = 10, b = 20
swapInt(&a, &b)
var p = "iOS 7", q = "iOS 8"
swapString(&p,&q)
func swapInt(inout a:Int, inout b:Int) {
let t = a; a = b; b = t
}
func swapString(inout a:String, inout b:String) {
let t = a; a = b; b = t
}
var a = 10, b = 20
swapInt(&a, &b)
var p = "iOS 7", q = "iOS 8"
swapString(&p,&q)
// MARK: With Generics
func Swap <T> (inout a: T, inout b: T) {
let t = a; a = b; b = t
}
Swap(&a, &b);
Swap(&p, &q);
func swapInt(inout a:Int, inout b:Int) {
let t = a; a = b; b = t
}
func swapString(inout a:String, inout b:String) {
let t = a; a = b; b = t
}
var a = 10, b = 20
swapInt(&a, &b)
var p = "iOS 7", q = "iOS 8"
swapString(&p,&q)
// MARK: With Generics
func Swap <T> (inout a: T, inout b: T) {
let t = a; a = b; b = t
}
Swap(&a, &b);
Swap(&p, &q);
// Generic Type
struct Stack<T> {
var items = [T]()
mutating func push(item: T) {
items.append(item)
}
mutating func pop() -> T {
return items.removeLast()
}
}
// Stack from somewhere
class Stack<T> {
}
// Extension
extension Stack {
func top() -> T? {
return nil
}
}
// Type constraints
func findIndex<T: Equatable>( array: [T], valueToFind: T) -> Int? {
for(index, value) in enumerate(array) {
if value == valueToFind {
return index
}
}
return nil
}
Mutating
Structures and enumerations are value
types.
By default, the properties of a value type
cannot be modified from within its
instance methods.
// Immutatbility and Mutating
struct Point {
var x = 0.0, y = 0.0
// No change in the actual object
func pointByScaling(factor: Double) -> Point {
return Point(x: self.x*factor, y: self.y*factor)
}
// Function modifies the object
mutating func scale(factor : Double) {
self.x *= factor
self.y *= factor
}
}
// Immutatbility and Mutating
struct Point {
var x = 0.0, y = 0.0
// No change in the actual object
func pointByScaling(factor: Double) -> Point {
return Point(x: self.x*factor, y: self.y*factor)
}
// Function modifies the object
mutating func scale(factor : Double) {
self.x *= factor
self.y *= factor
}
}
// Immutatbility and Mutating
struct Point {
var x = 0.0, y = 0.0
// No change in the actual object
func pointByScaling(factor: Double) -> Point {
return Point(x: self.x*factor, y: self.y*factor)
}
// Function modifies the object
mutating func scale(factor : Double) {
self.x *= factor
self.y *= factor
}
}
Advanced
Operators
struct Vector2D {
var x = 0.0, y = 0.0
}
func + (left:Vector2D, right:Vector2D) -> Vector2D {
return Vector2D(x: left.x + right.x, y: left.y + right.y)
}
// Compound Operator
func += (inout left:Vector2D, right:Vector2D) {
left.x += right.x
left.y += right.y
}
var vector = Vector2D(x: 3.0, y: 1.0)
let anotherVector = Vector2D(x: 2.0, y: 4.0)
let combinedVector = vector + anotherVector
vector += anotherVector
struct Vector2D {
var x = 0.0, y = 0.0
}
func + (left:Vector2D, right:Vector2D) -> Vector2D {
return Vector2D(x: left.x + right.x, y: left.y + right.y)
}
// Compound Operator
func += (inout left:Vector2D, right:Vector2D) {
left.x += right.x
left.y += right.y
}
var vector = Vector2D(x: 3.0, y: 1.0)
let anotherVector = Vector2D(x: 2.0, y: 4.0)
let combinedVector = vector + anotherVector
vector += anotherVector
struct Vector2D {
var x = 0.0, y = 0.0
}
func + (left:Vector2D, right:Vector2D) -> Vector2D {
return Vector2D(x: left.x + right.x, y: left.y + right.y)
}
// Compound Operator
func += (inout left:Vector2D, right:Vector2D) {
left.x += right.x
left.y += right.y
}
var vector = Vector2D(x: 3.0, y: 1.0)
let anotherVector = Vector2D(x: 2.0, y: 4.0)
let combinedVector = vector + anotherVector
vector += anotherVector
struct Vector2D {
var x = 0.0, y = 0.0
}
func + (left:Vector2D, right:Vector2D) -> Vector2D {
return Vector2D(x: left.x + right.x, y: left.y + right.y)
}
// Compound Operator
func += (inout left:Vector2D, right:Vector2D) {
left.x += right.x
left.y += right.y
}
var vector = Vector2D(x: 3.0, y: 1.0)
let anotherVector = Vector2D(x: 2.0, y: 4.0)
let combinedVector = vector + anotherVector
vector += anotherVector
struct Vector2D {
var x = 0.0, y = 0.0
}
// Custom operator - Doubling
prefix operator +++ {}
prefix func +++ (inout vector: Vector2D) ->
Vector2D {
vector += vector
return vector
}
let doubled = +++vector
struct Vector2D {
var x = 0.0, y = 0.0
}
// Custom operator - Doubling
prefix operator +++ {}
prefix func +++ (inout vector: Vector2D) ->
Vector2D {
vector += vector
return vector
}
let doubled = +++vector
struct Vector2D {
var x = 0.0, y = 0.0
}
// Custom operator - Doubling
prefix operator +++ {}
prefix func +++ (inout vector: Vector2D) ->
Vector2D {
vector += vector
return vector
}
let doubled = +++vector
operators are only
allowed in global
scope
Using Objective-C
frameworks with Swift
Bridging Header
Demo - FacebookSDK
Integration
References
• The Swift Programming Language - iBooks
• Using Swift with Objective-C and Cocoa -
iBooks
• WWDC 2014 Sessions on Swift
• Developing iOS 8 Apps with Swift -
iTunesU - Stanford

Deep Dive Into Swift

  • 1.
  • 2.
  • 3.
    A bit ofhistory
  • 4.
    Chris Lattner • Authorof the original LLVM tool chain project • Started working on Swift in 2010 • A research intern at Microsoft Research • Leads Development Tool Effort at Apple
  • 5.
  • 6.
  • 7.
    Influenced by Python, Ruby,Objective-C, C# etc.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
    REPL (Read-Eval-Print-Loop) - Writeit in lldb when program runs - Use xcrun swift to run externally
  • 13.
  • 14.
    can deploy toprevious version of iOS and OS X
  • 15.
  • 16.
    – The RedMonkProgramming Language Rankings: January 2015 “Swift has gone from our 68th ranked language during Q3 to number 22 this quarter, a jump of 46 spots.”
  • 17.
  • 18.
  • 19.
  • 20.
  • 23.
  • 24.
  • 25.
    enum CompassPoint { caseNorth case South case East case West }
  • 26.
    enum CompassPoint { caseNorth case South case East case West } var directionToHead = CompassPoint.East; directionToHead = .East;
  • 27.
    enum CompassPoint { caseNorth case South case East case West } var directionToHead = CompassPoint.East; directionToHead = .East; switch(directionToHead) { case .East: println( "Heading east") case .West: println( "Heading West") case .North: println( "Heading North") case .South: println( "Heading South") default: println("Nowhere to go") }
  • 28.
  • 29.
    Enumerations can storeassociated values of any given type. The type can be different for each member in the enumeration
  • 30.
    // Associated ValuesExamples enum Barcode { case UPCA(Int, Int, Int, Int) case QRCode(String) }
  • 31.
    // Associated ValuesExamples enum Barcode { case UPCA(Int, Int, Int, Int) case QRCode(String) } var productBarcode = Barcode.UPCA(8, 85909, 51226, 3) productBarcode = .QRCode("ABCDEFGHIJ")
  • 32.
    // Associated ValuesExamples enum Barcode { case UPCA(Int, Int, Int, Int) case QRCode(String) } var productBarcode = Barcode.UPCA(8, 85909, 51226, 3) productBarcode = .QRCode("ABCDEFGHIJ") let numberSystem = 8, manufacturer = 85909, product = 51226, check = 3 switch productBarcode { case let .UPCA(numberSystem, manufacturer, product, check) println("UPCA Detected") case let .QRCode("ABCDEFGHIJ") println("QRCode detected") }
  • 33.
  • 34.
    // Pattern Matchingwith Switch-Case let x = 9 switch(x) { case 1...5: // Closed range operator println( "Range - 1,2,3,4,5") case 6..<10: // Half closed range operator println( "Range - 6,7,8,9") default: println("Default") }
  • 35.
  • 36.
    associates values with classes,structure or enumerations
  • 37.
  • 38.
    Lazy Stored Properties •Initializes on first time access • Declared with lazy keyword • Lazy Stored properties can’t be a constant; for obvious reasons • Useful when the initial values are depends on outside factors
  • 39.
    // Lazy initialization classDataImporter { } class DataManager { lazy var importer = DataImporter() var data = [String]() } let m = DataManager() // importer has not yet been created m.data.append("Element 1"); m.data.append("Element 2"); m.data.append("Element 3"); // Initialize on first access m.importer.import();
  • 40.
    Computed Properties computes avalue (rather than store)
  • 41.
    // Computed properties classRectangle { var height = 0 var width = 0 var area : Int { get { return height * width } } }
  • 42.
  • 43.
    // Property Observers classTemperature { var current : Int = 26 { willSet { println("(newValue)"); // Prints 32 } didSet { println("(oldValue)"); // Prints 26 } } } var obj = Temperature() obj.current = 32;
  • 44.
  • 45.
  • 46.
    Self-contained blocks of functionalitythat can be passed around and used in your code.
  • 47.
    Similar to blocksin Objective-C
  • 48.
    Closures // Closures var cities= ["New Delhi", "Trivandrum", "Kochi", "Bangalore"] // Sort with delegates cities.sort({ (a, b) -> Bool in a < b })
  • 49.
    Closures - Trailingspaces // Closures var cities = ["New Delhi", "Trivandrum", "Kochi", "Bangalore"] // Sort with delegates cities.sort({ (a, b) -> Bool in a < b })
  • 50.
    Closures - Parentheses //Closures var cities = ["New Delhi", "Trivandrum", "Kochi", "Bangalore"] // Sort with delegates cities.sort { (a, b) -> Bool in a < b }
  • 51.
    Closures - Typeinference // Closures var cities = ["New Delhi", "Trivandrum", "Kochi", "Bangalore"] // Sort with delegates cities.sort { (a, b) -> Bool in a < b }
  • 52.
    Closures - Typeinference // Closures var cities = ["New Delhi", "Trivandrum", "Kochi", "Bangalore"] // Sort with delegates cities.sort { a, b -> Bool in a < b }
  • 53.
    Closures - Implicitreturn // Closures var cities = ["New Delhi", "Trivandrum", "Kochi", "Bangalore"] // Sort with delegates cities.sort { a, b in a < b }
  • 54.
    Closures - Positional Parameters //Closures var cities = ["New Delhi", "Trivandrum", "Kochi", "Bangalore"] // Sort with delegates — Positional parameters cities.sort { $0 < $1 }
  • 55.
    Closures - Operatoras closure // Closures var cities = ["New Delhi", "Trivandrum", "Kochi", "Bangalore"] // Sounds interesting? cities.sort( < )
  • 56.
  • 57.
  • 58.
  • 59.
    // Age canbe nil var age : Int? age = response.parse()
  • 60.
  • 61.
    var age :Int? age = response.parse() let x = age! // Your program would crash if you unwrap a nil value
  • 62.
  • 63.
    class Person { varresidence : Residence? } class Residence { var address : Address? } class Address { var buildingNumber : String? var streetName : String? var apartmentNumber : String? }
  • 64.
    // Optional Binding iflet home = paul.residence { if let postalAddress = home.address { if let building = postalAddress.buildingNumber { // Code } } }
  • 65.
  • 66.
    // Optional Chaining letbuildingNumber = paul.residence?.address?.buildingNumber
  • 67.
    // optional chaining+ bind + unwrap if let buildingNumber = paul.residence?.address?.buildingNumber { }
  • 68.
  • 69.
  • 70.
    designated initializers areprimary initializers of a class a class must have at least one designated initializer classes tend to have few designated initializers
  • 71.
    convenience initializers are secondary;supporting initializers of a class
  • 72.
    class Food { varname: String // Designated Initializer init(name: String) { self.name = name } // Convenience Initializer convenience init() { self.init(name: "Unnamed") } }
  • 73.
    class Food { varname: String // Designated Initializer init(name: String) { self.name = name } // Convenience Initializer convenience init() { self.init(name: "Unnamed") } }
  • 74.
    class Food { varname: String // Designated Initializer init(name: String) { self.name = name } // Convenience Initializer convenience init() { self.init(name: "Unnamed") } }
  • 75.
  • 76.
    class Vehicle { letnumberOfWheels = 0 } class Bicycle : Vehicle { override init() { super.init() numberOfWheels = 2 } } class Car : Vehicle { override init() { super.init() numberOfWheels = 4 } }
  • 77.
    class Vehicle { letnumberOfWheels = 0 } class Bicycle : Vehicle { override init() { super.init() numberOfWheels = 2 } } class Car : Vehicle { override init() { super.init() numberOfWheels = 4 } }
  • 78.
    class Vehicle { letnumberOfWheels = 0 } class Bicycle : Vehicle { override init() { super.init() numberOfWheels = 2 } } class Car : Vehicle { override init() { super.init() numberOfWheels = 4 } }
  • 79.
    class Vehicle { letnumberOfWheels = 0 } class Bicycle : Vehicle { override init() { super.init() numberOfWheels = 2 } } class Car : Vehicle { override init() { super.init() numberOfWheels = 4 } }
  • 80.
  • 81.
    helps you toattach functionality data types; even to the ones you didn’t create!
  • 82.
    // Extension asinstance method extension Int { func plusOne() -> Int { return self + 1 } } var i = 5 i.plusOne() 10.plusOne()
  • 83.
    // Extension asinstance method extension Int { func plusOne() -> Int { return self + 1 } } var i = 5 i.plusOne() 10.plusOne()
  • 84.
    // Extension asinstance method extension Int { func plusOne() -> Int { return self + 1 } } var i = 5 i.plusOne() 10.plusOne()
  • 85.
    // Extension asproperty extension Double { var km : Double { return self*1000.0 } var m : Double { return self } var cm : Double { return self / 100.0 } var mm : Double { return self / 10000.0 } var ft : Double { return self / 3.28084 } } let threeFeet = 3.ft // Meters let oneInch = 25.4.mm // Meters
  • 86.
    // Extension asproperty extension Double { var km : Double { return self*1000.0 } var m : Double { return self } var cm : Double { return self / 100.0 } var mm : Double { return self / 10000.0 } var ft : Double { return self / 3.28084 } } let threeFeet = 3.ft // Meters let oneInch = 25.4.mm // Meters
  • 87.
    // Extension asproperty extension Double { var km : Double { return self*1000.0 } var m : Double { return self } var cm : Double { return self / 100.0 } var mm : Double { return self / 10000.0 } var ft : Double { return self / 3.28084 } } let threeFeet = 3.ft // Meters let oneInch = 25.4.mm // Meters
  • 88.
    // Extension asclass method extension UIColor { class func chilliRed() -> UIColor { return UIColor(red: 94/255, green: 25/255, blue: 33/255, alpha: 1) } } var chilliRed = UIColor.chilliRed()
  • 89.
    // Extension asclass method extension UIColor { class func chilliRed() -> UIColor { return UIColor(red: 94/255, green: 25/255, blue: 33/255, alpha: 1) } } var chilliRed = UIColor.chilliRed()
  • 90.
    // Extension asclass method extension UIColor { class func chilliRed() -> UIColor { return UIColor(red: 94/255, green: 25/255, blue: 33/255, alpha: 1) } } var chilliRed = UIColor.chilliRed()
  • 91.
  • 92.
  • 93.
  • 94.
    class ViewController: UIViewController,FBLoginViewDelegate { } Class
  • 95.
    class ViewController: UIViewController,FBLoginViewDelegate { } ProtocolClass
  • 96.
    protocol LoginProtocol { funcloginSuccessful() func loginFailed() } class ViewController : LoginProtocol { func loginFailed() { // code } func loginSuccessful() { // code } }
  • 97.
    protocol LoginProtocol { varsomeProperty : Int { get set } func loginSuccessful() func loginFailed() } class ViewController : LoginProtocol { func loginFailed() { // code } func loginSuccessful() { // code } var someProperty : Int = 0 { willSet { // Update UI with newValue } didSet { // code } } }
  • 98.
    protocol LoginProtocol { varsomeProperty : Int { get set } func loginSuccessful() func loginFailed() } class ViewController : LoginProtocol { func loginFailed() { // code } func loginSuccessful() { // code } var someProperty : Int = 0 { willSet { // Update UI with newValue } didSet { // code } } }
  • 99.
    protocol LoginProtocol { varsomeProperty : Int { get set } func loginSuccessful() func loginFailed() } class ViewController : LoginProtocol { func loginFailed() { // code } func loginSuccessful() { // code } var someProperty : Int = 0 { willSet { // Update UI with newValue } didSet { // code } } }
  • 100.
    protocol LoginProtocol { varsomeProperty : Int { get set } func loginSuccessful() func loginFailed() } class ViewController : LoginProtocol { func loginFailed() { // code } func loginSuccessful() { // code } var someProperty : Int = 0 { willSet { // Update UI with newValue } didSet { // code } } }
  • 101.
  • 102.
    func swapInt(inout a:Int,inout b:Int) { let t = a; a = b; b = t } func swapString(inout a:String, inout b:String) { let t = a; a = b; b = t } var a = 10, b = 20 swapInt(&a, &b) var p = "iOS 7", q = "iOS 8" swapString(&p,&q)
  • 103.
    func swapInt(inout a:Int,inout b:Int) { let t = a; a = b; b = t } func swapString(inout a:String, inout b:String) { let t = a; a = b; b = t } var a = 10, b = 20 swapInt(&a, &b) var p = "iOS 7", q = "iOS 8" swapString(&p,&q) // MARK: With Generics func Swap <T> (inout a: T, inout b: T) { let t = a; a = b; b = t } Swap(&a, &b); Swap(&p, &q);
  • 104.
    func swapInt(inout a:Int,inout b:Int) { let t = a; a = b; b = t } func swapString(inout a:String, inout b:String) { let t = a; a = b; b = t } var a = 10, b = 20 swapInt(&a, &b) var p = "iOS 7", q = "iOS 8" swapString(&p,&q) // MARK: With Generics func Swap <T> (inout a: T, inout b: T) { let t = a; a = b; b = t } Swap(&a, &b); Swap(&p, &q);
  • 105.
    // Generic Type structStack<T> { var items = [T]() mutating func push(item: T) { items.append(item) } mutating func pop() -> T { return items.removeLast() } }
  • 106.
    // Stack fromsomewhere class Stack<T> { } // Extension extension Stack { func top() -> T? { return nil } }
  • 107.
    // Type constraints funcfindIndex<T: Equatable>( array: [T], valueToFind: T) -> Int? { for(index, value) in enumerate(array) { if value == valueToFind { return index } } return nil }
  • 108.
  • 109.
    Structures and enumerationsare value types. By default, the properties of a value type cannot be modified from within its instance methods.
  • 110.
    // Immutatbility andMutating struct Point { var x = 0.0, y = 0.0 // No change in the actual object func pointByScaling(factor: Double) -> Point { return Point(x: self.x*factor, y: self.y*factor) } // Function modifies the object mutating func scale(factor : Double) { self.x *= factor self.y *= factor } }
  • 111.
    // Immutatbility andMutating struct Point { var x = 0.0, y = 0.0 // No change in the actual object func pointByScaling(factor: Double) -> Point { return Point(x: self.x*factor, y: self.y*factor) } // Function modifies the object mutating func scale(factor : Double) { self.x *= factor self.y *= factor } }
  • 112.
    // Immutatbility andMutating struct Point { var x = 0.0, y = 0.0 // No change in the actual object func pointByScaling(factor: Double) -> Point { return Point(x: self.x*factor, y: self.y*factor) } // Function modifies the object mutating func scale(factor : Double) { self.x *= factor self.y *= factor } }
  • 113.
  • 114.
    struct Vector2D { varx = 0.0, y = 0.0 } func + (left:Vector2D, right:Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y) } // Compound Operator func += (inout left:Vector2D, right:Vector2D) { left.x += right.x left.y += right.y } var vector = Vector2D(x: 3.0, y: 1.0) let anotherVector = Vector2D(x: 2.0, y: 4.0) let combinedVector = vector + anotherVector vector += anotherVector
  • 115.
    struct Vector2D { varx = 0.0, y = 0.0 } func + (left:Vector2D, right:Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y) } // Compound Operator func += (inout left:Vector2D, right:Vector2D) { left.x += right.x left.y += right.y } var vector = Vector2D(x: 3.0, y: 1.0) let anotherVector = Vector2D(x: 2.0, y: 4.0) let combinedVector = vector + anotherVector vector += anotherVector
  • 116.
    struct Vector2D { varx = 0.0, y = 0.0 } func + (left:Vector2D, right:Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y) } // Compound Operator func += (inout left:Vector2D, right:Vector2D) { left.x += right.x left.y += right.y } var vector = Vector2D(x: 3.0, y: 1.0) let anotherVector = Vector2D(x: 2.0, y: 4.0) let combinedVector = vector + anotherVector vector += anotherVector
  • 117.
    struct Vector2D { varx = 0.0, y = 0.0 } func + (left:Vector2D, right:Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y) } // Compound Operator func += (inout left:Vector2D, right:Vector2D) { left.x += right.x left.y += right.y } var vector = Vector2D(x: 3.0, y: 1.0) let anotherVector = Vector2D(x: 2.0, y: 4.0) let combinedVector = vector + anotherVector vector += anotherVector
  • 118.
    struct Vector2D { varx = 0.0, y = 0.0 } // Custom operator - Doubling prefix operator +++ {} prefix func +++ (inout vector: Vector2D) -> Vector2D { vector += vector return vector } let doubled = +++vector
  • 119.
    struct Vector2D { varx = 0.0, y = 0.0 } // Custom operator - Doubling prefix operator +++ {} prefix func +++ (inout vector: Vector2D) -> Vector2D { vector += vector return vector } let doubled = +++vector
  • 120.
    struct Vector2D { varx = 0.0, y = 0.0 } // Custom operator - Doubling prefix operator +++ {} prefix func +++ (inout vector: Vector2D) -> Vector2D { vector += vector return vector } let doubled = +++vector
  • 121.
  • 122.
  • 123.
  • 125.
  • 126.
    References • The SwiftProgramming Language - iBooks • Using Swift with Objective-C and Cocoa - iBooks • WWDC 2014 Sessions on Swift • Developing iOS 8 Apps with Swift - iTunesU - Stanford