Slide 1

Slide 1 text

DEVNEXUS Atlanta – February 22, 2018 Swift Patrick Seda - @pxtrick

Slide 2

Slide 2 text

Target Tools

Slide 3

Slide 3 text

Beginner Target Tools @pxtrick

Slide 4

Slide 4 text

Target Tools @pxtrick “Beyond Beginner” This

Slide 5

Slide 5 text

Background

Slide 6

Slide 6 text

Background @pxtrick “The Effects of RR-Interval Data on Heart Rate Variability and Congestive Heart Failure” Then: Now: Mobile and Web Business Apps Atlanta-ish, GA @pxtrick Patrick Seda Increasing the Quality of the Universe

Slide 7

Slide 7 text

Access Control

Slide 8

Slide 8 text

public open internal fileprivate private Access Control @pxtrick

Slide 9

Slide 9 text

file 2 class A class B file 1 module “consumer” Access Control @pxtrick class C

Slide 10

Slide 10 text

file 2 class A class B file 1 module “consumer” // Class with a member variable. class A { private var value } Access Control @pxtrick class C

Slide 11

Slide 11 text

file 2 class A class B file 1 module “consumer” // Class with a member variable. class A { fileprivate var value } Access Control @pxtrick class C

Slide 12

Slide 12 text

class C file 2 class A class B file 1 module “consumer” // Class with a member variable. class A { internal var value } Access Control @pxtrick

Slide 13

Slide 13 text

file 2 class A class B file 1 module “consumer” // Class with a member variable. class A { public var value // Accessible, no override } Access Control @pxtrick class C

Slide 14

Slide 14 text

file 2 class A class B file 1 module “consumer” // Class with a member variable. class A { open var value // Accessible, can override } Access Control @pxtrick class C

Slide 15

Slide 15 text

Most restrictive Least restrictive Access Control @pxtrick

Slide 16

Slide 16 text

-open -public -internal -fileprivate -private Access Control @pxtrick Most restrictive Least restrictive Default!

Slide 17

Slide 17 text

Why is the default level internal? “When you write a simple single-target app, the code in your app is typically self-contained within the app and doesn’t need to be made available outside of the app’s module. The default access level of internal already matches this requirement. Therefore, you don’t need to specify a custom access level.” Because: Less typing for small apps! Access Control @pxtrick

Slide 18

Slide 18 text

-open -public -internal -fileprivate -private What should we do? Access Control @pxtrick Most restrictive Least restrictive

Slide 19

Slide 19 text

Named Model Types

Slide 20

Slide 20 text

enum vs. struct vs. class Named Model Types @pxtrick

Slide 21

Slide 21 text

enum Named Model Types @pxtrick

Slide 22

Slide 22 text

// Modeling a Finite-State Machine. // State of the system. enum AlarmState { case disarmed case armed case alarming } // System-wide events. enum Event { case arm case disarm case tripSensor } Named Model Types @pxtrick

Slide 23

Slide 23 text

var currentState: AlarmState func handleEvent(_ event: Event) { switch event { case .arm: if (currentState == .disarmed) { currentState = .armed } case .disarm: currentState = .disarmed case .tripSensor: if (currentState == .armed) { currentState = .alarming } } } Named Model Types @pxtrick

Slide 24

Slide 24 text

var currentState: AlarmState = .disarmed handleEvent(.arm) // currentState == .armed handleEvent(.tripSensor) // currentState == .alarming handleEvent(.disarm) // currentState == .disarmed handleEvent(.tripSensor) // currentState == .disarmed Named Model Types @pxtrick

Slide 25

Slide 25 text

// Define some Gibson guitar types enum Gibson: String { case lesPaul case es355 case flyingV case sg } Named Model Types @pxtrick

Slide 26

Slide 26 text

// Define some Gibson guitar types enum Gibson: String { case lesPaul case es355 case flyingV case sg } let myGuitar = Gibson.lesPaul print("My guitar is a \(myGuitar.rawValue)") let yourGuitar: Gibson = .flyingV print("Your guitar is a \(yourGuitar.rawValue)") My guitar is a lesPaul Your guitar is a flyingV Named Model Types @pxtrick Ou t p u t :

