Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Developing iOS apps with Swift

Developing iOS apps with Swift

40 minute introduction to iOS development and Swift for Computer Science students not yet familiar with iOS and functional programming. Touching upon what components an app contains, common problems, autolayout, Swift and a little bit of functional programming.

As presented at Q42 for students from Utrecht University.

Want to know more about Q42 and Swift?
Check out: http://q42.com/swift

Mathijs Kadijk

February 27, 2015
Tweet

More Decks by Mathijs Kadijk

Other Decks in Programming

Transcript

  1. Booleans struct ShipmentResultState { var pending: Bool = true var

    notFound: Bool = false var details: Bool = false var error: Bool = false } ✗ Can create illigal states ✗ Amibiguous ✗ No state associated data
  2. Enum enum ShipmentResultViewModel { case Pending(ShipmentAddToMailboxRequest, Promise<SearchResult<Shipment>>) case NotFound(ShipmentAddToMailboxRequest) case

    Details(Shipment) case Error(ShipmentAddToMailboxRequest) } ✔ Always one valid state ✔ Very clear what a state means ✔ Contains state data
  3. Cocoa style error handling var optionalError: NSError? if let object

    = existingObjectWithID(managedObjectID, error: &optionalError) { println("Object found: \(object)") } else if let error = optionalError { println("An error occured: \(error)") } ✗ Both can be nil ✗ Both can be something ✗ Doesn't scale
  4. Cocoa style error handling var optionalError: NSError? if let object

    = existingObjectWithID(managedObjectID, error: &optionalError) { if let object = deleteObject(object, error: &optionalError) { println("Object deleted!") } else if let error = optionalError { println("An error occured: \(error)") } } else if let error = optionalError { println("An error occured: \(error)") }
  5. Result enum error handling switch existingObjectWithID(managedObjectID) { case let .Success(object):

    println("Object found: \(object)") case let .Failure(error): println("An error occured: \(error)") } ✔ Always one valid state ✔ Very clear what happend ✗ Doesn't scale
  6. Result enum error handling switch existingObjectWithID(managedObjectID) { case let .Success(object):

    switch deleteObject(object) { case .Success: println("Object deleted!") case let .Failure(error): println("An error occured: \(error)") } case let .Failure(error): println("An error occured: \(error)") }
  7. Result enum with map extension Result { func map<U>(f: T

    -> U) -> Result<U> { switch self { case let .Success(x): return .Success(f(x)) case let .Failure(x): return .Failure(x) } } }
  8. Result map example let carResult: Result<Car> = ... let colorResult:

    Result<UIColor> = carResult.map({ car in return car.color })
  9. Result map example let carResult: Result<Car> = ... let colorResult:

    Result<UIColor> = carResult.map { car in return car.color }
  10. Result map example let carResult: Result<Car> = ... let colorResult:

    Result<UIColor> = carResult.map { car in car.color }
  11. Result map example let carResult: Result<Car> = ... let colorResult:

    Result<UIColor> = carResult.map { $0.color }
  12. Result enum with flatten func flatten<T>(result: Result<Result<T>>) -> Result<T> {

    switch result { case let .Success(x): return x case let .Failure(x): return .Failure(x) } }
  13. Error handling with map + flatten let findResult = existingObjectWithID(managedObjectID)

    let deleteResult: Result<Void> = flatten(findResult.map(deleteObject))
  14. Result enum with flatmap extension Result { func flatMap<U>(f: T

    -> Result<U>) -> Result<U> { return flatten(map(f)) } }
  15. Cocoa style error handling var optionalError: NSError? if let object

    = existingObjectWithID(managedObjectID, error: &optionalError) { if let object = deleteObject(object, error: &optionalError) { println("Object deleted!") } else if let error = optionalError { println("An error occured: \(error)") } } else if let error = optionalError { println("An error occured: \(error)") }
  16. Functional style error handling switch existingObjectWithID(managedObjectID) .flatMap(deleteObject) { case .Success:

    println("Object deleted!") case let .Failure(error): println("An error occured: \(error)") }
  17. BONUS: Custom operators infix operator >>== {} func >>== <T,U>(x:

    Result<T>, f: T -> Result<U>) -> Result<U> { return x.flatMap(f) }
  18. BONUS: Optional chaining return car.map { $0.owner }.map { $0.partner

    }.map { $0.name } // == return car.owner?.partner?.name