WWDC 2016, session 404: Getting Started with Swift

Posted on September 15, 2016


Basics

It is possible to use a range as a subscript and replace 3 items with 2

var packingList = ["Socks", "Shoes"]
packingList.append(contentsOf: ["Shorts", "Sandals", "Sunblock"])
packingList[3...5] = ["Hoodie", Scarf]

Case can be a range or a statement:

case 13...19:
  // ...
case let decade where decade % 10 == 0:
  // ...

This is a complete switch statement, no need for default:

switch (username, passwordIsValid) {
case ("admin", true):
  print("Welcome back, administrator")
case ("guest", _):
  print("Guests not allowed")
case (_, let isValid):
  print(isValid? "Welcome": "ACCESS DENIED")  
}

Fuctions & Closures (16:30)

Demonstrate a function without label for 1st argument and a default value for the 3rd argument

func sendMessage(_ message: String, to recipient: String, shouting: Bool = false) {
  var message = "\(message) \(recipient)!"
  if shouting {
    message = message.uppercased()
  }
  print(message)
}

sendMessage("Hey", to: "Morgan")

Filtering Numbers (23:31)

// We need a function that takes a function as an argument
func filterInts(_ numbers: [Int], _ includeNumber: [?]) -> [Int] {}

// A function is declared as (parameter types) -> return type
func filterInts(_ numbers: [Int], _ includeNumber: (Int) -> Bool) -> [Int] {}

// The body would look like
func filterInts(_ numbers: [Int], _ includeNumber: (Int) -> Bool) -> [Int] {
  var result: [Int] = []
  for number in numbers {
    if includeNumber(number) {
      result.append(number)
    }
  }
  return result
}

// And this is how to call this function
let numbers = [4, 17, 34, 41, 82]
func divisibleByTwo(_ number: Int) -> Bool {
  return n % 2 == 0
}
let evenNumbers = filterInts(numbers, divisibleByTwo)

// divisibleByTwo is just a name so we don't really need it:
let evenNumbers = filterInts(numbers, { (number: Int) -> Bool in return n % 2 == 0 })

// but the function type of the includeNumber parameter is already known so we can remove it
let evenNumbers = filterInts(numbers, { number in return n % 2 == 0 })

// when the whole body of the closure is a return statement, the return keyword is not needed
let evenNumbers = filterInts(numbers, { number in n % 2 == 0 })

// and then we can use an implicit argument
let evenNumbers = filterInts(numbers, { $0 % 2 == 0 })

// Since the closure is the last argument, it can be written as a "trailing closure"
let evenNumbers = filterInts(numbers) { $0 % 2 == 0 }

Data Types

Computed properties

struct Rectangle {
  var width: Int
  var height: Int
  var area: Int {
    return width * height
  }
}

Swifts implements a member-wise initializer for structures

let small = Rectangle(width: 4, height: 5)

A structure acts like a “big value” - anytime it makes sense to check for equality or to make a copy, you usually want a value like a structure.

A structure can have an extension and that extension can conform to a protocol

struct HumanPlayer: Player {}
extension HumanPlayer: CustomStringConvertible {
  var description: String {
    return "custom string"
  }
}

Enumeration syntax is similar to structs and classes

enum Alignment {
  case left, right
}
let textAlignment = Alignment.left

Enumerations can have associated values

enum Alignment {
  case left(padding: Double), right(padding: Double)
}
let textAlignment = Alignment.left(padding: 42.9)

Stay in touch!