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.

A Modest Introduction To Swift

327 views

Published on

As presented at The Perl Conference 2017 on 19 Jun 2017

Published in: Software
  • Be the first to comment

A Modest Introduction To Swift

  1. 1. A Modest Introduction To Swift The Perl Conference 2017 19 Jun 2017 John SJ Anderson @genehack
  2. 2. @genehack › Intro to Swift › TPC 2017 Sorry!
  3. 3. @genehack › Intro to Swift › TPC 2017 Hi I'm John aka @genehack • VP Tech, Infinity Interactive • Perl tribe • Polyglot coder • Just this guy, you know?
  4. 4. Polyglotism
  5. 5. @genehack › Intro to Swift › TPC 2017 Swift?
  6. 6. @genehack › Intro to Swift › TPC 2017 Introduced in 2014
  7. 7. @genehack › Intro to Swift › TPC 2017 Went Open Source at version 2.2
  8. 8. @genehack › Intro to Swift › TPC 2017 Version 3.1 just released (in March)
  9. 9. @genehack › Intro to Swift › TPC 2017 Version 4 coming Real Soon Now
  10. 10. @genehack › Intro to Swift › TPC 2017 Originally MacOS only
  11. 11. @genehack › Intro to Swift › TPC 2017 Now on Linux too.
  12. 12. @genehack › Intro to Swift › TPC 2017 Android in the works!
  13. 13. @genehack › Intro to Swift › TPC 2017 Android in the works!DONE!!
  14. 14. @genehack › Intro to Swift › TPC 2017 Windows too?
  15. 15. https://swiftforwindows.codeplex.com/
  16. 16. @genehack › Intro to Swift › TPC 2017 Originally targeted MacOS, iOS, watchOS, and tvOS
  17. 17. @genehack › Intro to Swift › TPC 2017 With expanded platform support, offers potential "single-language stack" advantages a la Node
  18. 18. So what's it like, man?
  19. 19. First, a brief digression…
  20. 20. @genehack › Intro to Swift › TPC 2017 How many MacOS / iOS users do we have here?
  21. 21. @genehack › Intro to Swift › TPC 2017 How many MacOS / iOS developers do we have?
  22. 22. @genehack › Intro to Swift › TPC 2017 The dirty little secret of developing for Apple
  23. 23. @genehack › Intro to Swift › TPC 2017 From In The Beginning Was The Command Line by Neal Stephenson
  24. 24. @genehack › Intro to Swift › TPC 2017 Weird Pascal-based naming and calling conventions
  25. 25. @genehack › Intro to Swift › TPC 2017 HANDLES?!?
  26. 26. @genehack › Intro to Swift › TPC 2017 ObjectiveC's "syntax"
  27. 27. Swift is the Mac of Apple programming languages
  28. 28. Swift Syntax
  29. 29. @genehack › Intro to Swift › TPC 2017 Comments // this is a comment
  30. 30. @genehack › Intro to Swift › TPC 2017 Comments /* this is a multi-line comment */
  31. 31. @genehack › Intro to Swift › TPC 2017 Comments /* this is a /* _nested_ multi-line comment, */ which is cool! */
  32. 32. @genehack › Intro to Swift › TPC 2017 Comments /// doc comment
  33. 33. @genehack › Intro to Swift › TPC 2017 Variables var foo = 1 var bar: Int var baz = "whee!"
  34. 34. @genehack › Intro to Swift › TPC 2017 Variables var foo = 1 var bar: Int var baz = "whee!"
  35. 35. @genehack › Intro to Swift › TPC 2017 Variables var foo = 1 var bar: Int var baz = "whee!"
  36. 36. @genehack › Intro to Swift › TPC 2017 Variables var foo = 1 var bar: Int var baz = "whee!"
  37. 37. @genehack › Intro to Swift › TPC 2017 Variables let bar = 1 bar += 1 // ^^ compile time error!
  38. 38. @genehack › Intro to Swift › TPC 2017 Variables let bar = 1 bar += 1 // ^^ compile time error!
  39. 39. @genehack › Intro to Swift › TPC 2017 Variables let bar // also a compile time error /* You canNOT have an uninitialized and untyped variable. You also can't use an uninitialized variable _at all_ */
  40. 40. @genehack › Intro to Swift › TPC 2017 Variables let bar // also a compile time error /* You canNOT have an uninitialized and untyped variable. You also can't use an uninitialized variable _at all_ */
  41. 41. How friggin' awesome is that?
  42. 42. @genehack › Intro to Swift › TPC 2017 Operators
  43. 43. @genehack › Intro to Swift › TPC 2017 Flow Control let n = 1 if n > 1 { print("we got a big N here") }
  44. 44. @genehack › Intro to Swift › TPC 2017 Flow Control let n = 1 if n > 1 { print("we got a big N here") }
  45. 45. @genehack › Intro to Swift › TPC 2017 Flow Control let n = 1 if n > 1 { print("we got a big N here") }
  46. 46. @genehack › Intro to Swift › TPC 2017 Flow Control let arr = [ 1, 2, 3, 4] var sum = 0 for elem in arr { sum += elem } // sum now is 10
  47. 47. @genehack › Intro to Swift › TPC 2017 Flow Control let arr = [ 1, 2, 3, 4] var sum = 0 for elem in arr { sum += elem } // sum now is 10
  48. 48. @genehack › Intro to Swift › TPC 2017 Flow Control let arr = [ 1, 2, 3, 4] var sum = 0 for elem in arr { sum += elem } // sum now is 10
  49. 49. @genehack › Intro to Swift › TPC 2017 Flow Control let arr = [ 1, 2, 3, 4] var sum = 0 for elem in arr { sum += elem } // sum now is 10
  50. 50. @genehack › Intro to Swift › TPC 2017 Flow Control for index in 1 ... 10 { # do something 10 times }
  51. 51. @genehack › Intro to Swift › TPC 2017 Flow Control for index in 1 ... 10 { # do something 10 times }
  52. 52. @genehack › Intro to Swift › TPC 2017 Flow Control for index in 1 ..< 10 { # do something 9 times }
  53. 53. @genehack › Intro to Swift › TPC 2017 Flow Control for index in 1 ..< 10 { # do something 9 times }
  54. 54. @genehack › Intro to Swift › TPC 2017 Flow Control var countDown = 5 while countDown > 0 { countDown-- }
  55. 55. @genehack › Intro to Swift › TPC 2017 Flow Control var countDown = 5 while countDown > 0 { countDown-- }
  56. 56. @genehack › Intro to Swift › TPC 2017 Flow Control var countDown = 5 while countDown > 0 { countDown -= 1 }
  57. 57. @genehack › Intro to Swift › TPC 2017 Flow Control var countDown = 5 while countDown > 0 { countDown -= 1 }
  58. 58. @genehack › Intro to Swift › TPC 2017 Flow Control var countUp = 0 repeat { countUp++ } while countUp < 5
  59. 59. @genehack › Intro to Swift › TPC 2017 Flow Control var countUp = 0 repeat { countUp++ } while countUp < 5
  60. 60. @genehack › Intro to Swift › TPC 2017 Flow Control var countUp = 0 repeat { countUp += 1 } while countUp < 5
  61. 61. @genehack › Intro to Swift › TPC 2017 Flow Control let sample = 2 switch sample { case 0: print("Is 0") case 2: print("Is 2") default: // mandatory when cases not exclusive print("Not 0 or 2, is it.") }
  62. 62. @genehack › Intro to Swift › TPC 2017 Flow Control let sample = 2 switch sample { case 0: print("Is 0") case 2: print("Is 2") default: // mandatory when cases not exclusive print("Not 0 or 2, is it.") }
  63. 63. @genehack › Intro to Swift › TPC 2017 Flow Control let sample = 2 switch sample { case 0: print("Is 0") case 2: print("Is 2") default: // mandatory when cases not exclusive print("Not 0 or 2, is it.") }
  64. 64. @genehack › Intro to Swift › TPC 2017 Flow Control let sample = 2 switch sample { case 0: print("Is 0") case 2: print("Is 2") default: // mandatory when cases not exclusive print("Not 0 or 2, is it.") } No fallthru by default!
  65. 65. @genehack › Intro to Swift › TPC 2017 Flow Control let sample = 2 switch sample { case 0: print("Is 0") case 2: print("Is 2") default: // mandatory when cases not exclusive print("Not 0 or 2, is it.") }
  66. 66. @genehack › Intro to Swift › TPC 2017 Flow Control let sample = "foo" switch sample { case "foo": print("Is foo") case "bar": print("Is bar") default: // mandatory when cases not exclusive print("Not foo or bar, is it.") }
  67. 67. @genehack › Intro to Swift › TPC 2017 Flow Control let sample = "foo" switch sample { case "foo": print("Is foo") case "bar": print("Is bar") default: // mandatory when cases not exclusive print("Not foo or bar, is it.") }
  68. 68. @genehack › Intro to Swift › TPC 2017 Flow Control let sample = ("foo", 2) switch sample { case ("foo", 2): print("Is foo, 2") case ("bar", _): print("Is bar") default: // mandatory when cases not exclusive print(" ¯_(ツ)_/¯ ") }
  69. 69. @genehack › Intro to Swift › TPC 2017 Flow Control let sample = ("foo", 2) switch sample { case ("foo", 2): print("Is foo, 2") case ("bar", _): print("Is bar") default: // mandatory when cases not exclusive print(" ¯_(ツ)_/¯ ") }
  70. 70. @genehack › Intro to Swift › TPC 2017 Flow Control let sample = ("foo", 2) switch sample { case ("foo", 2): print("Is foo, 2") case ("bar", _): print("Is bar") default: // mandatory when cases not exclusive print(" ¯_(ツ)_/¯ ") }
  71. 71. @genehack › Intro to Swift › TPC 2017 Flow Control let sample = ("foo", 2) switch sample { case ("foo", 2): print("Is foo, 2") case ("bar", _): print("Is bar") default: // mandatory when cases not exclusive print(" ¯_(ツ)_/¯ ") }
  72. 72. @genehack › Intro to Swift › TPC 2017 Flow Control let sample = ("foo", 2) switch sample { case ("foo", 3): print("Is foo, 3") case (let one, let two): print("Is (one) and (two)") }
  73. 73. @genehack › Intro to Swift › TPC 2017 Flow Control let sample = ("foo", 2) switch sample { case ("foo", 3): print("Is foo, 3") case (let one, let two): print("Is (one) and (two)") }
  74. 74. @genehack › Intro to Swift › TPC 2017 Strings var myString = "this is a string" if myString.isEmpty { // do something } myString += "and this is a longer string"
  75. 75. @genehack › Intro to Swift › TPC 2017 Strings var myString = "this is a string" if myString.isEmpty { // do something } myString += "and this is a longer string"
  76. 76. @genehack › Intro to Swift › TPC 2017 Strings var myString = "this is a string" if myString.isEmpty { // do something } myString += "and this is a longer string"
  77. 77. Swift is very strongly typed.
  78. 78. @genehack › Intro to Swift › TPC 2017 Typing var foo = 1 // foo is an Int var bar: Int // bar is an uninit'd Int var baz = Int() if baz is Int { print("Nice Int you got there") }
  79. 79. @genehack › Intro to Swift › TPC 2017 Typing var foo = 1 // foo is an Int var bar: Int // bar is an uninit'd Int var baz = Int() if baz is Int { print("Nice Int you got there") }
  80. 80. @genehack › Intro to Swift › TPC 2017 Typing var foo = 1 // foo is an Int var bar: Int // bar is an uninit'd Int var baz = Int() if baz is Int { print("Nice Int you got there") }
  81. 81. @genehack › Intro to Swift › TPC 2017 Typing var foo = 1 // foo is an Int var bar: Int // bar is an uninit'd Int var baz = Int() if baz is Int { print("Nice Int you got there") }
  82. 82. @genehack › Intro to Swift › TPC 2017 Typing var foo = 1 // foo is an Int var bar: Int // bar is an uninit'd Int var baz = Int() if baz is Int { print("Nice Int you got there") }
  83. 83. @genehack › Intro to Swift › TPC 2017 Casts var foo = 1 // foo is an Int var bar = String(foo) // "1" var maybeBaz = stringishThing as? String // maybeBaz is an optionally typed String var forceBaz = stringishThing as! String
  84. 84. @genehack › Intro to Swift › TPC 2017 Casts var foo = 1 // foo is an Int var bar = String(foo) // "1" var maybeBaz = stringishThing as? String // maybeBaz is an optionally typed String var forceBaz = stringishThing as! String
  85. 85. @genehack › Intro to Swift › TPC 2017 Casts var foo = 1 // foo is an Int var bar = String(foo) // "1" var maybeBaz = stringishThing as? String // maybeBaz is an optionally typed String var forceBaz = stringishThing as! String
  86. 86. @genehack › Intro to Swift › TPC 2017 Casts var foo = 1 // foo is an Int var bar = String(foo) // "1" var maybeBaz = stringishThing as? String // maybeBaz is an optionally typed String var forceBaz = stringishThing as! String
  87. 87. @genehack › Intro to Swift › TPC 2017 Optional Types // When a variable may not have a value var bar: Int? // test if bar != nil { // has a value }
  88. 88. @genehack › Intro to Swift › TPC 2017 Optional Types // When a variable may not have a value var bar: Int? // test if bar != nil { // has a value }
  89. 89. @genehack › Intro to Swift › TPC 2017 Optional Types // When a variable may not have a value var bar: Int? // test if bar != nil { // has a value }
  90. 90. @genehack › Intro to Swift › TPC 2017 Optional Types // unwrap the value to use if bar != nil { bar! += 2 } // unwrapping nil --> runtime exception!
  91. 91. @genehack › Intro to Swift › TPC 2017 Optional Types // unwrap the value to use if bar != nil { bar! += 2 } // unwrapping nil --> runtime exception!
  92. 92. @genehack › Intro to Swift › TPC 2017 Optional Types // unwrap the value to use if bar != nil { bar! += 2 } // unwrapping nil --> runtime exception!
  93. 93. @genehack › Intro to Swift › TPC 2017 if-let var bar: Int? if let foo = bar { // bar had a value & // foo now has that unwrapped value } else { // bar was nil }
  94. 94. @genehack › Intro to Swift › TPC 2017 if-let var bar: Int? if let foo = bar { // bar had a value & // foo now has that unwrapped value } else { // bar was nil }
  95. 95. @genehack › Intro to Swift › TPC 2017 if-let var bar: Int? if let foo = bar { // bar had a value & // foo now has that unwrapped value } else { // bar was nil }
  96. 96. @genehack › Intro to Swift › TPC 2017 if-var var bar: Int? if var foo = bar { // bar had a value & // foo now has that unwrapped value & // foo is mutable foo += 1 } else { // bar was nil }
  97. 97. @genehack › Intro to Swift › TPC 2017 if-var var bar: Int? if var foo = bar { // bar had a value & // foo now has that unwrapped value & // foo is mutable foo += 1 } else { // bar was nil }
  98. 98. @genehack › Intro to Swift › TPC 2017 if-var var bar: Int? if var foo = bar { // bar had a value & // foo now has that unwrapped value & // foo is mutable foo += 1 } else { // bar was nil }
  99. 99. Types of Values
  100. 100. @genehack › Intro to Swift › TPC 2017 Tuples let tuple = ("foo", 42) let first = tuple.0 // "foo" let labeledTuple = (one: "foo", two: 42) let second = labeledTuple.two // 42
  101. 101. @genehack › Intro to Swift › TPC 2017 Tuples let tuple = ("foo", 42) let first = tuple.0 // "foo" let labeledTuple = (one: "foo", two: 42) let second = labeledTuple.two // 42
  102. 102. @genehack › Intro to Swift › TPC 2017 Tuples let tuple = ("foo", 42) let first = tuple.0 // "foo" let labeledTuple = (one: "foo", two: 42) let second = labeledTuple.two // 42
  103. 103. @genehack › Intro to Swift › TPC 2017 Tuples let tuple = ("foo", 42) let first = tuple.0 // "foo" let labeledTuple = (one: "foo", two: 42) let second = labeledTuple.two // 42
  104. 104. @genehack › Intro to Swift › TPC 2017 Tuples let tuple = ("foo", 42) let first = tuple.0 // "foo" let labeledTuple = (one: "foo", two: 42) let second = labeledTuple.two // 42
  105. 105. @genehack › Intro to Swift › TPC 2017 Arrays let nums = [1, 2, 3] var strs : [String] // _can_ mix & match let mixed = [1, "foo"] // but you probably shouldn't // in Swift 3+ this is a compile // error unless specifically // type-annotated let mixed: [Any] = [1, "foo"]
  106. 106. @genehack › Intro to Swift › TPC 2017 Arrays let nums = [1, 2, 3] var strs : [String] // _can_ mix & match let mixed = [1, "foo"] // but you probably shouldn't // in Swift 3+ this is a compile // error unless specifically // type-annotated let mixed: [Any] = [1, "foo"]
  107. 107. @genehack › Intro to Swift › TPC 2017 Arrays let nums = [1, 2, 3] var strs : [String] // _can_ mix & match let mixed = [1, "foo"] // but you probably shouldn't // in Swift 3+ this is a compile // error unless specifically // type-annotated let mixed: [Any] = [1, "foo"]
  108. 108. @genehack › Intro to Swift › TPC 2017 Arrays let nums = [1, 2, 3] var strs : [String] // _can_ mix & match let mixed = [1, "foo"] // but you probably shouldn't // in Swift 3+ this is a compile // error unless specifically // type-annotated let mixed: [Any] = [1, "foo"]
  109. 109. @genehack › Intro to Swift › TPC 2017 Arrays let nums = [1, 2, 3] var strs : [String] // _can_ mix & match let mixed = [1, "foo"] // but you probably shouldn't // in Swift 3+ this is a compile // error unless specifically // type-annotated let mixed: [Any] = [1, "foo"]
  110. 110. @genehack › Intro to Swift › TPC 2017 Dictionary let capitalCityStates = [ "Salem": "Oregon", "Richmond": "Virginia", ] // capitalCityStates has type // [String:String]
  111. 111. @genehack › Intro to Swift › TPC 2017 Dictionary let capitalCityStates = [ "Salem": "Oregon", "Richmond": "Virginia", ] // capitalCityStates has type // [String:String]
  112. 112. @genehack › Intro to Swift › TPC 2017 Dictionary let capitalCityStates = [ "Salem": "Oregon", "Richmond": "Virginia", ] // capitalCityStates has type // [String:String]
  113. 113. @genehack › Intro to Swift › TPC 2017 Dictionary let capitalCityStates = [ "Salem": "Oregon", "Richmond": 2, ] // capitalCityStates must be // annotated with type // [String:Any]
  114. 114. @genehack › Intro to Swift › TPC 2017 Dictionary let capitalCityStates = [ "Salem": "Oregon", "Richmond": 2, ] // capitalCityStates must be // annotated with type // [String:Any]
  115. 115. @genehack › Intro to Swift › TPC 2017 Dictionary let capitalCityStates = [ "Salem": "Oregon", "Richmond": 2, ] // capitalCityStates must be // annotated with type // [String:Any]
  116. 116. @genehack › Intro to Swift › TPC 2017 Dictionary let capitalCityStates: [String:Any] = [ "Salem": "Oregon", "Richmond": 2, ] // capitalCityStates must be // annotated with type [String:Any]
  117. 117. @genehack › Intro to Swift › TPC 2017 Sets var petSet :Set = [ "cat", "dog", "fish", "dog"] petSet.count // returns 3
  118. 118. @genehack › Intro to Swift › TPC 2017 Sets var petSet :Set = [ "cat", "dog", "fish", "dog"] petSet.count // returns 3
  119. 119. @genehack › Intro to Swift › TPC 2017 Sets var petSet :Set = [ "cat", "dog", "fish", "dog"] petSet.count // returns 3
  120. 120. @genehack › Intro to Swift › TPC 2017 Sets var petSet :Set = [ "cat", "dog", "fish", "dog"] petSet.count // returns 3
  121. 121. Functions
  122. 122. @genehack › Intro to Swift › TPC 2017 Functions func obExample () { print("Hello, Perl!") } // call like: obExample()
  123. 123. @genehack › Intro to Swift › TPC 2017 Functions func obExample (who :String) { print("Hello, (who)!") } // call like obExample(who: "The Perl Conference")
  124. 124. @genehack › Intro to Swift › TPC 2017 Functions func obExample (who :String) { print("Hello, (who)!") } // call like obExample(who: "The Perl Conference")
  125. 125. @genehack › Intro to Swift › TPC 2017 Functions func obExample (who :String) { print("Hello, (who)!") } // call like obExample(who: "The Perl Conference")
  126. 126. @genehack › Intro to Swift › TPC 2017 Functions func obExample (who :String) -> String { return "Hello, (who)!" } // call like let greets = obExample("TPC") // greets == "Hello, TPC"
  127. 127. @genehack › Intro to Swift › TPC 2017 Functions func obExample (who :String) -> String { return "Hello, (who)!" } // call like let greets = obExample("TPC") // greets == "Hello, TPC"
  128. 128. @genehack › Intro to Swift › TPC 2017 Functions func obExample (who :String = "Swift") -> String { return "Hello, (who)!" } // call like let greets = obExample(who:"Perl") // "Hello, Perl!" let defGreets = obExample() // "Hello, Swift!"
  129. 129. @genehack › Intro to Swift › TPC 2017 Functions func obExample (who :String = "Swift") -> String { return "Hello, (who)!" } // call like let greets = obExample(who:"Perl") // "Hello, Perl!" let defGreets = obExample() // "Hello, Swift!"
  130. 130. @genehack › Intro to Swift › TPC 2017 Functions func obExample (who :String = "Swift") -> String { return "Hello, (who)!" } // call like let greets = obExample(who:"Perl") // "Hello, Perl!" let defGreets = obExample() // "Hello, Swift!"
  131. 131. @genehack › Intro to Swift › TPC 2017 Functions func obExample (who :String = "Swift") -> String { return "Hello, (who)!" } // call like let greets = obExample(who:"Perl") // "Hello, Perl!" let defGreets = obExample() // "Hello, Swift!"
  132. 132. @genehack › Intro to Swift › TPC 2017 Functions func obExample (what :String = "Hello", who them :String = "Perl") { print("(what), (them)!") } // call like obExample(what: "bye") // "bye, Perl!" obExample(what: "bye", who: "Felicia") // "bye, Felicia!"
  133. 133. @genehack › Intro to Swift › TPC 2017 Functions func obExample (what :String = "Hello", who them :String = "Perl") { print("(what), (them)!") } // call like obExample(what: "bye") // "bye, Perl!" obExample(what: "bye", who: "Felicia") // "bye, Felicia!"
  134. 134. @genehack › Intro to Swift › TPC 2017 Functions func obExample (what :String = "Hello", who them :String = "Perl") { print("(what), (them)!") } // call like obExample(what: "bye") // "bye, Perl!" obExample(what: "bye", who: "Felicia") // "bye, Felicia!"
  135. 135. @genehack › Intro to Swift › TPC 2017 Functions func obExample (what :String = "Hello", who them :String = "Perl") { print("(what), (them)!") } // call like obExample(what: "bye") // "bye, Perl!" obExample(what: "bye", who: "Felicia") // "bye, Felicia!"
  136. 136. @genehack › Intro to Swift › TPC 2017 Functions func obExample (what :String = "Hello", who them :String = "Perl") { print("(what), (them)!") } // call like obExample(what: "bye") // "bye, Perl!" obExample(what: "bye", who: "Felicia") // "bye, Felicia!"
  137. 137. @genehack › Intro to Swift › TPC 2017 Functions func obExample (what :String = "Hello", _ who :String = "Perl") { print "(what), (who)!" } // call like obExample(what: "bye") // "bye, Salem!" obExample(what: "bye", who:"Felicia") // COMPILE ERROR obExample(what: "bye", "Felicia") // "bye, Felicia!"
  138. 138. @genehack › Intro to Swift › TPC 2017 Functions func obExample (what :String = "Hello", _ who :String = "Perl") { print "(what), (who)!" } // call like obExample(what: "bye") // "bye, Salem!" obExample(what: "bye", who:"Felicia") // COMPILE ERROR obExample(what: "bye", "Felicia") // "bye, Felicia!"
  139. 139. @genehack › Intro to Swift › TPC 2017 Functions func obExample (what :String = "Hello", _ who :String = "Perl") { print "(what), (who)!" } // call like obExample(what: "bye") // "bye, Salem!" obExample(what: "bye", who:"Felicia") // COMPILE ERROR obExample(what: "bye", "Felicia") // "bye, Felicia!"
  140. 140. @genehack › Intro to Swift › TPC 2017 Functions func obExample (what :String = "Hello", _ who :String = "Perl") { print "(what), (who)!" } // call like obExample(what: "bye") // "bye, Salem!" obExample(what: "bye", who:"Felicia") // COMPILE ERROR obExample(what: "bye", "Felicia") // "bye, Felicia!"
  141. 141. @genehack › Intro to Swift › TPC 2017 Functions func obExample (what :String = "Hello", _ who :String = "Perl") { print "(what), (who)!" } // call like obExample(what: "bye") // "bye, Salem!" obExample(what: "bye", who:"Felicia") // COMPILE ERROR obExample(what: "bye", "Felicia") // "bye, Felicia!"
  142. 142. @genehack › Intro to Swift › TPC 2017 Functions func obExample (what :String = "Hello", _ who :String = "Perl") { print "(what), (who)!" } // call like obExample(what: "bye") // "bye, Salem!" obExample(what: "bye", who:"Felicia") // COMPILE ERROR obExample(what: "bye", "Felicia") // "bye, Felicia!"
  143. 143. @genehack › Intro to Swift › TPC 2017 Functions func variadiacExample (nums: Int...) { // do something with nums // nums is Array[Int] }
  144. 144. @genehack › Intro to Swift › TPC 2017 Functions func variadiacExample (nums: Int...) { // do something with nums // nums is Array[Int] }
  145. 145. Functions are first-class citizens
  146. 146. @genehack › Intro to Swift › TPC 2017 Closures let numbers = [2,1,56,32,120,13] var sorted = numbers.sorted(by:{ (n1: Int, n2: Int) -> Bool in return n2 > n1 }) // sorted = [1, 2, 13, 32, 56, 120]
  147. 147. @genehack › Intro to Swift › TPC 2017 Closures let numbers = [2,1,56,32,120,13] var sorted = numbers.sorted(by:{ (n1: Int, n2: Int) -> Bool in return n2 > n1 }) // sorted = [1, 2, 13, 32, 56, 120]
  148. 148. @genehack › Intro to Swift › TPC 2017 Closures let numbers = [2,1,56,32,120,13] var sorted = numbers.sorted(by:{ (n1: Int, n2: Int) -> Bool in return n2 > n1 }) // sorted = [1, 2, 13, 32, 56, 120]
  149. 149. @genehack › Intro to Swift › TPC 2017 Closures let numbers = [2,1,56,32,120,13] var sorted = numbers.sorted(by:{ (n1: Int, n2: Int) -> Bool in return n2 > n1 }) // sorted = [1, 2, 13, 32, 56, 120] This is already the func sig for sort!
  150. 150. @genehack › Intro to Swift › TPC 2017 Closures let numbers = [2,1,56,32,120,13] // inferred param & return types var sorted = numbers.sorted(by: {n1, n2 in return n2 > n1}) // sorted = [1, 2, 13, 32, 56, 120]
  151. 151. @genehack › Intro to Swift › TPC 2017 Closures let numbers = [2,1,56,32,120,13] // inferred param & return types var sorted = numbers.sorted(by: {n1, n2 in return n2 > n1}) // sorted = [1, 2, 13, 32, 56, 120]
  152. 152. @genehack › Intro to Swift › TPC 2017 Closures let numbers = [2,1,56,32,120,13] // positionally named parameters var sorted = numbers.sorted(by: {return $0 > $1}) // sorted = [1, 2, 13, 32, 56, 120]
  153. 153. @genehack › Intro to Swift › TPC 2017 Closures let numbers = [2,1,56,32,120,13] // positionally named parameters var sorted = numbers.sorted(by: {return $0 > $1}) // sorted = [1, 2, 13, 32, 56, 120]
  154. 154. @genehack › Intro to Swift › TPC 2017 Closures let numbers = [2,1,56,32,120,13] // when closure is last param, // param name & parens optional var sorted = numbers.sorted { $0 > $1 } // sorted = [1, 2, 13, 32, 56, 120]
  155. 155. @genehack › Intro to Swift › TPC 2017 Closures let numbers = [2,1,56,32,120,13] // when closure is last param, // param name & parens optional var sorted = numbers.sorted { $0 > $1 } // sorted = [1, 2, 13, 32, 56, 120]
  156. 156. OOP is also well supported
  157. 157. @genehack › Intro to Swift › TPC 2017 Classes class Dog { }
  158. 158. @genehack › Intro to Swift › TPC 2017 Properties class Dog { var name: String let noise = "WOOF!" }
  159. 159. @genehack › Intro to Swift › TPC 2017 Properties class Dog { var name: String let noise = "WOOF!" }
  160. 160. @genehack › Intro to Swift › TPC 2017 Properties class Dog { var name: String let noise = "WOOF!" } Class 'Dog' has no initializers
  161. 161. @genehack › Intro to Swift › TPC 2017 Properties class Dog { var name: String? let noise = "WOOF!" }
  162. 162. @genehack › Intro to Swift › TPC 2017 Properties class Dog { var name: String? let noise = "WOOF!" }
  163. 163. @genehack › Intro to Swift › TPC 2017 Initializers class Dog { var name: String let noise = "WOOF" init (name: String) { self.name = name } }
  164. 164. @genehack › Intro to Swift › TPC 2017 Initializers class Dog { var name: String let noise = "WOOF" init (name: String) { self.name = name } }
  165. 165. @genehack › Intro to Swift › TPC 2017 Initializers class Dog { var name: String let noise = "WOOF" init (name: String) { self.name = name } }
  166. 166. @genehack › Intro to Swift › TPC 2017 Deinitializers class Dog { var name: String let noise = "WOOF" init (name: String) { self.name = name } deinit () { // do any cleanup here } }
  167. 167. @genehack › Intro to Swift › TPC 2017 Deinitializers class Dog { var name: String let noise = "WOOF" init (name: String) { self.name = name } deinit () { // do any cleanup here } }
  168. 168. @genehack › Intro to Swift › TPC 2017 Methods class Dog { var name: String let noise = "WOOF" init (name: String) { self.name = name } func speak () -> String { return self.noise } }
  169. 169. @genehack › Intro to Swift › TPC 2017 Methods class Dog { var name: String let noise = "WOOF" init (name: String) { self.name = name } func speak () -> String { return self.noise } }
  170. 170. @genehack › Intro to Swift › TPC 2017 Using Objects let sammy = Dog(name: "Sammy"); // sammy is Dog print(sammy.name) // prints "Sammyn" print(sammy.speak()) // prints "WOOF!n" sammy.name = "Buster" // works b/c prop is var
  171. 171. @genehack › Intro to Swift › TPC 2017 Using Objects let sammy = Dog(name: "Sammy"); // sammy is Dog print(sammy.name) // prints "Sammyn" print(sammy.speak()) // prints "WOOF!n" sammy.name = "Buster" // works b/c prop is var
  172. 172. @genehack › Intro to Swift › TPC 2017 Using Objects let sammy = Dog(name: "Sammy"); // sammy is Dog print(sammy.name) // prints "Sammyn" print(sammy.speak()) // prints "WOOF!n" sammy.name = "Buster" // works b/c prop is var
  173. 173. @genehack › Intro to Swift › TPC 2017 Using Objects let sammy = Dog(name: "Sammy"); // sammy is Dog print(sammy.name) // prints "Sammyn" print(sammy.speak()) // prints "WOOF!n" sammy.name = "Buster" // works b/c prop is var
  174. 174. @genehack › Intro to Swift › TPC 2017 Using Objects let sammy = Dog(name: "Sammy"); // sammy is Dog print(sammy.name) // prints "Sammyn" print(sammy.speak()) // prints "WOOF!n" sammy.name = "Buster" // works b/c prop is var
  175. 175. @genehack › Intro to Swift › TPC 2017 Computed Properties class Dog { var age :Int { get { return currentYear - self.birthYear } set { // this is horrible, don't do this self.birthYear = currentYear - newValue } } }
  176. 176. @genehack › Intro to Swift › TPC 2017 Computed Properties class Dog { var age :Int { get { return currentYear - self.birthYear } set { // this is horrible, don't do this self.birthYear = currentYear - newValue } } }
  177. 177. @genehack › Intro to Swift › TPC 2017 Computed Properties class Dog { var age :Int { get { return currentYear - self.birthYear } set { // this is horrible, don't do this self.birthYear = currentYear - newValue } } }
  178. 178. @genehack › Intro to Swift › TPC 2017 Computed Properties class Dog { var age :Int { get { return currentYear - self.birthYear } set { // this is horrible, don't do this self.birthYear = currentYear - newValue } } }
  179. 179. @genehack › Intro to Swift › TPC 2017 Computed Properties class Dog { var age :Int { get { return currentYear - self.birthYear } set (age) { // this is horrible, don't do this self.birthYear = currentYear - age } } }
  180. 180. @genehack › Intro to Swift › TPC 2017 Computed Properties class Dog { var age :Int { get { return currentYear - self.birthYear } set (age) { // this is horrible, don't do this self.birthYear = currentYear - age } } }
  181. 181. @genehack › Intro to Swift › TPC 2017 Computed Properties class Dog { var age :Int { get { return currentYear - self.birthYear } set { // this is horrible, don't do this self.birthYear = currentYear - age } } }
  182. 182. @genehack › Intro to Swift › TPC 2017 Computed Properties class Dog { var age :Int { willSet { // runs before property value changes } didSet { // runs after property value changes } } }
  183. 183. @genehack › Intro to Swift › TPC 2017 Computed Properties class Dog { var age :Int { willSet { // runs before property value changes } didSet { // runs after property value changes } } }
  184. 184. Inheritance
  185. 185. @genehack › Intro to Swift › TPC 2017 Inheritance class Animal { } class Dog : Animal { }
  186. 186. @genehack › Intro to Swift › TPC 2017 Inheritance class Animal { } class Dog : Animal { }
  187. 187. @genehack › Intro to Swift › TPC 2017 Inheritance class Animal { let name: String init (name: name) { self.name = name } } class Dog : Animal { override init (name: name) { super.init(name: name) } }
  188. 188. @genehack › Intro to Swift › TPC 2017 Inheritance class Animal { let name: String init (name: name) { self.name = name } } class Dog : Animal { override init (name: name) { super.init(name: name) } }
  189. 189. @genehack › Intro to Swift › TPC 2017 Inheritance class Animal { let name: String init (name: name) { self.name = name } } class Dog : Animal { override init (name: name) { super.init(name: name) } }
  190. 190. @genehack › Intro to Swift › TPC 2017 Overrides class Animal { func speak() { ... } } class Dog : Animal { override func speak () { ... } }
  191. 191. @genehack › Intro to Swift › TPC 2017 Overrides class Animal { func speak() { ... } } class Dog : Animal { override func speak () { ... } }
  192. 192. Structs & Enumerations
  193. 193. @genehack › Intro to Swift › TPC 2017 Structs struct Animal { var name: String var noise: String init (name: String, makes: String) { self.name = name noise = makes } func speak () -> String { return noise } }
  194. 194. @genehack › Intro to Swift › TPC 2017 Structs struct Animal { var name: String var noise: String init (name: String, makes: String) { self.name = name noise = makes } func speak () -> String { return noise } }
  195. 195. @genehack › Intro to Swift › TPC 2017 Structs struct Animal { var name: String var noise: String init (name: String, makes: String) { self.name = name noise = makes } func speak () -> String { return noise } }
  196. 196. @genehack › Intro to Swift › TPC 2017 Structs struct Animal { var name: String var noise: String init (name: String, makes: String) { self.name = name noise = makes } func speak () -> String { return noise } }
  197. 197. @genehack › Intro to Swift › TPC 2017 Enumerations enum OpenSourceConfs { case TPC case YAPC } var conf = OpenSourceConfs.TPC // conf is type OpenSourceConfs
  198. 198. @genehack › Intro to Swift › TPC 2017 Enumerations enum OpenSourceConfs { case TPC case YAPC } var conf = OpenSourceConfs.TPC // conf is type OpenSourceConfs
  199. 199. @genehack › Intro to Swift › TPC 2017 Enumerations enum OpenSourceConfs { case TPC case YAPC } var conf = OpenSourceConfs.TPC // conf is type OpenSourceConfs
  200. 200. @genehack › Intro to Swift › TPC 2017 Enumerations enum OpenSourceConfs { case TPC case YAPC } var conf = OpenSourceConfs.TPC // conf is type OpenSourceConfs
  201. 201. @genehack › Intro to Swift › TPC 2017 Enumerations enum OpenSourceConfs :Int { case TPC = 1 case YAPC } var conf = OpenSourceConfs.YAPC // conf is type OpenSourceConfs conf.rawValue // 2
  202. 202. @genehack › Intro to Swift › TPC 2017 Enumerations enum OpenSourceConfs :Int { case TPC = 1 case YAPC } var conf = OpenSourceConfs.YAPC // conf is type OpenSourceConfs conf.rawValue // 2
  203. 203. @genehack › Intro to Swift › TPC 2017 Enumerations enum OpenSourceConfs :Int { case TPC = 1 case YAPC } var conf = OpenSourceConfs.YAPC // conf is type OpenSourceConfs conf.rawValue // 2
  204. 204. @genehack › Intro to Swift › TPC 2017 Enumerations enum OpenSourceConfs :Int { case TPC = 1 case YAPC } var conf = OpenSourceConfs.YAPC // conf is type OpenSourceConfs conf.rawValue // 2
  205. 205. @genehack › Intro to Swift › TPC 2017 Enumerations enum OpenSourceConfs { case TPC case YAPC func describe() -> String { switch self { case .TPC: return "hello virginia!" case .YAPC: return "I thought YAPC was dead" } } } var conf = OpenSourceConfs.TPC conf.describe()
  206. 206. @genehack › Intro to Swift › TPC 2017 Enumerations enum OpenSourceConfs { case TPC case YAPC func describe() -> String { switch self { case .TPC: return "hello virginia!" case .YAPC: return "I thought YAPC was dead" } } } var conf = OpenSourceConfs.TPC conf.describe()
  207. 207. @genehack › Intro to Swift › TPC 2017 Enumerations enum OpenSourceConfs { case TPC case YAPC func describe() -> String { switch self { case .TPC: return "hello virginia!" case .YAPC: return "I thought YAPC was dead" } } } var conf = OpenSourceConfs.TPC conf.describe()
  208. 208. @genehack › Intro to Swift › TPC 2017 Enumerations enum OpenSourceConfs { case TPC case YAPC func describe() -> String { switch self { case .TPC: return "hello virginia!" case .YAPC: return "I thought YAPC was dead" } } } var conf = OpenSourceConfs.TPC conf.describe()
  209. 209. @genehack › Intro to Swift › TPC 2017 Enumerations enum OpenSourceConfs { case TPC(String) case YAPC func describe() -> String { switch self { case .TPC(let location): return "hello (location)!" case .YAPC: return "I thought YAPC was dead" } } } var conf = OpenSourceConfs.TPC("DC") conf.describe()
  210. 210. @genehack › Intro to Swift › TPC 2017 Enumerations enum OpenSourceConfs { case TPC(String) case YAPC func describe() -> String { switch self { case .TPC(let location): return "hello (location)!" case .YAPC: return "I thought YAPC was dead" } } } var conf = OpenSourceConfs.TPC("DC") conf.describe()
  211. 211. @genehack › Intro to Swift › TPC 2017 Enumerations enum OpenSourceConfs { case TPC(String) case YAPC func describe() -> String { switch self { case .TPC(let location): return "hello (location)!" case .YAPC: return "I thought YAPC was dead" } } } var conf = OpenSourceConfs.TPC("DC") conf.describe()
  212. 212. @genehack › Intro to Swift › TPC 2017 Enumerations enum OpenSourceConfs { case TPC(String) case YAPC func describe() -> String { switch self { case .TPC(let location): return "hello (location)!" case .YAPC: return "I thought YAPC was dead" } } } var conf = OpenSourceConfs.TPC("DC") conf.describe()
  213. 213. @genehack › Intro to Swift › TPC 2017 Enumerations enum OpenSourceConfs { case TPC(String) case YAPC func describe() -> String { switch self { case .TPC (let location): return "hello (location)!" case .YAPC(location) return "I thought YAPC was dead" } } } var tpc2017 = OpenSourceConfs.TPC("DC") var tpc2018 = OpenSourceConfs.TPC("Pittsurgh?")
  214. 214. @genehack › Intro to Swift › TPC 2017 Enumerations enum OpenSourceConfs { case TPC(String) case YAPC func describe() -> String { switch self { case .TPC (let location): return "hello (location)!" case .YAPC(location) return "I thought YAPC was dead" } } } var tpc2017 = OpenSourceConfs.TPC("DC") var tpc2018 = OpenSourceConfs.TPC("Pittsurgh?")
  215. 215. @genehack › Intro to Swift › TPC 2017 Protocols protocol Talker { var noise: String { get } func talk () -> String }
  216. 216. @genehack › Intro to Swift › TPC 2017 Protocols protocol Talker { var noise: String { get } func talk () -> String }
  217. 217. @genehack › Intro to Swift › TPC 2017 Protocols protocol Talker { var noise: String { get } func talk () -> String }
  218. 218. @genehack › Intro to Swift › TPC 2017 Protocols protocol Talker { var noise: String { get } func talk () -> String }
  219. 219. @genehack › Intro to Swift › TPC 2017 Protocols protocol Talker { var noise: String { get } func talk () -> String mutating func mute() } class Dog: Talker { var noise: String init (noise: String) { self.noise = noise } func talk () -> String { return noise } func mute () { noise = "" } }
  220. 220. @genehack › Intro to Swift › TPC 2017 Protocols protocol Talker { var noise: String { get } func talk () -> String mutating func mute() } class Dog: Talker { var noise: String init (noise: String) { self.noise = noise } func talk () -> String { return noise } func mute () { noise = "" } }
  221. 221. @genehack › Intro to Swift › TPC 2017 Protocols protocol Talker { var noise: String { get } func talk () -> String mutating func mute() } class Dog: Talker { var noise: String init (noise: String) { self.noise = noise } func talk () -> String { return noise } func mute () { noise = "" } }
  222. 222. @genehack › Intro to Swift › TPC 2017 Protocols protocol Talker { var noise: String { get } func talk () -> String mutating func mute() } class Dog: Talker { var noise: String init (noise: String) { self.noise = noise } func talk () -> String { return noise } func mute () { noise = "" } }
  223. 223. @genehack › Intro to Swift › TPC 2017 Protocols protocol Talker { var noise: String { get } func talk () -> String mutating func mute() } class Dog: Talker { var noise: String init (noise: String) { self.noise = noise } func talk () -> String { return noise } func mute () { noise = "" } }
  224. 224. @genehack › Intro to Swift › TPC 2017 Protocols protocol Talker { var noise: String { get } func talk () -> String mutating func mute() } class Dog: Talker { var noise: String init (noise: String) { self.noise = noise } func talk () -> String { return noise } func mute () { noise = "" } }
  225. 225. @genehack › Intro to Swift › TPC 2017 Protocols protocol Talker { var noise: String { get } func talk () -> String mutating func mute() } class Dog: Talker { var noise: String init (noise: String) { self.noise = noise } func talk () -> String { return noise } func mute () { noise = "" } }
  226. 226. @genehack › Intro to Swift › TPC 2017 Protocols protocol Talker { ... } class Dog: Talker { ... } class Fish { ... } var sammy: Talker sammy = Dog(noise: "WOOF!") sammy = Fish() // compile error
  227. 227. @genehack › Intro to Swift › TPC 2017 Protocols protocol Talker { ... } class Dog: Talker { ... } class Fish { ... } var sammy: Talker sammy = Dog(noise: "WOOF!") sammy = Fish() // compile error
  228. 228. @genehack › Intro to Swift › TPC 2017 Protocols protocol Talker { ... } class Dog: Talker { ... } class Fish { ... } var sammy: Talker sammy = Dog(noise: "WOOF!") sammy = Fish() // compile error
  229. 229. @genehack › Intro to Swift › TPC 2017 Protocols protocol Talker { ... } class Dog: Talker { ... } class Fish { ... } var sammy: Talker sammy = Dog(noise: "WOOF!") sammy = Fish() // compile error
  230. 230. @genehack › Intro to Swift › TPC 2017 Extensions extension Int { func squared () -> Int { return self * self } } let foo = 2 print(foo.squared()) // 4 print(foo.squared().squared()) // 16
  231. 231. @genehack › Intro to Swift › TPC 2017 Extensions extension Int { func squared () -> Int { return self * self } } let foo = 2 print(foo.squared()) // 4 print(foo.squared().squared()) // 16
  232. 232. @genehack › Intro to Swift › TPC 2017 Extensions extension Int { func squared () -> Int { return self * self } } let foo = 2 print(foo.squared()) // 4 print(foo.squared().squared()) // 16
  233. 233. @genehack › Intro to Swift › TPC 2017 Extensions extension Int { func squared () -> Int { return self * self } } let foo = 2 print(foo.squared()) // 4 print(foo.squared().squared()) // 16
  234. 234. Exceptions & Error Handling
  235. 235. @genehack › Intro to Swift › TPC 2017 Exceptions enum TalkErrors: Error { case TooShort case TooLong case TooBoring } func giveATalk (talk: String) throws -> String { if talk == "boring" { throw TalkErrors.TooBoring } return "talk!" }
  236. 236. @genehack › Intro to Swift › TPC 2017 Exceptions enum TalkErrors: Error { case TooShort case TooLong case TooBoring } func giveATalk (talk: String) throws -> String { if talk == "boring" { throw TalkErrors.TooBoring } return "talk!" }
  237. 237. @genehack › Intro to Swift › TPC 2017 Exceptions enum TalkErrors: Error { case TooShort case TooLong case TooBoring } func giveATalk (talk: String) throws -> String { if talk == "boring" { throw TalkErrors.TooBoring } return "talk!" }
  238. 238. @genehack › Intro to Swift › TPC 2017 Exceptions enum TalkErrors: Error { case TooShort case TooLong case TooBoring } func giveATalk (talk: String) throws -> String { if talk == "boring" { throw TalkErrors.TooBoring } return "talk!" }
  239. 239. @genehack › Intro to Swift › TPC 2017 Exceptions do { let thisTalk = try giveATalk(talk: "boring") print(thisTalk) } catch { print(error) }
  240. 240. @genehack › Intro to Swift › TPC 2017 Exceptions do { let thisTalk = try giveATalk(talk: "boring") print(thisTalk) } catch { print(error) }
  241. 241. @genehack › Intro to Swift › TPC 2017 Exceptions do { let thisTalk = try giveATalk(talk: "boring") print(thisTalk) } catch { print(error) }
  242. 242. @genehack › Intro to Swift › TPC 2017 Exceptions do { let thisTalk = try giveATalk(talk: "boring") print(thisTalk) } catch { print(error) }
  243. 243. @genehack › Intro to Swift › TPC 2017 Exceptions do { let thisTalk = try giveATalk(talk: "fine") print(thisTalk) } catch TalkErrors.TooLong { print("shut up already") } catch let talkError as TalkErrors { print("Talk error: (talkError).") } catch { print (error) }
  244. 244. @genehack › Intro to Swift › TPC 2017 Exceptions do { let thisTalk = try giveATalk(talk: "fine") print(thisTalk) } catch TalkErrors.TooLong { print("shut up already") } catch let talkError as TalkErrors { print("Talk error: (talkError).") } catch { print (error) }
  245. 245. @genehack › Intro to Swift › TPC 2017 Exceptions do { let thisTalk = try giveATalk(talk: "fine") print(thisTalk) } catch TalkErrors.TooLong { print("shut up already") } catch let talkError as TalkErrors { print("Talk error: (talkError).") } catch { print (error) }
  246. 246. @genehack › Intro to Swift › TPC 2017 Exceptions do { let thisTalk = try giveATalk(talk: "fine") print(thisTalk) } catch TalkErrors.TooLong { print("shut up already") } catch let talkError as TalkErrors { print("Talk error: (talkError).") } catch { print (error) }
  247. 247. @genehack › Intro to Swift › TPC 2017 Exceptions do { let thisTalk = try giveATalk(talk: "fine") print(thisTalk) } catch TalkErrors.TooLong { print("shut up already") } catch let talkError as TalkErrors { print("Talk error: (talkError).") } catch { print (error) }
  248. 248. @genehack › Intro to Swift › TPC 2017 Exceptions // silently discards error let thisTalk = try? giveATalk(talk:"fine") // thisTalk isa String?
  249. 249. @genehack › Intro to Swift › TPC 2017 Exceptions // silently discards error let thisTalk = try? giveATalk(talk:"fine") // thisTalk isa String?
  250. 250. @genehack › Intro to Swift › TPC 2017 Exceptions // silently discards error let thisTalk = try? giveATalk(talk:"fine") // thisTalk isa String?
  251. 251. @genehack › Intro to Swift › TPC 2017 Defer func needsMuchSetupAndTearDown () { // do the setup here, open files, etc. defer { // and do the cleanup here, // right next to set up } // other code here. }
  252. 252. @genehack › Intro to Swift › TPC 2017 Defer func needsMuchSetupAndTearDown () { // do the setup here, open files, etc. defer { // and do the cleanup here, // right next to set up } // other code here. }
  253. 253. Workspaces
  254. 254. Ill-advised live demo time!
  255. 255. Ill-advised live demo time!
  256. 256. https://developer.apple.com/swift
  257. 257. THANKS!
  258. 258. questions?

×