Swift was originally released in 2014, and Open Sourced by Apple in late 2015. The Open Source release generated an explosion of community interest and support, resulting in ports to other platforms and significant language changes. Swift version 3, which reflects the results of much of this work, was released in September of 2016, bringing with it some significant refinements to the core language and a new package manager.
Swift is a multi-paradigm language, supporting imperative, functional, and object-oriented programming styles. The language is strongly typed but has extensive support for type inference and substantial tooling available in XCode to identify and in some cases automatically fix common programming errors. Swift uses a memory management strategy called automatic reference counting (ARC), freeing programmers from the tedium of manually managing memory allocation. This combination of strong typing, maximal type inference, automatic reference counting (ARC), and excellent tooling results in an experience that can be described as “the Macintosh of programming languages”.
This talk will present some of the history of the development of Swift with emphasis on how the Open Source release of the language kick-started activity, review the basic syntax of Swift (with comparisons to similar languages that attendees may be more familiar with), and describe what tools are available to help learn the language, including XCode, the Swift REPL available from XCode, and the new Swift Playgrounds for iPad that debuted with Swift 3 and iOS10. After attending this talk, an attendee with no previous Swift experience will understand exactly why they should be excited about this relatively new programming language and be up to date on exactly what they need to do to dive into Swift coding for themselves.
29. variables
let bar = 1
bar += 1
// ^^ compile time error!
A Modest Intro To Swift — ATO 2017 — @genehack 29
30. variables
let bar
// also a compile time error
// You CANNOT have an untyped, uninitialized variable.
// You also can't use an uninitialized variable _at all_.
A Modest Intro To Swift — ATO 2017 — @genehack 30
32. flow control: conditionals
let n = 1
if n > 1 {
print("we got a big N here")
}
A Modest Intro To Swift — ATO 2017 — @genehack 32
33. flow control: loops
let arr = [ 1, 2, 3, 4 ]
var sum = 0
for elem in arr {
sum += elem
}
// sum now is 10
A Modest Intro To Swift — ATO 2017 — @genehack 33
34. flow control: loops
for index in 1 ... 10 {
# do something 10 times
}
A Modest Intro To Swift — ATO 2017 — @genehack 34
35. flow control: loops
var countDown = 5
while countDown > 0 {
print("(countdown)...")
countDown--
}
print("BLASTOFF")
A Modest Intro To Swift — ATO 2017 — @genehack 35
36. ut oh
error: '--' is unavailable: it has been removed in Swift 3
A Modest Intro To Swift — ATO 2017 — @genehack 36
37. flow control: loops
var countDown = 5
while countDown > 0 {
print("(countdown)...")
countDown -= 1
}
print("BLASTOFF")
A Modest Intro To Swift — ATO 2017 — @genehack 37
38. remember that whole
“swift is the macintosh of apple programming languages”
thing?A Modest Intro To Swift — ATO 2017 — @genehack 38
41. flow control: switch statements
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.")
}
A Modest Intro To Swift — ATO 2017 — @genehack 41
42. flow control: switch statements
let sample = ("foo", 2)
switch sample {
case ("foo", 3):
print("Is foo, 3")
case ("bar", _):
print("Is bar")
case (let one, let two):
print("Is (one) and (two)!")
}
A Modest Intro To Swift — ATO 2017 — @genehack 42
44. types
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")
}
A Modest Intro To Swift — ATO 2017 — @genehack 44
45. type 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
A Modest Intro To Swift — ATO 2017 — @genehack 45
46. optional types
// When a variable may not have a value
var bar :Int?
// test
if bar != nil {
// has a value
print(bar!)
}
// unwrapping nil --> runtime exception!
A Modest Intro To Swift — ATO 2017 — @genehack 46
47. if-let
var bar :Int?
if let foo = bar {
// bar had a value &
// foo now has that unwrapped value
print(foo)
}
else {
// bar was nil
}
A Modest Intro To Swift — ATO 2017 — @genehack 47
48. if-var
var bar :Int?
if var foo = bar {
// bar had a value &
// foo now has that unwrapped value
foo += 1
}
else {
// bar was nil
}
A Modest Intro To Swift — ATO 2017 — @genehack 48
50. tuples
let tuple = ("foo", 42)
let first = tuple.0 // "foo"
let labeledTuple = (one: "foo", two: 42)
let second = labeledTuple.two // 42
A Modest Intro To Swift — ATO 2017 — @genehack 50
51. 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"]
A Modest Intro To Swift — ATO 2017 — @genehack 51
52. dictionaries
let stateCaps = [
"Oregon": "Salem",
"North Carolina": "Raleigh",
"Kansas": "Topeka"
]
// stateCaps has type [String:String]
A Modest Intro To Swift — ATO 2017 — @genehack 52
53. dictionary lookups
// subscript access returns optional type. why?
stateCaps["Oregon"] is String? // true
// use if-let or guard statement to unwrap
// or provide default
let location = stateCaps["DC"] ?? "world"
print("hello (location)!")
A Modest Intro To Swift — ATO 2017 — @genehack 53
54. sets
var petSet :Set = [ "cat", "dog",
"fish", "dog"]
petSet.count // returns 3
A Modest Intro To Swift — ATO 2017 — @genehack 54
55. all these variable types
provide a rich set of
methodsA Modest Intro To Swift — ATO 2017 — @genehack 55
57. functions
func obExample () {
print("Hello, ATO!")
}
// call like:
obExample()
A Modest Intro To Swift — ATO 2017 — @genehack 57
58. functions with arguments
func obExample (who :String) {
print("Hello, (who)!")
}
// call like
obExample(who: "ATO 2017")
A Modest Intro To Swift — ATO 2017 — @genehack 58
59. functions with return values
func obExample (who :String) -> String {
return "Hello, (who)!"
}
// call like
let greets = obExample(who: "ATO")
// greets == "Hello, ATO"
A Modest Intro To Swift — ATO 2017 — @genehack 59
60. functions with default argument values
func obExample (who :String = "Swift") -> String {
return "Hello, (who)!"
}
// call like
let greets = obExample(who:"ATO")
// "Hello, ATO!"
let defGreets = obExample()
// "Hello, Swift!"
A Modest Intro To Swift — ATO 2017 — @genehack 60
61. functions with stupid parameter name tricks
func obExample (what :String = "Hello",
who them :String = "Swift") {
print("(what), (them)!")
}
// call like
obExample(what: "bye") // "bye, Swift!"
obExample(what: "bye", who: "Felicia") // "bye, Felicia!"
A Modest Intro To Swift — ATO 2017 — @genehack 61
62. functions with stupid parameter name tricks
func obExample (what :String = "Hello",
_ who :String = "Swift") {
print "(what), (who)!"
}
// call like
obExample(what: "bye") // "bye, Swift!"
obExample(what: "bye", who:"Felicia") // COMPILE ERROR
obExample(what: "bye", "Felicia") // "bye, Felicia!"
A Modest Intro To Swift — ATO 2017 — @genehack 62
63. variadiac functions
func sum (_ nums :Int...) -> Int {
// nums is Array[Int]
return nums.reduce(0, { $0 + $1 })
}
sum(1, 2, 3) // 6
A Modest Intro To Swift — ATO 2017 — @genehack 63
65. 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]
A Modest Intro To Swift — ATO 2017 — @genehack 65
66. 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]
A Modest Intro To Swift — ATO 2017 — @genehack 66
67. closures
let numbers = [2, 1, 56, 32, 120, 13]
// inferred function signature
var sorted = numbers.sorted(by: {n1, n2 in return n2 > n1})
// sorted = [1, 2, 13, 32, 56, 120]
A Modest Intro To Swift — ATO 2017 — @genehack 67
68. closures
let numbers = [2, 1, 56, 32, 120, 13]
// inferred function signature
// *and* positionally named parameters
var sorted = numbers.sorted(by: {return $0 > $1})
// sorted = [1, 2, 13, 32, 56, 120]
A Modest Intro To Swift — ATO 2017 — @genehack 68
69. 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]
A Modest Intro To Swift — ATO 2017 — @genehack 69
70. closures
// these do the exact same thing
var sorted = numbers.sorted(by: {
(n1 :Int, n2 :Int) -> Bool in return n2 > n1
})
var sorted = numbers.sorted { $0 > $1 }
A Modest Intro To Swift — ATO 2017 — @genehack 70
73. properties in classes
class Dog {
var name :String
let noise = "WOOF!"
}
A Modest Intro To Swift — ATO 2017 — @genehack 73
74. properties in classes
class Dog {
var name :String
let noise = "WOOF!"
}
// Class ‘Dog’ has no initializers
A Modest Intro To Swift — ATO 2017 — @genehack 74
75. properties in classes
class Dog {
var name :String?
let noise = "WOOF!"
}
A Modest Intro To Swift — ATO 2017 — @genehack 75
76. initializers
class Dog {
var name :String
let noise = "WOOF"
init (name :String) {
self.name = name
}
}
A Modest Intro To Swift — ATO 2017 — @genehack 76
77. deinitializers
class Dog {
var name :String
let noise = "WOOF"
init (name :String) {
self.name = name
}
deinit () {
// clean up stuff here
}
}
A Modest Intro To Swift — ATO 2017 — @genehack 77
78. methods
class Dog {
var name :String
let noise = "WOOF"
init (name :String) {
self.name = name
}
func speak () -> String {
return self.noise
}
}
A Modest Intro To Swift — ATO 2017 — @genehack 78
79. 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
A Modest Intro To Swift — ATO 2017 — @genehack 79
80. computed properties
class Square {
var side :Float
init (side :Float) { self.side = side }
var perimeter :Float {
get {
return 4 * self.side
}
set {
self.side = newValue / 4
}
}
}
A Modest Intro To Swift — ATO 2017 — @genehack 80
81. computed properties
class Square {
var side :Float
init (side :Float) { self.side = side }
var perimeter :Float {
get {
return 4 * self.side
}
set (perimeter) {
self.side = perimeter / 4
}
}
}
A Modest Intro To Swift — ATO 2017 — @genehack 81
84. inheritance
class Animal {
let name :String
init (name :String) {
self.name = name
}
}
class Dog :Animal {
override init (name: String) {
super.init(name: name)
}
}
A Modest Intro To Swift — ATO 2017 — @genehack 84
86. structs
struct Animal {
var name :String
var noise :String
init (name :String, makes :String) {
self.name = name
noise = makes
}
func speak () -> String {
return noise
}
}
A Modest Intro To Swift — ATO 2017 — @genehack 86
87. enumerations
enum OpenSourceConfs {
case AllThingsOpen
case OSCON
}
var conf = OpenSourceConfs.AllThingsOpen
// conf is type OpenSourceConfs
A Modest Intro To Swift — ATO 2017 — @genehack 87
88. enumerations
enum OpenSourceConfs :Int {
case AllThingsOpen = 1
case OSCON
}
var conf = OpenSourceConfs.OSCON
// conf is type OpenSourceConfs
conf.rawValue // 2
A Modest Intro To Swift — ATO 2017 — @genehack 88
89. functions in enumerations
enum OpenSourceConfs {
case AllThingsOpen
case OSCON
func describe() -> String {
switch self {
case .AllThingsOpen:
return "Hello Raleigh!"
case .OSCON:
return "Hello Portland!"
}
}
}
var conf = OpenSourceConfs.AllThingsOpen
conf.describe()
A Modest Intro To Swift — ATO 2017 — @genehack 89
90. functions in enumerations
enum OpenSourceConfs {
case AllThingsOpen
case OSCON(String)
func describe() -> String {
switch self {
case .AllThingsOpen:
return "Hello Raleigh!"
case .OSCON (let location):
return "Hello (location)!"
}
}
}
var conf = OpenSourceConfs.OSCON("Portland")
conf.describe()
A Modest Intro To Swift — ATO 2017 — @genehack 90
91. functions in enumerations
enum OpenSourceConfs {
case AllThingsOpen
case OSCON(String)
func describe() -> String {
switch self {
case .AllThingsOpen:
return "Hello Raleigh!"
case .OSCON (let location):
return "Hello (location)!"
}
}
}
var oscon2017 = OpenSourceConfs.OSCON("Austin")
var oscon2018 = OpenSourceConfs.OSCON("Portland")
A Modest Intro To Swift — ATO 2017 — @genehack 91
93. protocols
protocol Talker {
var noise :String { get }
func talk () -> String
}
A Modest Intro To Swift — ATO 2017 — @genehack 93
94. 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 = ""
}
}
A Modest Intro To Swift — ATO 2017 — @genehack 94
95. protocols are types
protocol Talker { ... }
class Dog :Talker { ... }
class Fish { ... }
var sammy :Talker
sammy = Dog(noise: "WOOF!")
sammy = Fish() // compile error
A Modest Intro To Swift — ATO 2017 — @genehack 95
99. exceptions
enum TalkErrors :Error {
case TooShort
case TooLong
case TooBoring
}
func giveATalk (talk :String) throws -> String {
if talk == "boring" {
throw TalkErrors.TooBoring
}
return "talk!"
}
A Modest Intro To Swift — ATO 2017 — @genehack 99
100. catching exceptions
do {
let thisTalk = try giveATalk(talk: "boring")
print(thisTalk)
}
catch {
print(error)
}
A Modest Intro To Swift — ATO 2017 — @genehack 100
101. catching 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)
}
A Modest Intro To Swift — ATO 2017 — @genehack 101
102. not catching exceptions
// silently discards error
let thisTalk = try? giveATalk(talk:"fine")
// thisTalk is String?
A Modest Intro To Swift — ATO 2017 — @genehack 102
103. defer
func needsMuchSetupAndTearDown () {
// do the setup here, open files, etc.
defer {
// and do the cleanup here,
// right next to set up
}
// other code here.
}
A Modest Intro To Swift — ATO 2017 — @genehack 103