Swift 2.2 Design Patterns CocoaConf Austin 2016

of 100/100
Swift 2.2 Design Patterns COCOACONF AUSTIN APRIL 2016 Skyline Credit: User:Argash [GFDL (http://www.gnu.org/copyleft/fdl.html) or CC BY-SA 3.0 (http://creativecommons.org/licenses/by-sa/3.0)], via Wikimedia Commons @CarlBrwn
  • date post

    12-Jan-2017
  • Category

    Technology

  • view

    311
  • download

    0

Embed Size (px)

Transcript of Swift 2.2 Design Patterns CocoaConf Austin 2016

  • Swift 2.2 Design Patterns

    COCOACONF AUSTIN APRIL 2016

    Skyline Credit: User:Argash [GFDL (http://www.gnu.org/copyleft/fdl.html) or CC BY-SA 3.0 (http://creativecommons.org/licenses/by-sa/3.0)], via Wikimedia Commons

    @CarlBrwn

  • Swift 2.2 Design Patterns

    COCOACONF AUSTIN APRIL 2016

    Skyline Credit: User:Argash [GFDL (http://www.gnu.org/copyleft/fdl.html) or CC BY-SA 3.0 (http://creativecommons.org/licenses/by-sa/3.0)], via Wikimedia Commons

    @CarlBrwn

  • [:]?

    So, who is this idiot, anyway?

    INTRODUCTION

    @CarlBrwn

  • These mean a lot of different things to different people.

    Hopefully theyre of some use to you.

    WIDELY RECOGNIZED, BUT NOT UNDISPUTED

  • These mean a lot of different things to different people.

    Hopefully theyre of some use to you.

    WIDELY RECOGNIZED, BUT NOT UNDISPUTED

    [:]?

    Critical Concept in Software Engineering?Some think so, others disagree.

    [:]?Simple Enumeration of

    Weaknesses in C++See http://www.norvig.com/design-

    patterns/[:]?

    Just Shared Vocabulary?

  • So, Lets talk about Swift (2.2 Version)

    PATTERNS ARE LANGUAGE SPECIFIC

    [:]?

    Critical Concept in Software Engineering?Some think so, others disagree.

    [:]?Simple Enumeration of

    Weaknesses in C++See http://www.norvig.com/design-

    patterns/[:]?

    Just Shared Vocabulary?

  • So, Lets talk about Swift (2.2 Version)

    & Cocoa

    PATTERNS ARE LANGUAGE (& FRAMEWORK) SPECIFIC

    [:]?

    Critical Concept in Software Engineering?Some think so, others disagree.

    [:]?Simple Enumeration of

    Weaknesses in C++See http://www.norvig.com/design-

    patterns/[:]?

    Just Shared Vocabulary?

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    PATTERN SOURCES FOR TODAY

    8

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    PATTERN SOURCES FOR TODAY

    8

    Classic Cocoa Design Patterns as implemented in Swift

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    PATTERN SOURCES FOR TODAY

    8

    Classic Cocoa Design Patterns as implemented in SwiftSome Gang of Four Patterns that lend

    themselves to Swift

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    PATTERN SOURCES FOR TODAY

    8

    Classic Cocoa Design Patterns as implemented in SwiftSome Gang of Four Patterns that lend

    themselves to SwiftPatterns Apple Documents for Swift

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    PATTERN SOURCES FOR TODAY

    8

    Classic Cocoa Design Patterns as implemented in SwiftSome Gang of Four Patterns that lend

    themselves to SwiftPatterns Apple Documents for SwiftPatterns from Other Languages

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    PATTERN SOURCES FOR TODAY

    8

    Classic Cocoa Design Patterns as implemented in SwiftSome Gang of Four Patterns that lend

    themselves to SwiftPatterns Apple Documents for SwiftPatterns from Other LanguagesInteresting/Potential Swift-specific Patterns

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    DELEGATE PATTERN

    9

    Cocoa is said to favor Composition over Inheritance. Delegation is one of the hallmarks of that strategy. UITableViewDataSource and UITableViewDelegate are examples.

    CLASSIC COCOA PATTERN

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    DELEGATE PATTERN

    9

    Cocoa is said to favor Composition over Inheritance. Delegation is one of the hallmarks of that strategy. UITableViewDataSource and UITableViewDelegate are examples.

    CLASSIC COCOA PATTERN

    [:]?Eases ConstructionThis is a big reason why we dont have to use the Factory Pattern in Cocoa/Swift

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    DELEGATE PATTERN IN SWIFT

    10

    var myDS : UITableViewDataSource?

    let myTVC = UITableViewController() let myTV = myTVC.tableView

    let num = myDS?.tableView(myTV, numberOfRowsInSection: 0)

    let firstHeader = myDS?.tableView?(myTV, titleForHeaderInSection: 0)

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    DELEGATE PATTERN IN SWIFT

    10

    var myDS : UITableViewDataSource?

    let myTVC = UITableViewController() let myTV = myTVC.tableView

    let num = myDS?.tableView(myTV, numberOfRowsInSection: 0)

    let firstHeader = myDS?.tableView?(myTV, titleForHeaderInSection: 0)

    1Test Delegate OptionalThe delegate itself must not be nil (check with ? and dont (EVER) use !)

    2Test Method ExistsPut ? after method call to test for @optional implementation

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    ERROR HANDLING PATTERN

    11

    In Cocoa, methods that produce errors take an NSError pointer parameter last parameter.

    In Swift 2, this is converted to a thrown ErrorType

    NEW IN SWIFT 2 - HOOKS INTO COCOAS (NSError**)

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    ERROR HANDLING PATTERN

    11

    In Cocoa, methods that produce errors take an NSError pointer parameter last parameter.

    In Swift 2, this is converted to a thrown ErrorType

    NEW IN SWIFT 2 - HOOKS INTO COCOAS (NSError**)

    []Not JAvas Throwtry on each line that might throw catch for blocks

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    ERROR HANDLING PATTERN IN SWIFT

    12

    - (BOOL)removeItemAtURL:(NSURL *)URL error:(NSError **)error { NSFileManager *fileManager = [NSFileManager defaultManager]; NSURL *URL = [NSURL fileURLWithPath:@"/path/to/file"]; NSError *error = nil; BOOL success = [fileManager removeItemAtURL:URL error:&error]; if (!success) { NSLog(@"Error: %@", error.domain); } }

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    ERROR HANDLING PATTERN IN SWIFT

    12

    func removeItemAtURL(URL: NSURL) throws { let fileManager = NSFileManager.defaultManager() let URL = NSURL.fileURLWithPath("/path/to/file") do { try fileManager.removeItemAtURL(URL) } catch let error as NSError { print("Error: \(error.domain)") } }

    - (BOOL)removeItemAtURL:(NSURL *)URL error:(NSError **)error { NSFileManager *fileManager = [NSFileManager defaultManager]; NSURL *URL = [NSURL fileURLWithPath:@"/path/to/file"]; NSError *error = nil; BOOL success = [fileManager removeItemAtURL:URL error:&error]; if (!success) { NSLog(@"Error: %@", error.domain); } }

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    OBSERVER PATTERN

    13

    Key-Value Observing lets you observe any well-behaved Cocoa property (getter/setter).

    It works in Swift *As Long As* the target isKindOf: NSObject

    KVO IN SWIFT

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    OBSERVER PATTERN IN SWIFT

    14

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    OBSERVER PATTERN IN SWIFT

    14

    objectToObserve.addObserver(self, forKeyPath: "myDate", options: .New, context: &myContext)

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    OBSERVER PATTERN IN SWIFT

    14

    objectToObserve.addObserver(self, forKeyPath: "myDate", options: .New, context: &myContext)

    override func observeValueForKeyPath(keyPath:String?, ofObject object: AnyObject?, change: [ String : AnyObject ]?, context: UnsafeMutablePointer ) {

    if context == &myContext { if let newValue = change?[NSKeyValueChangeNewKey] { print("Date changed: \(newValue)") } } else { super.observeValueForKeyPath(keyPath, ofObject: object, change: change, context: context)

    } }

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    OBSERVER PATTERN IN SWIFT

    14

    objectToObserve.addObserver(self, forKeyPath: "myDate", options: .New, context: &myContext)

    override func observeValueForKeyPath(keyPath:String?, ofObject object: AnyObject?, change: [ String : AnyObject ]?, context: UnsafeMutablePointer ) {

    if context == &myContext { if let newValue = change?[NSKeyValueChangeNewKey] { print("Date changed: \(newValue)") } } else { super.observeValueForKeyPath(keyPath, ofObject: object, change: change, context: context)

    } }

    objectToObserve.removeObserver(self, forKeyPath: "myDate", context: &myContext)

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    SWIFT-NATIVE KVO *MAYBE* IN SWIFT 4

    15

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    TARGET-ACTION PATTERN

    16

    In Objective-C, we use @selector to wrap the method name when adding it as a target.

    In Swift 1.x, we just used a String and still had no compiler typo checking. In Swift 2.2, we have #selector (SE-0022) and we FINALLY have compiler type checking.

    OSS FTW!!

    ATTACH AN ACTION TO A UI ELEMENT

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    TARGET-ACTION PATTERN IN SWIFT

    17

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    TARGET-ACTION PATTERN IN SWIFT

    17

    @objc func tappedButton(sender:UIButton!) { print("tapped button") }

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    TARGET-ACTION PATTERN IN SWIFT

    17

    @objc func tappedButton(sender:UIButton!) { print("tapped button") } #if swift(>=2.2)

    myButton.addTarget(self, action: #selector(tappedButton), forControlEvents: .TouchUpInside)

    #else myButton.addTarget(self, action: "tappedButton",

    forControlEvents: .TouchUpInside) #endif

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    TARGET-ACTION PATTERN IN SWIFT

    17

    @objc func tappedButton(sender:UIButton!) { print("tapped button") } #if swift(>=2.2)

    myButton.addTarget(self, action: #selector(tappedButton), forControlEvents: .TouchUpInside)

    #else myButton.addTarget(self, action: "tappedButton",

    forControlEvents: .TouchUpInside) #endif

    1Legacy Objective-COnly @objc functions can be made #selectors

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    SINGLETON PATTERN

    18

    Fairly common in Cocoa, like [UIApplication sharedApplication]

    In Swift, theyre much simpler to declare (and like ObjC, never dealloced).

    A static type property is guaranteed to be lazily initialized only once, even when accessed across multiple threads simultaneously.

    SINGLETONS: GLOBAL SHARED INSTANCE

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    SINGLETON PATTERN IN SWIFT

    19

    class Singleton { static let sharedInstance = Singleton() }

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    SINGLETON PATTERN IN SWIFT

    19

    class Singleton { static let sharedInstance = Singleton() }

    []Well, That Was EasyObj-C is so much more complicated

    []Not All Shared Instances Are Singletonse.g. NSFileManager

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    INTROSPECTION PATTERN

    20

    Apples Docs call this a pattern. Its pretty much the same functionality as we discussed for Delegation. In my mind, is this a kind of X class and does this implement Y method are very limited forms of Introspection.

    DYNAMICALLY EXAMINE TYPES AT RUNTIME

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    INTROSPECTION PATTERN

    20

    Apples Docs call this a pattern. Its pretty much the same functionality as we discussed for Delegation. In my mind, is this a kind of X class and does this implement Y method are very limited forms of Introspection.

    DYNAMICALLY EXAMINE TYPES AT RUNTIME

    []Not Very UsefulWay harder in pure Swift than ObjC. Most attempts bridge NSObjects.

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    API AVAILABILITY CHECKING PATTERN

    21

    Swift does this at Compile time rather than Runtime (like ObjC). Calling this a Pattern seems like a bit of a stretch to me, but Apple does. It is indisputably useful, though.

    DECIDE WHETHER AN API IS AVAILABLE

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    API AVAILABILITY CHECKING PATTERN

    21

    Swift does this at Compile time rather than Runtime (like ObjC). Calling this a Pattern seems like a bit of a stretch to me, but Apple does. It is indisputably useful, though.

    DECIDE WHETHER AN API IS AVAILABLE

    []Also for Swift Version #sStarting with Swift 2.2

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    API AVAILABILITY CHECKING PATTERN IN SWIFT

    22

    if ([CLLocationManager instancesRespondToSelector:@selector(requestWhenInUseAuthorization)]) {

    // Method is available for use. } else { // Method is not available. }

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    API AVAILABILITY CHECKING PATTERN IN SWIFT

    22

    let locationManager = CLLocationManager() if #available(iOS 8.0, OSX 10.10, *) { locationManager.requestWhenInUseAuthorization() } let locationManager = CLLocationManager() guard #available(iOS 8.0, OSX 10.10, *) else { return } locationManager.requestWhenInUseAuthorization()

    if ([CLLocationManager instancesRespondToSelector:@selector(requestWhenInUseAuthorization)]) {

    // Method is available for use. } else { // Method is not available. }

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    API AVAILABILITY CHECKING PATTERN IN SWIFT

    22

    let locationManager = CLLocationManager() if #available(iOS 8.0, OSX 10.10, *) { locationManager.requestWhenInUseAuthorization() } let locationManager = CLLocationManager() guard #available(iOS 8.0, OSX 10.10, *) else { return } locationManager.requestWhenInUseAuthorization()

    if ([CLLocationManager instancesRespondToSelector:@selector(requestWhenInUseAuthorization)]) {

    // Method is available for use. } else { // Method is not available. }

    #if swift(>=2.2) let tapped = #selector(tappedButton)

    #endif

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    VALUE TYPES/STRUCTS

    23

    Swift structs can have methods and implement protocols much like classes, but theyre always passed by value (copied) rather than passed by reference like objects (which makes them generally thread-safe, amongst other things).

    SWIFT HAS RICH VALUE-TYPES

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    UBIQUITOUS IMMUTABILITY

    24

    Pretty much all Swift variables can be declared immutable (with let), not just certain types like ObjC.

    Immutable variables are safer, thread-safe and side-effect free, which is one claim to fame for functional languages.

    NOT JUST FOR STRING/DICT/ARRAY ANYMORE

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    SEPARATION OF ERRORS

    25

    Swift has several mechanisms to keep error checking outside and separate from your business logic.

    Checks often get moved from runtime to compile time, and syntax allows for checks to be isolated to avoid further complicating already-intricate code.

    KEEP ERROR CHECKING AWAY FROM YOUR ALGORITHMS

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    SEPARATION OF ERRORS 1: if let

    26

    Much safer than finding out the hard way at runtime.

    Unless you use (!)

    You dont use (!), do you? (At least not in shipping apps)

    ENFORCES NIL-CHECK AT COMPILE TIME

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    SEPARATION OF ERRORS IN SWIFT 1: if let

    27

    if let obj = obj { //business logic about object goes here }

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    SEPARATION OF ERRORS 2: guard

    28

    Good for checking at the top of a method

    Avoids the if-let pyramid of doom

    LIKE if-let, BUT WITH CONTINUING SCOPE

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    SEPARATION OF ERRORS IN SWIFT 2: guard

    29

    guard let obj = obj as? NSString where obj.length > 0 else { return }

    //business logic about object goes here

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    SEPARATION OF ERRORS 3: defer

    30

    Make sure something happens as you exit a scope

    SCHEDULE SOMETHING FOR LATER

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    SEPARATION OF ERRORS 3: defer

    30

    Make sure something happens as you exit a scope

    SCHEDULE SOMETHING FOR LATER

    []Dearly [email protected](dict) { //use dict safely

    }

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    SEPARATION OF ERRORS IN SWIFT 3: defer

    31

    let lock = NSLock()

    func useLock() { lock.lock() defer { lock.unlock() } //use lock }

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    SEPARATION OF ERRORS: try?

    32

    The try syntax gets scattered all over your code.

    Not exactly as good, but at least better than NSError** (or god forbid Cs return codes and errno).

    TRY IS A COUNTER-EXAMPLE THOUGH

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    SEPARATION OF ERRORS IN SWIFT: try?

    33

    let url = try fileManager.URLForDirectory(.ApplicationDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: false)

    try fileManager.removeItemAtURL( url.URLByAppendingPathComponent("/path/to/file", isDirectory: true))

    if let path = url.URLByAppendingPathComponent("/path/to/file").path { let files = try fileManager.contentsOfDirectoryAtPath(path) //do something with files }

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    SEPARATION OF ERRORS IN SWIFT: try?

    33

    let url = try fileManager.URLForDirectory(.ApplicationDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: false)

    try fileManager.removeItemAtURL( url.URLByAppendingPathComponent("/path/to/file", isDirectory: true))

    if let path = url.URLByAppendingPathComponent("/path/to/file").path { let files = try fileManager.contentsOfDirectoryAtPath(path) //do something with files }

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    MONADS (A LA HASKELL MAYBE)

    34

    Very complicated, at least if you believe most people.

    I remember being amazed - *Really amazed* at WWDC 2014 when I realized Apple stuck a Haskell Maybe Monad into Swift, and used all of 1-character to do it.

    FUNCTIONAL PROGRAMMING CONCEPT

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    MAYBE MONAD

    35

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    MAYBE MONAD SWIFT OPTIONAL

    36

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    MAYBE MONAD SWIFT OPTIONAL

    36

    Optional

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    MAYBE MONAD SWIFT OPTIONAL

    36

    Optional

    ! ?

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    MAYBE MONAD SWIFT OPTIONAL

    36

    Optional

    ! ?

    ?

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    MAYBE MONAD SWIFT OPTIONAL

    36

    Optional

    ! ?

    ?

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    MAYBE MONAD SWIFT OPTIONAL

    36

    Optional

    ! ?

    ?

    !

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    MAYBE MONAD SWIFT OPTIONAL

    36

    Optional

    ! ?

    ?

    !

    []! Considered HARMFULI mean that in a GOTO sense.

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    MAPREDUCE

    37

    Without this, the Internet as you know it would never have come to exist, and least not when and how it did.

    SEMINAL PAPER BEHIND EARLY GOOGLE

    http://static.googleusercontent.com/media/research.google.com/es/us/archive/mapreduce-osdi04.pdf

    http://static.googleusercontent.com/media/research.google.com/es/us/archive/mapreduce-osdi04.pdf

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    MAPREDUCE MAP

    38

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    MAPREDUCE MAP

    38

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    MAPREDUCE MAP

    38

    []

    Rule of thumbSame count, Different Type

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    MAPREDUCE MAP IN SWIFT

    39

    let names = ["RedStripeOnWhite.jpg","OrangeStripeOnWhite.jpg", "YellowStripeOnWhite.jpg","GreenStripeOnWhite.jpg", "BlackHorizontal.jpg","BlueStripeOnWhite.jpg", IndigoStripeOnWhite.jpg,"VioletStripeOnWhite.jpg"]

    let images = names.map { UIImage(named: $0)

    }

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    MAPREDUCE MAP IN SWIFT

    39

    let names = ["RedStripeOnWhite.jpg","OrangeStripeOnWhite.jpg", "YellowStripeOnWhite.jpg","GreenStripeOnWhite.jpg", "BlackHorizontal.jpg","BlueStripeOnWhite.jpg", IndigoStripeOnWhite.jpg,"VioletStripeOnWhite.jpg"]

    let images = names.map { UIImage(named: $0)

    }

    1Real WorlD: JSONI use this a lot to map JSON Dict to Object/Struct, but this is more visual

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    MAPREDUCE FILTER

    40

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    MAPREDUCE FILTER

    40

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    MAPREDUCE FILTER

    40

    []

    Rule of thumbSame Type, Lower Count

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    MAPREDUCE FILTER IN SWIFT

    41

    let colors = images.filter { !mono($0) }

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    MAPREDUCE FILTER IN SWIFT

    41

    let colors = images.filter { !mono($0) }

    1Real WorlD: JSONI use this a lot to throw out JSON Dicts I dont need

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    MAPREDUCE REDUCE

    42

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    MAPREDUCE REDUCE

    42

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    MAPREDUCE REDUCE

    42

    []

    Rule of thumbDifferent Type, Count == 1

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    MAPREDUCE REDUCE

    43

    let rainbowImage = ciImages.reduce(CIImage()) { (s, img) -> CIImage? in let f = CIFilter(name: "CISourceOverCompositing") f?.setValue(s, forKey: kCIInputBackgroundImageKey) f?.setValue(img, forKey:kCIInputImageKey) return f?.outputImage }

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    MAPREDUCE REDUCE

    43

    let rainbowImage = ciImages.reduce(CIImage()) { (s, img) -> CIImage? in let f = CIFilter(name: "CISourceOverCompositing") f?.setValue(s, forKey: kCIInputBackgroundImageKey) f?.setValue(img, forKey:kCIInputImageKey) return f?.outputImage }

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    MAPREDUCE REDUCE

    44

    let rainbowImage = ciImages.reduce(CIImage()) { (s, img) -> CIImage? in let f = CIFilter(name: "CISourceOverCompositing") f?.setValue(s, forKey: kCIInputBackgroundImageKey) f?.setValue(img, forKey:kCIInputImageKey) return f?.outputImage }

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    MAPREDUCE REDUCE

    44

    let rainbowImage = ciImages.reduce(CIImage()) { (s, img) -> CIImage? in let f = CIFilter(name: "CISourceOverCompositing") f?.setValue(s, forKey: kCIInputBackgroundImageKey) f?.setValue(img, forKey:kCIInputImageKey) return f?.outputImage }

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    MAPREDUCE REDUCE

    45

    let rainbowImage = ciImages.reduce(CIImage()) { (s, img) -> CIImage? in let f = CIFilter(name: "CISourceOverCompositing") f?.setValue(s, forKey: kCIInputBackgroundImageKey) f?.setValue(img, forKey:kCIInputImageKey) return f?.outputImage }

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    MAPREDUCE REDUCE

    45

    let rainbowImage = ciImages.reduce(CIImage()) { (s, img) -> CIImage? in let f = CIFilter(name: "CISourceOverCompositing") f?.setValue(s, forKey: kCIInputBackgroundImageKey) f?.setValue(img, forKey:kCIInputImageKey) return f?.outputImage }

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    MAPREDUCE REDUCE

    46

    let rainbowImage = ciImages.reduce(CIImage()) { (s, img) -> CIImage? in let f = CIFilter(name: "CISourceOverCompositing") f?.setValue(s, forKey: kCIInputBackgroundImageKey) f?.setValue(img, forKey:kCIInputImageKey) return f?.outputImage }

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    MAPREDUCE REDUCE

    46

    let rainbowImage = ciImages.reduce(CIImage()) { (s, img) -> CIImage? in let f = CIFilter(name: "CISourceOverCompositing") f?.setValue(s, forKey: kCIInputBackgroundImageKey) f?.setValue(img, forKey:kCIInputImageKey) return f?.outputImage }

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    MAPREDUCE REDUCE

    47

    let rainbowImage = ciImages.reduce(CIImage()) { (s, img) -> CIImage? in let f = CIFilter(name: "CISourceOverCompositing") f?.setValue(s, forKey: kCIInputBackgroundImageKey) f?.setValue(img, forKey:kCIInputImageKey) return f?.outputImage }

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    MAPREDUCE REDUCE

    47

    let rainbowImage = ciImages.reduce(CIImage()) { (s, img) -> CIImage? in let f = CIFilter(name: "CISourceOverCompositing") f?.setValue(s, forKey: kCIInputBackgroundImageKey) f?.setValue(img, forKey:kCIInputImageKey) return f?.outputImage }

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    MAPREDUCE REDUCE

    48

    let rainbowImage = ciImages.reduce(CIImage()) { (s, img) -> CIImage? in let f = CIFilter(name: "CISourceOverCompositing") f?.setValue(s, forKey: kCIInputBackgroundImageKey) f?.setValue(img, forKey:kCIInputImageKey) return f?.outputImage }

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    MAPREDUCE REDUCE

    48

    let rainbowImage = ciImages.reduce(CIImage()) { (s, img) -> CIImage? in let f = CIFilter(name: "CISourceOverCompositing") f?.setValue(s, forKey: kCIInputBackgroundImageKey) f?.setValue(img, forKey:kCIInputImageKey) return f?.outputImage }

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    MAPREDUCE REDUCE

    49

    let rainbowImage = ciImages.reduce(CIImage()) { (s, img) -> CIImage? in let f = CIFilter(name: "CISourceOverCompositing") f?.setValue(s, forKey: kCIInputBackgroundImageKey) f?.setValue(img, forKey:kCIInputImageKey) return f?.outputImage }

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    MAPREDUCE REDUCE

    49

    let rainbowImage = ciImages.reduce(CIImage()) { (s, img) -> CIImage? in let f = CIFilter(name: "CISourceOverCompositing") f?.setValue(s, forKey: kCIInputBackgroundImageKey) f?.setValue(img, forKey:kCIInputImageKey) return f?.outputImage }

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    MAPREDUCE - WAIT, WAIT, WAIT!!!

    50

    I have yet to see a case where map/reduce worked consistently faster on iOS than the equivalent for..in loop, and often it can be quite a bit slower.

    BUT - learn it anyway.

    ABOUT SWIFTS MAPREDUCE PERFORMANCE

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    MAPREDUCE - SO WHATS THE POINT?

    51

    or threads. Or at least, that was the design intent.

    I still use it (although I dont have to), because Im used to it from other languages (and I use it with dispatch_groups, despite the fact they dont fit on slides).

    But Soon (SWIFT 4?? - see earlier email), well have a Swift release that focuses on asynchronous functionality. And THEN, it will really, really matter.

    MAPREDUCE SPLITS WORK BETWEEN MACHINES

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    PROTOCOL DEFAULT IMPLEMENTATIONS

    52

    Protocol Implementations allow for much more useful protocols, and for much more flexible implementations.

    WHOLE NEW WORLD

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    PROTOCOL EXTENSIONS (W/IMPLEMENTATIONS)

    53

    Protocol Implementations allow for much more useful protocols, and for much more flexible implementations.

    WHOLE NEW WORLD

  • Design Patterns in Swift 2.2CocoaConf Austin 2016

    PROTOCOL EXTENSIONS (W/IMPLEMENTATIONS)

    53

    Protocol Implementations allow for much more useful protocols, and for much more flexible implementations.

    WHOLE NEW WORLD

    1Examples are ContrivedAnd they take a while to set up, and Im expecting this is already going long

    2Big TopicTheres a whole (VERY GOOD) WWDC talk on just this.

  • Speaking to you all is always a pleasure.

    Thank You

  • Speaking to you all is always a pleasure.

    Thank You