Swift 2.2 Design Patterns CocoaConf Austin 2016
-
Upload
carl-brown -
Category
Technology
-
view
313 -
download
0
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 they’re of some use to you.
WIDELY RECOGNIZED, BUT NOT UNDISPUTED
These mean a lot of different things to different people.
Hopefully they’re 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, Let’s 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, Let’s 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 don’t 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 don’t (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 COCOA’S (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 COCOA’S (NSError**)
[]Not JAva’s 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 <Void>) {
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 <Void>) {
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, they’re much simpler to declare (and like ObjC, never dealloc’ed).
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
Apple’s Docs call this a pattern. It’s 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
Apple’s Docs call this a pattern. It’s 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 they’re 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 don’t 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 Departed@synchronized(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 C’s 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
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 don’t 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 SWIFT’S MAPREDUCE PERFORMANCE…
Design Patterns in Swift 2.2CocoaConf Austin 2016
MAPREDUCE - SO WHAT’S THE POINT?
51
…or threads. Or at least, that was the design intent.
I still use it (although I don’t have to), because I’m used to it from other languages (and I use it with dispatch_groups, despite the fact they don’t fit on slides).
But Soon (SWIFT 4?? - see earlier email), we’ll 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 I’m expecting this is already going long
2Big TopicThere’s 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