Swift

Swift

  • Apple's replacement for Objective-C
  • Open source
  • Modern design and features
  • iOS, Mac OS, Linux, Windows
  • In the "C" family of languages

Why we're talking about it

  • Really cool and powerful language features
  • Now runs outside of Apple's walled garden
  • A great first language
  • Static typing without being a pain in the ass
  • Way better than Objective-C

Objective-C

- (NSString *) generateMD5Hash:(NSString *)filePath {
    unsigned char dataOutput[CC_MD5_DIGEST_LENGTH];
    NSData *fileData = [[NSData alloc] initWithContentsOfFile:filePath];
    CC_MD5([fileData bytes], [fileData length], dataOutput);
    [fileData release];

    NSMutableString *md5HashStr = [[NSMutableString alloc] init];
    for (NSUInteger i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
        [md5HashStr appendFormat:@"%02x", dataOutput[i]];
    }
    return [md5HashStr autorelease];
}

Swift Basics

Static Inferred Typing

// Explicit Typing
var myName: String = "Alex"
var myCoolness: Int = 3 // you decide the scale...
var myHeightInFeet: Float = 6.17

// Implicit Typing
var myName = "Alex"
var myCoolness = 3
var myHeightInFeet = 6.17

// Override what the compiler would choose
var myFloatingPointNumber: Float = 42

Constants

// "var" for variables
var myName = "Alex"
myName = "Kylo Ren"

// "let" for constants
let myName = "Alex"
myName = "Kylo Ren" // <COMPILE ERROR>

String Interpolation

let myName = "Alex"
let myCoolness = 3
print("\(myName) is \(myCoolness) cool")
// Alex is 3 cool

Typed Arrays & Dictionaries

// Type inferred: [String]
var awesomeCharacters = ["Wash", "Kaylee", "Inara"]
awesomeCharacters.append("River")
awesomeCharacters[1] // Kaylee
awesomeCharacters.append(4) // <COMPILE ERROR>

// Type inferred: [String: Int]
var movieReviews = [
    "Alien":  9,
    "Aliens": 9,
]
movieReviews["Alien 3"] = 4
movieReviews["Alien vs Predator"] = "wat" //
    // <COMPILE ERROR>

Named Arguments

// first argument doesn't require a label. *
func foo(a: Int, b: Int) {}
foo(1, b: 2)

// You can require a specific label.
func bar(aValue a: Int, bValue b: Int) {}
bar(aValue: 1, bValue: 2)

// _ allows you to ignore a label.
func raz(a: Int, _ b: Int) {}
raz(1, 2)

// * This is for Swift 2
// It changed a bit in Swift 3...

Optionals

​What if nullability was a declared part of your data model?

 

  • java.lang.NullPointerException
  • NoMethodError: undefined method `strip' for nil:NilClass
  • TypeError: Cannot read property 'length' of null

Optionals

var fullName: String = "Alex Wayne"
var nickName: String? = nil // ? declares an optional

// Check an optional for a value, and use its value
if nickName != nil {
  print(nickName!) // ! unwraps an optional
} else {
  print(fullName)
}

Optionals in Conditionals

var nickName: String? = nil

// "if let" tests for and assigns an optional
if let aka = nickName {
  print("also known as: \(aka)") // no unwrap
}

Coalescing Optionals

var fullName: String = "Alex Wayne"
var nickName: String? = nil

// ?? is the "nil coalescing operator"
let name = nickName ?? fullName

// equivalent to
let name = nickName != nil ? nickName! : fullName

Optional Chaining

// ? is the optional chaining operator

var nickName: String? = nil
nickName?.count // type: Int?, value: nil

nickName = "Bo Jangles"
nickName?.count // type: Int?, value: 10

Classes and Structs

init

class Person {
    let name: String // can't be changed
    var coolness: Int = 0 // starts at zero
    var darkSecret: String? // may not have this

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

let me = Person(name: "Alex")
me.coolness = 3

Completeness is enforced!

class Person {
    let name: String // can't be changed
    var coolness: Int = 0 // starts at zero
    var darkSecret: String? // may not have this

    init(name: String) {
        // <COMPILE ERROR>
        // required variable "name" has no value
    }
}

Methods

class Person {
    func greet(phrase: String = "Hello") {
        print("\(phrase), \(name)")
    }
}

let me = Person(name: "Alex")
me.greet() // Hello, Alex
me.greet("Hi") // Hi, Alex

Classes

Structs

// Creates a value
struct MyStruct {
    var name: String
    // init is optional. Swift
    // assumes you want to set
    // all instance variables.
}

// create a struct
var a = MyStruct(name: "A")

// copy and modify a struct
var b = a
b.name = "B"

// 2 structs
a.name // "A"
b.name // "B"
// Creates an instance
class MyClass {
    var name: String
    init(name: String) {
        self.name = name
    }
}

// create an instance
var a = MyClass(name: "A")

// set a & b to same instance
var b = a
b.name = "B"

// 1 instance
a.name // "B"
b.name // "B"

Functional Stuff

Methods are Functions

class PersonLoader {    
    init(id: Int) {
        HttpClient
            .get("http://myapi.com/people/\(id)/name")
            .onComplete(self.sayName) // callback
    }

    func sayName(name: String) {
        print("your name: \(name)")
    }
}

PersonLoader(id: 123)
// loads data, then later:
// "your name: Alex"

Functions have types

func summer(a: Int, b: Int) -> Int { return a + b }
func multer(a: Int, b: Int) -> Int { return a * b }

func math(
    _ op: (Int, Int) -> Int, // function type
    _ a: Int,
    _ b: Int
) -> Int { // return value is Int
    return op(a, b) // run the operation
}

math(summer, 5, 7) // 12
math(multer, 5, 7) // 35

Enumerations

Enumerations

enum Gender {
    case Male
    case Female
}

class Person {
    var gender: Gender
    init(gender: Gender) {
        self.gender = gender
    }
}

let me = Person(gender: Gender.Male)
let me = Person(gender: .Male) // shorthand

Enumerations: Methods

enum Gender {
    case Male
    case Female
    
    var namePrefix: String {
        switch self {
        case .Male:
            return "Mr."
        case .Female:
            return "Ms."
        }
    }
}

let myGender: Gender = .Male
myGender.namePrefix // "Mr."

Enumerations: Methods

enum Gender {
    case Male
    case Female
    
    func sexChange() -> Gender {
        return self == .Male ? .Female : .Male
    }
}

var myGender: Gender = .Male
myGender.sexChange() // Gender.Female

Didn't have time for everything...

 

  • Operator overloading and creating new operators
  • Tuples and multiple return values
  • Property setters, getters
  • Property callbacks (willSet, didSet)
  • Extensions
  • Protocols

Running Swift

Run and Compile

// MySwiftProgram.swift
func greeter(phrase: String, name: String) {
    print("\(phrase), \(string)")
}
greeter("Hello", "Hack Sonoma County")
# Run your swift program
$ swift MySwiftProgram.swift
Hello, Hack Sonoma County

# Compile your swift program
$ swiftc MySwiftProgram.swift
$ ./MySwiftProgram
Hello, Hack Sonoma County

swift.org

Alex Wayne - Sep 22, 2016

alex@beautifulpixel.com

Swift

By Alex Wayne

Swift

  • 706