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

Taking Swift into production

Taking Swift into production

Have you already embraced Swift? We at Q42 decided to adopt Swift as soon as possible. With this talk we’ll share our learnings with the new language while building the new PostNL app. Learn about our frustrations, glorious moments and touch upon some practical Functional Programming. Of course the famous SourceKitService crashes and how we managed to use a new language for such a high profile project will also have its place. After this talk you will know wether you want to use Swift in your projects and have practical tips that will kickstart you when using Swift.

As presented at mdevcon:
http://mdevcon.com/posts/2015/01/09/mathijs-kadijk/

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

Mathijs Kadijk

March 06, 2015
Tweet

More Decks by Mathijs Kadijk

Other Decks in Programming

Transcript

  1. 3

  2. 5

  3. 9

  4. Optionals: if let pyramid if let availableOptions = availableOptions {

    if let otherDay = availableOptions.otherDay { if let timeTable = otherDay.timeTable { // Do something with timeTable } } } 22
  5. Optionals: Multiple unwrap if let greeting = greeting, name =

    name { println("\(greeting) \(name)") } Swift 1.2 only! 24
  6. Result screen: enum enum ShipmentResultViewModel { case Pending case NotFound

    case Details case Error } var state: ShipmentResultViewModel = .Pending var request: ShipmentAddToMailboxRequest var shipment: Shipment? var error: NSError? 30
  7. Result screen: enum enum ShipmentResultViewModel { case Pending case NotFound(ShipmentAddToMailboxRequest)

    case Details(ShipmentAddToMailboxRequest, Shipment) case Error(ShipmentAddToMailboxRequest, NSError) } var state: ShipmentResultViewModel = .Pending 32
  8. Result screen: Using the enum switch resultViewModel { case .Pending:

    println("Pending") case let .NotFound(request): println("NotFound: \(request)") case let .Details(request, shipment): println("Details: \(request) \(shipment)") case let .Error(request, error) println("Details: \(request) \(error)") } 33
  9. AnyObjects everywhere func dequeueReusableCellWithIdentifier(/* ... */) -> AnyObject var subviews:

    [AnyObject] { get } func constraints() -> [AnyObject] func addConstraints(_ constraints: [AnyObject]) func subpathsAtPath(_ path: String) -> [AnyObject]? func indexPathsForRowsInRect(_ rect: CGRect) -> [AnyObject] 36
  10. NSError in Swift var optionalError: NSError? if let object =

    existingObjectWithID(managedObjectID, error: &optionalError) { println("Object found: \(object)") } else if let error = optionalError { println("An error occured: \(error)") } 38
  11. NSError in Swift 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)") } 39
  12. Result enum From: func existingObjectWithID(_ objectID: NSManagedObjectID, error error: NSErrorPointer)

    -> NSManagedObject? To: func existingObjectWithID(_ objectID: NSManagedObjectID) -> Result<NSManagedObject> 42
  13. Result enum switch existingObjectWithID(managedObjectID) { case let .Success(object): println("Object found:

    \(object)") case let .Failure(error): println("An error occured: \(error)") } 43
  14. Result enum 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)") } 44
  15. 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) } } } 45
  16. 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) } } 47
  17. Error handling with map + flatten let findResult = existingObjectWithID(managedObjectID)

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

    -> Result<U>) -> Result<U> { return flatten(map(f)) } } 49
  19. Functional style error handling switch existingObjectWithID(managedObjectID) .flatMap(deleteObject) { case .Success:

    println("Object deleted!") case let .Failure(error): println("An error occured: \(error)") } 51