Swift Foundation #2

optional, error, codable model

Optional

  • Type can be declared as an optional
  • An additional state; possible to be nil
  • Int? means the Int can be nil

Optional - Forced unwrap!

Unwrap is to transform Int? to Int

let num: Int? = ... // num is an Optional Int

if num != nil {
    let unwrappedNum = num! // Forced unwrap to type Int
}

Optional - if-let unwrap

if let unwrappedNum = num {
    // unwrappedNum is a new copy
}

Optional - Shorthand 2

if let num = num {
    // num is a new copy
}

Optional - Shorthand 3

if let num {
    // num is a new copy
}

Error Handling

do-try-catch to handle a possible error

do {
    try funcThatCanThrowError()
} catch {
    print(error)
}

Error Handling - the lazy way

try! funcThatCanThrowError() // Forced try!
_ = try? funcThatCanThrowError() // Maybe.. if not nil

Error Not Handling

throws the error back to the caller

func iAmNotHandling() throws -> Bool {
    try funcThatCanThrowError() // Note: Not handled in do-try-catch
}

Throw my custom error

enum PrinterError: Error {
    case outOfPaper, noToner
}

func iCanThrowError() throws -> Bool {
    throw PrinterError.outOfPaper
}

When to handle? When to throw?

Protocol Adoption

  • Error is a protocol with no requirement
  • Protocol Oriented Programming (POP)
  • Kind of like subclass (OOP)

Protocol Encodable

  • Another protocol, but with 1 requirement
  • func encode(to: Encoder) throws
  • Luckily, default implementation provided
  • Encode objects to JSON

Protocol extension

extension MyType: Encodable {
    func encode(to: Encoder) throws {
        // My implementation
    }
}

You can extend any type to provide additional func

Custom Protocol

  • Advanced
  • Create only if you need it
  • Good design needs good naming

Codable struct

An easy way to store (and restore) a type.

struct Animal: Codable {
    var numberOfLegs: Int
}

Refer to Codable