Slide 1

Slide 1 text

The Bright Future of Swift

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

The Future of Swift

Slide 5

Slide 5 text

I can see clearly now, where Swift will go I can see all obstacles in my way Gone are the dark clouds that had me blind It’s gonna be a bright, bright sun-shiny day. - Johnny Nash (emphasis mine)

Slide 6

Slide 6 text

Plan for the future, but live in the present

Slide 7

Slide 7 text

class Box { let value: T init(_ value: T) { self.value = value } } enum Result { case Success(Box) case Failure(Box) }

Slide 8

Slide 8 text

WWDC

Slide 9

Slide 9 text

Plan for the future, but live in the present

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

Plan for the future, but live in the present

Slide 13

Slide 13 text

session.dataTaskWithURL(url) { (data, response, error) -> Void in // process the response }

Slide 14

Slide 14 text

session.dataTaskWithURL(url) { (data, response, error) -> Void in // process the response dispatch_async(dispatch_get_main_queue()) { // update UI } } session.delegateQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)

Slide 15

Slide 15 text

func getBirds(completionHandler: [(Bird, UIImage)] -> Void) { session.dataTaskWithURL(NSURL(string: "http://developer.apple.com/naming.json")!) { (data, response, error) -> Void in if let data = data, json = self.birdsJsonFromResponseData(data) { var result: [(Bird, UIImage)] = [] for (index, bird) in json.enumerate() { if let bird = self.parseBird(bird) { self.getImage(bird) { image in result.insert((bird, image), atIndex: min(result.count, index)) if result.count == json.count { dispatch_async(dispatch_get_main_queue()) { completionHandler(result) } } } } } } }.resume() }

Slide 16

Slide 16 text

func getBirds(completionHandler: [(Bird, UIImage)] -> Void) { session.dataTaskWithURL(NSURL(string: "http://developer.apple.com/naming.json")!) { (data, response, error) -> Void in if let data = data, json = self.birdsJsonFromResponseData(data) { var result: [(Bird, UIImage)] = [] for (index, bird) in json.enumerate() { if let bird = self.parseBird(bird) { self.getImage(bird) { image in result.insert((bird, image), atIndex: min(result.count, index)) if result.count == json.count { dispatch_async(dispatch_get_main_queue()) { completionHandler(result) } } } } } } }.resume() }

Slide 17

Slide 17 text

Introducing Futures (aka Promises)

Slide 18

Slide 18 text

func getImage(name: String, completionHandler: UIImage -> Void)

Slide 19

Slide 19 text

func getImage(name: String) -> Future

Slide 20

Slide 20 text

getImage("swift").onSuccess { image in // do something with the image }

Slide 21

Slide 21 text

getImage("swift").onSuccess { image in // do something with the image }.onSuccess { image in // do something else with the image }

Slide 22

Slide 22 text

getImage("swift").onSuccess { image in // do something with the image }.onSuccess { image in // do something else with the image }.onFailure { error in // handle the error }

Slide 23

Slide 23 text

func getImage(name: String) -> Future { return Future { completion in session.fetchImage(name, completionHandler: { image in completion(.Success(image)) }) } }

Slide 24

Slide 24 text

getImage("swift").onSuccess { image in // do something with the image }.onSuccess { image in // do something else with the image }.onFailure { error in // handle the error }

Slide 25

Slide 25 text

let image = getImage("swift") // image is a Future

Slide 26

Slide 26 text

let image = getImage("swift") // image is a Future image.zip(getDetails("swift")).onSuccess { image, details in // do something with the image and the details }

Slide 27

Slide 27 text

let image = getImage("swift") // image is a Future image.zip(getDetails("swift")).onSuccess { image, details in // do something with the image and the details }.onFailure { error in // deal with the error }

Slide 28

Slide 28 text

getDetails("swift")

Slide 29

Slide 29 text

getDetails("swift").map { details in return details.substringToIndex( details.startIndex.advancedBy(30) ) }

Slide 30

Slide 30 text

getDetails("swift").map { details in return details.substringToIndex( details.startIndex.advancedBy(30) ) }.map { summary in return summary + "... Read more" }

Slide 31

Slide 31 text

getDetails("swift").map { details in return details.substringToIndex( details.startIndex.advancedBy(30) ) }.map { summary in return summary + "... Read more" } // subtitle is a Future let subtitle =

Slide 32

Slide 32 text

Asynchronous values as first-class citizens

Slide 33

Slide 33 text

getDetails("swift").map { details in return details.substringToIndex( details.startIndex.advancedBy(30) ) }.map { summary in return summary + "... Read more" } // subtitle is a Future let subtitle =

Slide 34

Slide 34 text

func +(lhs: Future, rhs: String) -> Future getDetails("swift").map { details in return details.substringToIndex( details.startIndex.advancedBy(30) ) }.map { summary in return summary + "... Read more" } // subtitle is a Future let subtitle =

Slide 35

Slide 35 text

func +(lhs: Future, rhs: String) -> Future { return lhs.map { l in return l + rhs } } getDetails("swift").map { details in return details.substringToIndex( details.startIndex.advancedBy(30) ) }.map { summary in return summary + "... Read more" } // subtitle is a Future let subtitle =

Slide 36

Slide 36 text

getDetails("swift").map { details in return details.substringToIndex( details.startIndex.advancedBy(30) ) } + "... Read more" func +(lhs: Future, rhs: String) -> Future { return lhs.map { l in return l + rhs } } let subtitle =

Slide 37

Slide 37 text

extension FutureType where Value == String { func substringToIndex(index: Int) -> Future { return map { str in return str.substringToIndex(str.startIndex.advancedBy(index)) } } } getDetails("swift").map { details in return details.substringToIndex( details.startIndex.advancedBy(30) ) } + "... Read more" let subtitle =

Slide 38

Slide 38 text

getDetails("swift").substringToIndex(30) + "... Read more" extension FutureType where Value == String { func substringToIndex(index: Int) -> Future { return map { str in return str.substringToIndex(str.startIndex.advancedBy(index)) } } } let subtitle =

Slide 39

Slide 39 text

// subtitle is a Future getDetails("swift").substringToIndex(30) + "... Read more" let subtitle =

Slide 40

Slide 40 text

cell.detailTextLabel!.text = subtitle // subtitle is a Future getDetails("swift").substringToIndex(30) + "... Read more" let subtitle =

Slide 41

Slide 41 text

public enum Optional

Slide 42

Slide 42 text

The Future’s 20%

Slide 43

Slide 43 text

func getImage(url: String) -> async UIImage

Slide 44

Slide 44 text

func getImage(url: String) -> async UIImage { let data: async NSData = session.fetch(url) return UIImage(data: data) }

Slide 45

Slide 45 text

func setImage(url: String) -> async Void { let image: async UIImage = getImage(url) when let image = image { imageView.image = image } }

Slide 46

Slide 46 text

func setImage(url: String) -> Future { let image: Future = getImage(url) return image.onSuccess { image in imageView.image = image }.asVoid() }

Slide 47

Slide 47 text

func setImage(url: String) -> async Void { let image: async UIImage = getImage(url) when let image = image { imageView.image = image } }

Slide 48

Slide 48 text

func setImage(url: String) { let image: async UIImage = getImage(url) if let image = image { imageView.image = image } }

Slide 49

Slide 49 text

func setImage(url: String) { let image: async UIImage = getImage(url) imageView.image = image! }

Slide 50

Slide 50 text

The Future’s 20% *

Slide 51

Slide 51 text

No content

Slide 52

Slide 52 text

The thread-safety layer Copyable Reentrant Code Gateway Annotation

Slide 54

Slide 54 text

Plan for the future, but live in the present

Slide 55

Slide 55 text

Thank you! @thomvis88 https://github.com/Thomvis/BrightFutures http://highstreetapp.com