Slide 27

Slide 27 text

// Define some Gibson guitar types enum Gibson: String { case lesPaul = "Les Paul" case es355 = "ES355" case flyingV = "Flying V" case sg = "SG" } let myGuitar = Gibson.lesPaul print("My guitar is a \(myGuitar.rawValue)") let yourGuitar: Gibson = .flyingV print("Your guitar is a \(yourGuitar.rawValue)") My guitar is a Les Paul Your guitar is a Flying V Named Model Types @pxtrick Ou t p u t :

Slide 28

Slide 28 text

struct & class Named Model Types @pxtrick

Slide 29

Slide 29 text

When should we use struct vs. class? “In all other cases, define a class, and create instances of that class to be managed and passed by reference. In practice, this means that most custom data constructs should be classes, not structures.” Use a struct when: - Encapsulate few, simple data values - Data can be copied (passed by value) - Does not need inheritance Named Model Types @pxtrick

Slide 30

Slide 30 text

Protocols for Design

Slide 31

Slide 31 text

Let’s Design A game! Protocols for Design @pxtrick

Slide 32

Slide 32 text

Protocols for Design @pxtrick

Slide 33

Slide 33 text

Design before coding! Protocols for Design @pxtrick

Slide 34

Slide 34 text

Musician Musical Instrument Stringed Instrument Cello Viola Violin Bass makeSound() numStrings perform() Protocols for Design @pxtrick

Slide 35

Slide 35 text

