SlideShare a Scribd company logo
November 2017
Coming Soon…
Declarative
presentations
Imperative
vs
Declarative
Instructions
Facts
Understand how the system works
and based on its state and state
transitions decide what instructions to
execute.
Instructions
Facts
Understand how the system works
and based on its state and state
transitions decide what instructions to
execute.
State how your code should work if
certain conditions are met. You don’t
need to keep track of the current
state of the system, it calls you.
Example
———————————— Imperative
button.frame = CGRect(
x: inset,
y: view.bounds.size.height - buttonSize - inset,
width: view.bounds.size.width - 2 * inset,
height: buttonSize
)
Example
———————————— Imperative
button.frame = CGRect(
x: inset,
y: view.bounds.size.height - buttonSize - inset,
width: view.bounds.size.width - 2 * inset,
height: buttonSize
)
Example
———————————— Imperative
button.frame = CGRect(
x: inset,
y: view.bounds.size.height - buttonSize - inset,
width: view.bounds.size.width - 2 * inset,
height: buttonSize
) // <— Needs to be done every time view.bounds change
Example
———————————— Imperative
button.frame = CGRect(
x: inset,
y: view.bounds.size.height - buttonSize - inset,
width: view.bounds.size.width - 2 * inset,
height: buttonSize
)
———————————— (More) Declarative
NSLayoutConstraint.activate(
button.heightAnchor == buttonSize,
button.centerXAnchor == view.centerXAnchor,
button.bottomAnchor == view.bottomAnchor - inset,
button.leadingAnchor == view.leadingAnchor + inset
)
Example
———————————— Imperative
button.frame = CGRect(
x: inset,
y: view.bounds.size.height - buttonSize - inset,
width: view.bounds.size.width - 2 * inset,
height: buttonSize
)
———————————— (More) Declarative
NSLayoutConstraint.activate(
button.heightAnchor == buttonSize,
button.centerXAnchor == view.centerXAnchor,
button.bottomAnchor == view.bottomAnchor - inset,
button.leadingAnchor == view.leadingAnchor + inset
)
Google Facebook
Apple? (maybe)
UIKit encourages
imperative
programming style
UIKit encourages
imperative
programming style
but we can wrap it!
The concept 📚
See it in practice "
Further opportunities 🚀
The plan
The concept
We show things on the screen for a
reason. When presenting a view, we
need to wait for a user to take some
kind of action and then our app
responds to that action.
💡
Presenting a view == asynchronous
operation.
The concept
If view presentations
are async functions
they can have a declarative interface
Let’s build a small app!
Pay now
Shopping cart
Receipt
Check out
Taking it further
Presentable as we defined it
protocol Presentable {
associatedtype Value
func start() -> (UIViewController, FutureResult<Value>)
}
Presentable in iZettle
public protocol Presentable {
associatedtype Matter
associatedtype Result
/// Constructs a matter from `self` and returns it
together with the result of presenting it.
func materialize() -> (Matter, Result)
}
Presentable wrapper
public struct Presentation<P>
where P : Presentable, P.Matter : UIViewController {
// The presentable wrapped by `self`.
public var presentable: P
// The presentation style to use when presenting `self`.
public var style: PresentationStyle
// The presentation options to use when presenting `self`.
public var options: PresentationOptions
// The configuration to apply just before presenting `self`.
public var configure: (P.Matter, DisposeBag) -> ()
// A transformation to apply on the result of `materialize()`.
public var transform: (P.Result) -> P.Result
// A callback that will be called once presentation is done,
either with `nil` if normally dismissed, or with an error if not.
public var onDismiss: (Error?) -> ()
}
Example
let playVideo: (Video) -> Presentation<MoviePlayer> = { video in
return Presentation(MoviePlayer(video: video),
style: .flipPush,
configure: installDismiss(.close))
}
9:55:53 AM: TestScreen will 'flipPush' present: MoviePlayer
9:55:55 AM: TestScreen did end presentation of: MoviePlayer
9:55:55 AM: MoviePlayer was deallocated after presentation from
TestScreen
(lldb)
Utilising Swift type system
You can create helpers that make it
easier to write declarative code, keep
track of presentations and even detect
memory leaks!
Testing
Test failure
func testRegister_fails_whenPresentReturnsError() {
let pointOfSale = PointOfSale.dummy
let expectedError = TestError()
let result = pointOfSale.pay { _ in
return FutureResult(error: expectedError)
}
let flowCompletion = expectation(description: "Flow completed")
result.observe { flowResult in
guard case .failure(let error) = flowResult else {
XCTFail("Expected flow failure but got (flowResult)")
return
}
XCTAssertEqual(error as? TestError, expectedError)
flowCompletion.fulfill()
}
wait(for: [flowCompletion], timeout: 0.1)
}
Snapshot testing
func configureAndTakeSnapshots<T: Presentable, R>(
of presentable: T,
configuredAs configuration: SnapshotWindow.Configuration,
identifier: String,
file: StaticString = #file,
line: UInt = #line
) where T.Matter: UIViewController, T.Result == Future<R> {
let (window, result) = presentable.materializeAndAddToWindow(
configuredAs: configuration
)
FBSnapshotVerifyView(
window,
identifier: identifier,
file: file,
line: line
)
result.disposable.dispose()
}
Hiding complexity
Choose
Payment
More realistic checkout
Checkout
Payment
Specific
Screens
Send
Receipt
Register
Choose
Payment
More realistic checkout
Checkout
Receipt
Payment
Specific
Register
Field tested
Take-aways
•We show UI for a purpose - to drive
data flows in our apps and we can
express presentations as async
functions that return a Result
•Keeping the UI flow logic decoupled
makes it easy to follow and test
•Declarative programming for
presentations makes the possible user
journeys explicit.
Further reading
1. Live coding playground
2. iZettle - Introducing Presentation [oss]
3. Chris Eidhof - Functional View Controllers
4. Benjamin Encz - Turning UIKit Inside Out
5. iZettle - Functional Views
6. Google I/O - Declarative UI patterns
7. Matt Galagher - Declarative views
8. Less verbose constraints [oss]
…
@nataliya_bg
Thank you!

