Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Cocoa Design Patterns in Swift

8,085 views

Published on

We have this new language, Swift, which takes some familiar Apple patterns, and introduces some new ones. With tools like closures and method chaining, there are definitely some new ways to solve the age-old Obj-c architecture challenges. This talk will walk through some of the most common Obj-c design patterns rewritten in Swift, and showcase the strengths and weaknesses of this new language.

Published in: Technology
  • Be the first to comment

Cocoa Design Patterns in Swift

  1. 1. Cocoa Design Patterns in Swift @MicheleTitolo
  2. 2. • New language features • Functional patterns • Patterns in Swift • Anti-patterns What we’ll cover
  3. 3. New language features
  4. 4. Tuples
  5. 5. Tuples group multiple values into a single compound value.
  6. 6. let http404Error = (404, "Not Found") println(http404Error.0)
  7. 7. var http200Response: (statusCode: Int, statusText: String, hasBody: Bool) http200Response.statusCode = 200 http200Response.statusText = "OK" http200Response.hasBody = true
  8. 8. You can put any kind of object in a tuple
  9. 9. Generics
  10. 10. <T>
  11. 11. More than just an id
  12. 12. Abstraction
  13. 13. Create functions without declaring type
  14. 14. struct Stack<T> { var items = [T]() mutating func push(item: T) { items.append(item) } mutating func pop() -> T { return items.removeLast() } }
  15. 15. <T: Equitable>
  16. 16. AnyObject
  17. 17. ...used a lot more like id
  18. 18. Closures
  19. 19. “Closures are behaviors with attached state” - Peter Norvig
  20. 20. Like blocks, but better!
  21. 21. var closure = { (params) -> returnType in statements }
  22. 22. let
  23. 23. Immutable variable
  24. 24. var myString: String? = someFucntion() if let greeting = myString { println(greeting) } else { println("Not a string") }
  25. 25. Structs + Enums
  26. 26. Structs: Pass-by-value
  27. 27. struct Rect { var origin: Point var size: Size }
  28. 28. Structs can have methods, and conform to protocols
  29. 29. Enums: also pass-by-value
  30. 30. Also can conform to protocols and have methods
  31. 31. enum Rank: Int { case Ace = 1 case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten case Jack, Queen, King func description() -> String { switch self { case .Ace: return "ace" case .Jack: return "jack" case .Queen: return "queen" case .King: return "king" default: return String(self.toRaw()) } } }
  32. 32. Functional Patterns
  33. 33. Function Passing
  34. 34. func printExcitedly(string: String){ println(string + "!!!!!!!") } var excitedFunc = printExcitedly
  35. 35. Pass functions into functions
  36. 36. func printVeryExcitedly(excitedFunction: (String) -> Void, message: String){ excitedFunction(message.uppercaseString) } printVeryExcitedly(printExcitedly, "Hello");
  37. 37. Return functions from functions
  38. 38. func beExcited(excitementLevel: Int) -> (String) -> Void { ... }
  39. 39. Patterns
  40. 40. Composition
  41. 41. ...because we can pass functions!
  42. 42. The OO way
  43. 43. class Car { let numWheels: Int let numCylinders: Int init (numWheels: Int, numCylinders: Int) { self.numWheels = numWheels self.numCylinders = numCylinders } } var newCar = Car(numWheels: 4,numCylinders: 4) var otherCar = Car(numWheels: 4, numCylinders: 6)
  44. 44. var motorcycle = ??
  45. 45. class Motorcycle { ... }
  46. 46. This is not ideal
  47. 47. protocol Vehicle { var numWheels: Int {get set} var numCylinders: Int {get set} func drive() }
  48. 48. Better
  49. 49. How do we handle this at scale?
  50. 50. struct WheelSet { var wheelSize: Int var wheelFrictionCoefficient: Float } struct BodyType { var numWheels: Int var wheels: WheelSet var wheelBase: Float } enum EngineType: Int { case Automatic, Manual } protocol Vehicle { var body: BodyType {get set} var transmission: EngineType {get set} func drive(force: Float) func turn(speed: Float) }
  51. 51. Better
  52. 52. ...but we can still improve
  53. 53. Factories
  54. 54. Abstract away object creation and composition
  55. 55. protocol VehicleCreator { func createVehicle(bodyType: BodyType, engineType: EngineType) -> Vehicle } class VehicleFactory: VehicleCreator { func createVehicle(bodyType: BodyType, engineType: EngineType) -> Vehicle {} }
  56. 56. protocol VehicleCreator { func createVehicle(bodyType: BodyType, engineType: EngineType) -> Vehicle } class VehicleFactory: VehicleCreator { func createVehicle(bodyType: BodyType, engineType: EngineType) -> Vehicle {} } class MotorcycleFactory: VehicleCreator { func createVehicle(bodyType: BodyType, engineType: EngineType) -> Vehicle {} }
  57. 57. This still looks very OO
  58. 58. class VehicleFactory { func wheelSetGenerator(wheelSize: Int, friction: Float) -> WheelSet { return WheelSet(wheelSize: wheelSize, wheelFrictionCoefficient: friction) } func generateBodyType(wheelCount: Int, wheelType: WheelSet, wheelBase: Float) -> (Void) -> BodyType { func bodyGen() -> BodyType { return BodyType(numWheels:wheelCount, wheels:wheelType, wheelBase:wheelBase) } return bodyGen } func createVehicle( bodyGenerator:(wheelCount: Int, wheelType: WheelSet, wheelBase: Float) -> BodyType, transmission: EngineType) -> Vehicle {} }
  59. 59. let factory: VehicleFactory = VehicleFactory() let motorcycleWheelSet: WheelSet = factory.wheelSetGenerator(28, friction: 0.5) let motorcycleBodyGen = factory.generateBodyType(2, wheelType:motorcycleWheelSet, wheelBase: 45) let motorcycle = factory.createVehicle(motorcycleBodyGen, transmission: .Manual) let electricMotorcycle = factory.createVehicle(motorcycleBodyGen, transmission: .Auomatic)
  60. 60. Factories in Swift can be incredibly flexible
  61. 61. Command
  62. 62. A delegate chain that returns a function
  63. 63. protocol Commander { func commandSomething(String) -> (Int) -> Dictionary<String, String> } class ViewController: { let delegate: Commander }
  64. 64. Why is this better than closures?
  65. 65. It’s more explicit
  66. 66. It’s more flexible
  67. 67. Enumeration
  68. 68. Not the type enum!
  69. 69. We have new ways of transforming collections
  70. 70. [1,2,3,4].map { (var number) -> Int in return number * number }
  71. 71. var array = [3, 2, 5, 1, 4] array.sort { $0 < $1 }
  72. 72. let array = [1, 2, 3, 4, 5] let reversedArray = array.reverse() // reversedArray = [5, 4, 3, 2, 1]
  73. 73. And of course, this is useful for more than just math
  74. 74. var vehicles = [suv, motorcycle, electricMotorcycle, car, truck] var manualVehicles = vehicles.filter { (var vehicle: Vehicle) -> Vehicle in return (vehicle.transmission == .Manual) } // manualVehicles = [motorcycle, truck]
  75. 75. Encapsulate better
  76. 76. func meanMedianMode(a: Array<Int>) -> (mean:Int, median:Int, mode:Int) { var mean = findMean(a) var median = findMedian(a) var mode = findMode(a) return (mean, median, mode) }
  77. 77. Tuples with names are incredibly useful
  78. 78. Anti-Patterns
  79. 79. No changes to handling protocols
  80. 80. This is the slide I was hoping to put something magical on
  81. 81. class ViewController: UIViewController, UITableViewDataSource { var tableView: UITableView func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! { var cell : UITableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell") as UITableViewCell if (cell == nil) { cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell") } cell.textLabel.text = "Hello World" return cell } func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int { return 1 } }
  82. 82. Protocols are first class citizens in Swift, just like in Obj-c
  83. 83. Tuples all the way down
  84. 84. Yes, you can put a tuple in a tuple
  85. 85. These are temporary data structures
  86. 86. We have better OO tools available
  87. 87. Operator overloading
  88. 88. Don’t overload default operators
  89. 89. func decode(json: JSON) -> User? { return _JSONObject(json) >>> { d in User.create <^> d["id"] >>> _JSONInt <*> d["name"] >>> _JSONString <*> d["email"] >>> _JSONString } }
  90. 90. Operators make code harder to read
  91. 91. Type is still important
  92. 92. Getting classes from AnyObject are kind of a pain
  93. 93. Still be explicit when you can
  94. 94. var music: [String: String] = ["AC/DC": "Hells Bells", "Red Hot Chili Peppers": "Californication"]
  95. 95. In Summary
  96. 96. Swift gives us new tools
  97. 97. But Objective-C, and its patterns, aren’t going away anytime soon
  98. 98. More Swift! • Today 11:30am Interoperating Swift with Lower Level Code by Stephan Tramer in Terrace • Tomorrow 1:45pm Functional Programming in Swift by Chris Eidhof in Vail
  99. 99. Resources • Swift Programming Guide from Apple • Design Patterns in Dynamic Programming by Peter Norvig • Erica Sadun’s many blog posts on Swift • Functional Programming in Swift, ebook by Objc.io founders (See Chris’ talk tomorrow!) • Instance Methods and Curried Functions in Swift by Ole Begemann
  100. 100. Thanks! @MicheleTitolo

×