protocol MusicalInstrument { func makeSound() } protocol StringedInstrument: MusicalInstrument { var numStrings: Int { get } } extension StringedInstrument { func makeSound() { print("Plink") } } class Cello: StringedInstrument { var numStrings: Int = 4 func makeSound() { print(”Hurrm Hummm") } } class Bass: StringedInstrument { var numStrings: Int = 4 func makeSound() { print("A Boom Boom Boom") } } Protocols for Design @pxtrick

Slide 36

Slide 36 text

class Musician { var instrument: MusicalInstrument? func perform() { instrument?.makeSound() } } let cello: MusicalInstrument = Cello() let bass: MusicalInstrument = Bass() let musician = Musician() musician.instrument = cello musician.perform() musician.instrument = bass musician.perform() Hurrm Hummm A Boom Boom Boom Protocols for Design @pxtrick Ou t p u t :

Slide 37

Slide 37 text

CLosures

Slide 38

Slide 38 text

callbacks Closures @pxtrick

Slide 39

Slide 39 text

// Do some stuff and then fire a callback. func doSomething( /* ??? */ ) { // ... onDone() } Closures - C a l lb a cks @pxtrick

Slide 40

Slide 40 text

// Increment an integer and fire a callback. func increment(_ value: inout Int, onDone onDone: () -> Void) { value += 1 onDone() } // Define our callback. var attentionCb = { print("Attention! value = \(value)") } // Test it out. var value = 3; increment(&value, onDone: attentionCb) increment(&value, onDone: attentionCb) Attention! value = 4 Attention! value = 5 @pxtrick Ou t p u t : Closures - C a l lb a cks

Slide 41

Slide 41 text

time of execution Closures @pxtrick

Slide 42

Slide 42 text

var queue = DispatchQueue.global() // Run using a thread pool. func execute(_ work: () -> Void) { queue.sync { work() } } // Create some work. var workItemOne = { print("Work item 1") } var workItemTwo = { print("Work item 2") } execute(workItemOne) execute(workItemTwo) Work item 1 Work item 2 @pxtrick Ou t p u t : Closures - T i m e of E xecu t ion

Slide 43

Slide 43 text

var queue = DispatchQueue.global() // Run using a thread pool. func execute(_ work: () -> Void) { queue.async { work() } } // Create some work. var workItemOne = { print("Work item 1") } var workItemTwo = { print("Work item 2") } execute(workItemOne) execute(workItemTwo) error: closure use of non-escaping parameter 'work' may allow it to escape @pxtrick Ou t p u t : Closures - T i m e of E xecu t ion

Slide 44

Slide 44 text

var queue = DispatchQueue.global() // Run using a thread pool. func execute(_ work: @escaping () -> Void) { queue.async { work() } } // Create some work. var workItemOne = { print("Work item 1") } var workItemTwo = { print("Work item 2") } execute(workItemOne) execute(workItemTwo) Work item 2 Work item 1 @pxtrick Ou t p u t : Closures - T i m e of E xecu t ion

Slide 45

Slide 45 text

Closure Expressions Closures @pxtrick

Slide 46

Slide 46 text

let cities = ["Geneva", "Traer", "Mint Hill", "Senoia"] // Define a normal comparison function. func backwards(_ s1: String, _ s2: String) { return s1 > s2 } // Execute the array sort. var reversedOrder = cities.sorted(by: backwards) print("\(reversedOrder)") ["Traer", "Senoia", "Mint Hill", "Geneva"] @pxtrick Ou t p u t : Closures - C l os u r e E xp r e s s io n s

Slide 47

Slide 47 text

let cities = ["Geneva", "Traer", "Mint Hill", "Senoia"] // Closure Expression syntax. var reversedOrder = cities.sorted(by: { (s1: String, s2: String) -> Bool in return s1 > s2 }) ["Traer", "Senoia", "Mint Hill", "Geneva"] @pxtrick Ou t p u t : Closures - C l os u r e E xp r e s s io n s

Slide 48

Slide 48 text

let cities = ["Geneva", "Traer", "Mint Hill", "Senoia"] // Inferring type from context. var reversedOrder = cities.sorted(by: { s1, s2 in return s1 > s2 }) ["Traer", "Senoia", "Mint Hill", "Geneva"] @pxtrick Ou t p u t : Closures - C l os u r e E xp r e s s io n s

Slide 49

Slide 49 text

let cities = ["Geneva", "Traer", "Mint Hill", "Senoia"] // Implicit returns from single-expression closures. var reversedOrder = cities.sorted(by: { s1, s2 in s1 > s2 }) ["Traer", "Senoia", "Mint Hill", "Geneva"] @pxtrick Ou t p u t : Closures - C l os u r e E xp r e s s io n s

Slide 50

Slide 50 text

let cities = ["Geneva", "Traer", "Mint Hill", "Senoia"] // Shorthand argument names. var reversedOrder = cities.sorted(by: { $0 > $1 }) ["Traer", "Senoia", "Mint Hill", "Geneva"] @pxtrick Ou t p u t : Closures - C l os u r e E xp r e s s io n s

Slide 51

Slide 51 text

let cities = ["Geneva", "Traer", "Mint Hill", "Senoia"] // Operator methods. var reversedOrder = cities.sorted(by: >) ["Traer", "Senoia", "Mint Hill", "Geneva"] @pxtrick Ou t p u t : Closures - C l os u r e E xp r e s s io n s

Slide 52

Slide 52 text

let cities = ["Geneva", "Traer", "Mint Hill", "Senoia"] // Operator methods. var reversedOrder = cities.sorted(by: >) ["Traer", "Senoia", "Mint Hill", "Geneva"] @pxtrick Ou t p u t : // Closure Expression syntax. var reversedOrder = cities.sorted(by: { (s1: String, s2: String) -> Bool in return s1 > s2 }) Previously: Closures - C l os u r e E xp r e s s io n s

Slide 53

Slide 53 text

Memory Leaks

Slide 54

Slide 54 text

ARC – Automatic Reference Counting Memory Leaks @pxtrick

Slide 55

Slide 55 text

// A rockin’ band. class RockBand { var keys: Keyboard? deinit { print("[RockBand] - deinit()") } } // A tasty delight. class Keyboard { var band: RockBand? deinit { print("[Keyboard] - deinit()") } } Memory Leaks @pxtrick

Slide 56

Slide 56 text

// Create our band. var band: RockBand? = RockBand() // Create our keys. var keys: Keyboard? = Keyboard() // Establish a beautiful friendship. band?.keys = keys keys?.band = band // Clean up. print("Removing band ...") band = nil print("Removing keys ...") keys = nil Removing band ... Removing keys ... Memory Leaks @pxtrick Ou t p u t :

Slide 57

Slide 57 text

var band strong strong strong var keys strong keys: band band: keys Memory Leaks @pxtrick

Slide 58

Slide 58 text

var band strong strong var keys strong keys: band band: keys Memory Leaks @pxtrick

Slide 59

Slide 59 text

var band strong strong var keys keys: band band: keys Memory Leaks @pxtrick

Slide 60

Slide 60 text

// A rockin’ band. class RockBand { var keys: Keyboard? deinit { print("[RockBand] - deinit()") } } // A tasty delight. class Keyboard { weak var band: RockBand? deinit { print("[Keyboard] - deinit()") } } Memory Leaks @pxtrick

Slide 61

Slide 61 text

var band strong strong var keys strong keys: band band: keys Memory Leaks @pxtrick weak

Slide 62

Slide 62 text

var band strong var keys strong keys: band band: keys Memory Leaks @pxtrick weak

Slide 63

Slide 63 text

var band var keys strong keys: band band: keys Memory Leaks @pxtrick

Slide 64

Slide 64 text

var band var keys keys: band band: keys Memory Leaks @pxtrick

Slide 65

Slide 65 text

var band var keys keys: band band: keys Memory Leaks @pxtrick

Slide 66

Slide 66 text

// Create our band. var band: RockBand? = RockBand() // Create our keys. var keys: Keyboard? = Keyboard() // Establish a beautiful friendship. band?.keys = keys keys?.band = band // Clean up. print("Removing band ...") band = nil print("Removing keys ...") keys = nil Removing band ... [RockBand] - deinit() Removing keys ... [Keyboard] - deinit() Memory Leaks @pxtrick Ou t p u t :

Slide 67

Slide 67 text

// A rock show. class Concert { var fans: Audience? deinit { print("[Concert] - deinit()") } } // The fans. class Audience { var concert: Concert init(_ concert: Concert) { self.concert = concert } deinit { print("[Audience] - deinit()") } } Memory Leaks @pxtrick

Slide 68

Slide 68 text

// Create our rock show. var rockShow: Concert? = Concert() // Create and assign our fans. rockShow?.fans = Audience(rockShow!) // Clean up. print("Removing rockShow...") rockShow = nil Removing rockShow ... Memory Leaks @pxtrick Ou t p u t :

Slide 69

Slide 69 text

var rockShow fans: rockShow concert: audience strong strong strong Memory Leaks @pxtrick

Slide 70

Slide 70 text

var rockShow strong strong fans: rockShow concert: audience Memory Leaks @pxtrick

Slide 71

Slide 71 text

// A rock show. class Concert { var fans: Audience? deinit { print("[Concert] - deinit()") } } // The fans. class Audience { unowned var concert: Concert init(_ concert: Concert) { self.concert = concert } deinit { print("[Audience] - deinit()") } } Memory Leaks @pxtrick

Slide 72

Slide 72 text

var rockShow fans: rockShow concert: audience strong strong Memory Leaks @pxtrick unowned

Slide 73

Slide 73 text

var rockShow fans: rockShow concert: audience strong Memory Leaks @pxtrick unowned

Slide 74

Slide 74 text

var rockShow fans: rockShow concert: audience Memory Leaks @pxtrick

Slide 75

Slide 75 text

// Create our rock show. var rockShow: Concert? = Concert() // Create and assign our fans. rockShow?.fans = Audience(rockShow!) // Clean up. print("Removing rockShow...") rockShow = nil Removing rockShow ... [Concert] - deinit() [Audience] - deinit() Ou t p u t : Memory Leaks @pxtrick

Slide 76

Slide 76 text

DEVNEXUS Atlanta – February 22, 2018 Thank You Patrick Seda - @pxtrick