ios reactive cocoa pipeline

49
Рак мозга или мозг рака Раком можно все

Upload: -

Post on 14-Apr-2017

311 views

Category:

Software


1 download

TRANSCRIPT

Page 1: iOS Reactive Cocoa Pipeline

Рак мозга или мозг рака

Раком можно все

Page 2: iOS Reactive Cocoa Pipeline

1023

Page 3: iOS Reactive Cocoa Pipeline

A for Architecture

Page 4: iOS Reactive Cocoa Pipeline

•Application Layer

•Transport Layer

•Service Layer

•Model Layer

•ViewModel Layer

•View Layer

Page 5: iOS Reactive Cocoa Pipeline

• Application Layer

•Transport Layer

•Service Layer

•Model Layer

•ViewModel Layer

•View Layer

Persistence Notifications Runtime

Page 6: iOS Reactive Cocoa Pipeline

• Application Layer

•Transport Layer

•Service Layer

•Model Layer

•ViewModel Layer

•View Layer

NSNotification LocationUpdate

Page 7: iOS Reactive Cocoa Pipeline

•Application Layer

• Transport Layer

•Service Layer

•Model Layer

•ViewModel Layer

•View Layer

Networking Networking policies

Page 8: iOS Reactive Cocoa Pipeline

•Application Layer

• Transport Layer

•Service Layer

•Model Layer

•ViewModel Layer

•View Layer

HTTP.Request HTTP.Response HTTP.Error

Page 9: iOS Reactive Cocoa Pipeline

•Application Layer

•Transport Layer

• Service Layer

•Model Layer

•ViewModel Layer

•View Layer

API Request Persistence Request Application Service wrapper

Page 10: iOS Reactive Cocoa Pipeline

•Application Layer

•Transport Layer

• Service Layer

•Model Layer

•ViewModel Layer

•View Layer

Update request Value Object Service Object

Page 11: iOS Reactive Cocoa Pipeline

•Application Layer

•Transport Layer

•Service Layer

• Model Layer

•ViewModel Layer

•View Layer

Business logic Logic state

Page 12: iOS Reactive Cocoa Pipeline

•Application Layer

•Transport Layer

•Service Layer

• Model Layer

•ViewModel Layer

•View Layer

Model Object

Page 13: iOS Reactive Cocoa Pipeline

•Application Layer

•Transport Layer

•Service Layer

•Model Layer

• ViewModel Layer

•View Layer

Application State Presentation Logic

Page 14: iOS Reactive Cocoa Pipeline

•Application Layer

•Transport Layer

•Service Layer

•Model Layer

• ViewModel Layer

•View Layer

Bindings Presentables

Page 15: iOS Reactive Cocoa Pipeline

•Application Layer

•Transport Layer

•Service Layer

•Model Layer

•ViewModel Layer

• View LayerPresentation UI State

Page 16: iOS Reactive Cocoa Pipeline

•Application Layer

•Transport Layer

•Service Layer

•Model Layer

•ViewModel Layer

• View LayerPresenters UIObjects Foundation Types

Page 17: iOS Reactive Cocoa Pipeline

Data Flow

Page 18: iOS Reactive Cocoa Pipeline

1024

Page 19: iOS Reactive Cocoa Pipeline

Data + Data Request Flow

Page 20: iOS Reactive Cocoa Pipeline

Transport Layer

Page 21: iOS Reactive Cocoa Pipeline

Transport Layer

Page 22: iOS Reactive Cocoa Pipeline

Transport Layer + Errors

Page 23: iOS Reactive Cocoa Pipeline

Transport Layer + Binding

Page 24: iOS Reactive Cocoa Pipeline

And now?

Page 25: iOS Reactive Cocoa Pipeline

RAC• Signal

• SignalProducer

• Action

• Property

• Result

Page 26: iOS Reactive Cocoa Pipeline

RAC• Signal

• SignalProducer

• Action

• Property

• Result

• Pipeline

• Future Task

• Future Builder

• Reactive State

• Enum<Value | Error>

Page 27: iOS Reactive Cocoa Pipeline

RAC• Signal

• SignalProducer

• Action

• Property

• Result

• NSNotificationCenter

• startWithCompletion:

• startWithInput:Completions

• value + KVO

• completions(result, error)

Page 28: iOS Reactive Cocoa Pipeline

RAC + Transforms• Signal -> Signal - Operator

• Signal.map(transform)

• Signal.retry(3)