More Related Content

What's hot

Workshop 5: JavaScript testing
Workshop 5: JavaScript testingWorkshop 5: JavaScript testing
Workshop 5: JavaScript testing
Visual Engineering
 
Funcitonal Swift Conference: The Functional Way
Funcitonal Swift Conference: The Functional WayFuncitonal Swift Conference: The Functional Way
Funcitonal Swift Conference: The Functional Way
Natasha Murashev
 
Protocol Oriented MVVM - Auckland iOS Meetup
Protocol Oriented MVVM - Auckland iOS MeetupProtocol Oriented MVVM - Auckland iOS Meetup
Protocol Oriented MVVM - Auckland iOS Meetup
Natasha Murashev
 
Workshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScriptWorkshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScript
Visual Engineering
 
Angular2: Quick overview with 2do app example
Angular2: Quick overview with 2do app exampleAngular2: Quick overview with 2do app example
Angular2: Quick overview with 2do app example
Alexey Frolov
 
Java Script Promise
Java Script PromiseJava Script Promise
Java Script PromiseAlok Guha
 
N Things You Don't Want to Repeat in React Native
N Things You Don't Want to Repeat in React NativeN Things You Don't Want to Repeat in React Native
N Things You Don't Want to Repeat in React Native
Anton Kulyk
 
Protocol-Oriented MVVM
Protocol-Oriented MVVMProtocol-Oriented MVVM
Protocol-Oriented MVVM
Natasha Murashev
 
Vue next
Vue nextVue next
Javascript And J Query
Javascript And J QueryJavascript And J Query
Javascript And J Query
itsarsalan
 
Javascript Design Patterns
Javascript Design PatternsJavascript Design Patterns
Javascript Design PatternsZohar Arad
 
Protocol-Oriented MVVM (extended edition)
Protocol-Oriented MVVM (extended edition)Protocol-Oriented MVVM (extended edition)
Protocol-Oriented MVVM (extended edition)
Natasha Murashev
 
Human Talks - StencilJS
Human Talks - StencilJSHuman Talks - StencilJS
Human Talks - StencilJS
Alexandre Koelsch
 
The evolution of asynchronous javascript
The evolution of asynchronous javascriptThe evolution of asynchronous javascript
The evolution of asynchronous javascript
Alessandro Cinelli (cirpo)
 
AngularJS Testing Strategies
AngularJS Testing StrategiesAngularJS Testing Strategies
AngularJS Testing Strategies
njpst8
 
Func up your code
Func up your codeFunc up your code
Func up your code
Maciej Komorowski
 
Backday Xebia : Akka, the reactive toolkit
Backday Xebia : Akka, the reactive toolkitBackday Xebia : Akka, the reactive toolkit
Backday Xebia : Akka, the reactive toolkit
Publicis Sapient Engineering
 