• Signal -> Signal -> Signal - pipeline

- retry(map(signal, transform), 3)

✓ signal.map(transform).retry(3)

Page 29: iOS Reactive Cocoa Pipeline

RAC + (flat)map

Page 30: iOS Reactive Cocoa Pipeline

Transport Layer + RAC

Page 31: iOS Reactive Cocoa Pipeline

Transport Layer + RAC

let requestAction = Action<URLRequest, URLResponse, Error> { .../*future task*/ } let http = Action<Request, Response, Error> { request in return Result<Request, Error>(value: request) .flatMap(serialize) //Result<JSON, Error> .flatMap(requestBuilder(forConfiguration: configuration)) //Result<URLRequest, Error> .map(SignalProducer.init) //SignalProducer<URLRequest, Error> .flatMap(.Latest, transform: requestAction.apply) //SignalProducer<URLResponse, Error> .attemptMap(deserialize) //SignalProducer<Response Error }

Заметьте - эта штука вполне может быть общей вне зависимости от входных и выходных данных засчет generic

Page 32: iOS Reactive Cocoa Pipeline

Build Your Own RAC

extension SignalType { /// Returns a signal that will yield an array of values when `self` completes. @warn_unused_result(message="Did you forget to call `observe` on the signal?") public func collect() -> Signal<[Value], Error> { return self .reduce(CollectState()) { $0.append($1) } .map { $0.values } } }

Page 33: iOS Reactive Cocoa Pipeline

Transport Layer + RAC

let httpWithPolicy = Action<Request, Response, Error> { request in http.apply(request) .retry(3) .suspendOn(enterBackgroundSignal: background, enterForeground: foreground) }

Page 34: iOS Reactive Cocoa Pipeline

Service Layer

Page 35: iOS Reactive Cocoa Pipeline

Service Layer

Page 36: iOS Reactive Cocoa Pipeline

Service Layer + RAC

let service = Action<Number, Image, Error> { number in let image = cacheService.inquire .apply(number) .concat { xkcdImageHTTP.apply(number) }

let description = xkcdDescriptionHTTP.apply(number)

return combineLatest(image, description).map { ImageWithDescription(image: $0, description: $1) } }

Page 37: iOS Reactive Cocoa Pipeline

Model Layer

Page 38: iOS Reactive Cocoa Pipeline

Model Layer

Page 39: iOS Reactive Cocoa Pipeline

Model Layer + RAC

struct State { let number: Int let value: AnyProperty<ImageWithDescription?>

init(number: Int) { self.number = number self.value = AnyProperty(value: nil, producer: service.apply(number)) } }

let state = MutableProperty(State(number: 100)) let increment = { number.value = State(number: number.value.number + 1) }

let exposedState = AnyProperty(state)

Page 40: iOS Reactive Cocoa Pipeline

View Model Layer

Page 41: iOS Reactive Cocoa Pipeline

View Model Layer

Page 42: iOS Reactive Cocoa Pipeline

VM Layer + RAC let image = model.exposedState .flatMap { $0.value.image } .map { $0 ?? imagePlaceholder }

let description = model.exposedState .flatMap { $0.value.description } .map { $0 ?? "Loading..." }

let rightButtonAction = model.increment

let present = { presenters in presenters.rightButtonAction <~ rightButtonAction presenters.description <~ description.producer presenters.image <~ description.image }

Page 43: iOS Reactive Cocoa Pipeline

View Layer

Page 44: iOS Reactive Cocoa Pipeline

View + RAC

class View { //{ self.imageView.image = $0 } let image: Presenter<UIImage> = self.imageView.imagePresenter //{ self.descriptionLabel.value = $0 } let description: Presenter<String> = self.descriptionLabel.textPresenter //{ self.button.clickedSignal.observe($0) } let rightButton: Presenter<() -> ()> = self.button.clickActionPresenter }

Page 45: iOS Reactive Cocoa Pipeline

Hm…

Page 46: iOS Reactive Cocoa Pipeline

Benefits?• Consistency

• Observability

• Testability

• Encapsulation

• Completeness

Page 47: iOS Reactive Cocoa Pipeline

Examples?Popup Action

Navigation Property + Actions

UIKit Sinks + Presentables

Login Form Action + Operators

Page 48: iOS Reactive Cocoa Pipeline

What’s next?

• RXMarbles (http://rxmarbles.com/)

• Reactive Cocoa sources - all here

Page 49: iOS Reactive Cocoa Pipeline

Questions?