AngularJs
AngularJsAngularJs
AngularJs
syam kumar kk
 
JavaScript promise
JavaScript promiseJavaScript promise
JavaScript promise
eslam_me
 

What's hot (20)

Workshop 5: JavaScript testing
Workshop 5: JavaScript testingWorkshop 5: JavaScript testing
Workshop 5: JavaScript testing
 
Funcitonal Swift Conference: The Functional Way
Funcitonal Swift Conference: The Functional WayFuncitonal Swift Conference: The Functional Way
Funcitonal Swift Conference: The Functional Way
 
Protocol Oriented MVVM - Auckland iOS Meetup
Protocol Oriented MVVM - Auckland iOS MeetupProtocol Oriented MVVM - Auckland iOS Meetup
Protocol Oriented MVVM - Auckland iOS Meetup
 
Workshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScriptWorkshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScript
 
Angular2: Quick overview with 2do app example
Angular2: Quick overview with 2do app exampleAngular2: Quick overview with 2do app example
Angular2: Quick overview with 2do app example
 
Java Script Promise
Java Script PromiseJava Script Promise
Java Script Promise
 
N Things You Don't Want to Repeat in React Native
N Things You Don't Want to Repeat in React NativeN Things You Don't Want to Repeat in React Native
N Things You Don't Want to Repeat in React Native
 
Protocol-Oriented MVVM
Protocol-Oriented MVVMProtocol-Oriented MVVM
Protocol-Oriented MVVM
 
Vue next
Vue nextVue next
Vue next
 
Javascript And J Query
Javascript And J QueryJavascript And J Query
Javascript And J Query
 
Javascript Design Patterns
Javascript Design PatternsJavascript Design Patterns
Javascript Design Patterns
 
Protocol-Oriented MVVM (extended edition)
Protocol-Oriented MVVM (extended edition)Protocol-Oriented MVVM (extended edition)
Protocol-Oriented MVVM (extended edition)
 
Human Talks - StencilJS
Human Talks - StencilJSHuman Talks - StencilJS
Human Talks - StencilJS
 
The evolution of asynchronous javascript
The evolution of asynchronous javascriptThe evolution of asynchronous javascript
The evolution of asynchronous javascript
 
AngularJS Testing Strategies
AngularJS Testing StrategiesAngularJS Testing Strategies
AngularJS Testing Strategies
 
Func up your code
Func up your codeFunc up your code
Func up your code
 
Backday Xebia : Akka, the reactive toolkit
Backday Xebia : Akka, the reactive toolkitBackday Xebia : Akka, the reactive toolkit
Backday Xebia : Akka, the reactive toolkit
 
AngularJs
AngularJsAngularJs
AngularJs
 
Intro to JavaScript
Intro to JavaScriptIntro to JavaScript
Intro to JavaScript
 
JavaScript promise
JavaScript promiseJavaScript promise
JavaScript promise
 

Similar to Declarative presentations UIKonf

Reactive programming every day
Reactive programming every dayReactive programming every day
Reactive programming every day
Vadym Khondar
 
Windows Store app using XAML and C#: Enterprise Product Development
Windows Store app using XAML and C#: Enterprise Product Development Windows Store app using XAML and C#: Enterprise Product Development
Windows Store app using XAML and C#: Enterprise Product Development Mahmoud Hamed Mahmoud
 
An approach to responsive, realtime with Backbone.js and WebSockets
An approach to responsive, realtime with Backbone.js and WebSocketsAn approach to responsive, realtime with Backbone.js and WebSockets
An approach to responsive, realtime with Backbone.js and WebSockets
Andrei Sebastian Cîmpean
 
Angular 16 – the rise of Signals
Angular 16 – the rise of SignalsAngular 16 – the rise of Signals
Angular 16 – the rise of Signals
Coding Academy
 
Behavioral pattern 4
Behavioral pattern 4Behavioral pattern 4
Behavioral pattern 4
Naga Muruga
 
Java Svet - Communication Between Android App Components
Java Svet - Communication Between Android App ComponentsJava Svet - Communication Between Android App Components
Java Svet - Communication Between Android App Components
Aleksandar Ilić
 
Java Svet - Communication Between Android App Components
Java Svet - Communication Between Android App ComponentsJava Svet - Communication Between Android App Components
Java Svet - Communication Between Android App Components
PSTechSerbia
 
Building a js widget
Building a js widgetBuilding a js widget
Building a js widget
Tudor Barbu
 
Flutter State Management Using GetX.pdf
Flutter State Management Using GetX.pdfFlutter State Management Using GetX.pdf
Flutter State Management Using GetX.pdf
Katy Slemon
 
Adding a modern twist to legacy web applications
Adding a modern twist to legacy web applicationsAdding a modern twist to legacy web applications
Adding a modern twist to legacy web applications
Jeff Durta
 
Behavioral Design Patterns
Behavioral Design PatternsBehavioral Design Patterns
Behavioral Design Patterns
Lidan Hifi
 
Battle of React State Managers in frontend applications
Battle of React State Managers in frontend applicationsBattle of React State Managers in frontend applications
Battle of React State Managers in frontend applications
Evangelia Mitsopoulou
 
Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best PracticesYekmer Simsek
 
How to instantiate any view controller for free
How to instantiate any view controller for freeHow to instantiate any view controller for free
How to instantiate any view controller for free
BenotCaron
 
Inversion Of Control
Inversion Of ControlInversion Of Control
Inversion Of Control
Chad Hietala
 
Developing ASP.NET Applications Using the Model View Controller Pattern
Developing ASP.NET Applications Using the Model View Controller PatternDeveloping ASP.NET Applications Using the Model View Controller Pattern
Developing ASP.NET Applications Using the Model View Controller Pattern
goodfriday
 
[NDC 2019] Enterprise-Grade Serverless
[NDC 2019] Enterprise-Grade Serverless[NDC 2019] Enterprise-Grade Serverless
[NDC 2019] Enterprise-Grade Serverless
KatyShimizu
 
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
KatyShimizu
 

Similar to Declarative presentations UIKonf (20)

Reactive programming every day
Reactive programming every dayReactive programming every day
Reactive programming every day
 
Windows Store app using XAML and C#: Enterprise Product Development
Windows Store app using XAML and C#: Enterprise Product Development Windows Store app using XAML and C#: Enterprise Product Development
Windows Store app using XAML and C#: Enterprise Product Development
 
Jsf intro
Jsf introJsf intro
Jsf intro
 
An approach to responsive, realtime with Backbone.js and WebSockets
An approach to responsive, realtime with Backbone.js and WebSocketsAn approach to responsive, realtime with Backbone.js and WebSockets
An approach to responsive, realtime with Backbone.js and WebSockets
 
Rhino Mocks
Rhino MocksRhino Mocks
Rhino Mocks
 
Angular 16 – the rise of Signals
Angular 16 – the rise of SignalsAngular 16 – the rise of Signals
Angular 16 – the rise of Signals
 
Behavioral pattern 4
Behavioral pattern 4Behavioral pattern 4
Behavioral pattern 4
 
Java Svet - Communication Between Android App Components
Java Svet - Communication Between Android App ComponentsJava Svet - Communication Between Android App Components
Java Svet - Communication Between Android App Components
 
Java Svet - Communication Between Android App Components
Java Svet - Communication Between Android App ComponentsJava Svet - Communication Between Android App Components
Java Svet - Communication Between Android App Components
 
Building a js widget
Building a js widgetBuilding a js widget
Building a js widget
 
Flutter State Management Using GetX.pdf
Flutter State Management Using GetX.pdfFlutter State Management Using GetX.pdf
Flutter State Management Using GetX.pdf
 
Adding a modern twist to legacy web applications
Adding a modern twist to legacy web applicationsAdding a modern twist to legacy web applications
Adding a modern twist to legacy web applications
 
Behavioral Design Patterns
Behavioral Design PatternsBehavioral Design Patterns
Behavioral Design Patterns
 
Battle of React State Managers in frontend applications
Battle of React State Managers in frontend applicationsBattle of React State Managers in frontend applications
Battle of React State Managers in frontend applications
 
Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best Practices
 
How to instantiate any view controller for free
How to instantiate any view controller for freeHow to instantiate any view controller for free
How to instantiate any view controller for free
 
Inversion Of Control
Inversion Of ControlInversion Of Control
Inversion Of Control
 
Developing ASP.NET Applications Using the Model View Controller Pattern
Developing ASP.NET Applications Using the Model View Controller PatternDeveloping ASP.NET Applications Using the Model View Controller Pattern
Developing ASP.NET Applications Using the Model View Controller Pattern
 
[NDC 2019] Enterprise-Grade Serverless
[NDC 2019] Enterprise-Grade Serverless[NDC 2019] Enterprise-Grade Serverless
[NDC 2019] Enterprise-Grade Serverless
 
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
 

Declarative presentations UIKonf