Slide 1

Slide 1 text

A PORTAL FROM ELM TO SWIFT 1 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 2

Slide 2 text

GUIDO MARUCCI BLAS CO-FOUNDER & TECH LEAD AT WOLOX CTO AT SYRMO Twitter: @guidomb Blog: http://guidomb.blog GitHub: http://github.com/guidomb 2 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 3

Slide 3 text

3 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 4

Slide 4 text

4 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 5

Slide 5 text

A PORTAL FROM ELM TO SWIFT 5 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 6

Slide 6 text

6 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 7

Slide 7 text

7 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 8

Slide 8 text

8 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 9

Slide 9 text

9 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 10

Slide 10 text

GO BACK IN TIME ... 10 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 11

Slide 11 text

MODEL VIEW CONTROLLER 11 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 12

Slide 12 text

12 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 13

Slide 13 text

MVC - PROBLEMS > Massive fat controllers > Hard to test > Highly coupled > Lots of boilerplate 13 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 14

Slide 14 text

MVC - POSSIBLE SOLUTIONS > Extract business logic > Extract "side-effects" into services with protocols > Use dependency injection > Use notifications 14 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 15

Slide 15 text

MODEL VIEW PRESENTER 15 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 16

Slide 16 text

16 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 17

Slide 17 text

MVP - PROBLEMS > Way more boilerplate > Most of the problems / solutions from MVC still apply. 17 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 18

Slide 18 text

MODEL VIEW VIEWMODEL 18 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 19

Slide 19 text

19 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 20

Slide 20 text

20 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 21

Slide 21 text

MVVM - PROBLEMS > Requires a binding mechanisim > It's not clear who is responsable for view transitions > Forces you to use DI framework, singletons or propagate dependencies over the whole hierarchy 21 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 22

Slide 22 text

FUNCTIONAL REACTIVE PROGRAMMING 22 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 23

Slide 23 text

23 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 24

Slide 24 text

24 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 25

Slide 25 text

All this architectures still have the same problems 25 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 26

Slide 26 text

The application's state is spread over several components 26 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 27

Slide 27 text

Which means state is mutated all over the place 27 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 28

Slide 28 text

Which also means that if state needs to be shared, it must be kept in sync 28 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 29

Slide 29 text

Shared mutable state is the root of all EVIL 29 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 30

Slide 30 text

30 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 31

Slide 31 text

yes, there is more 31 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 32

Slide 32 text

The other big issue is how this architectures manage side- effects 32 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 33

Slide 33 text

What do we do next? 33 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 34

Slide 34 text

THE ELM ARCHITECTURE 34 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 35

Slide 35 text

35 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 36

Slide 36 text

36 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 37

Slide 37 text

but what about Swift? 37 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 38

Slide 38 text

GITHUB ReSwift/ReSwift BendingSpoons/katana-swift 38 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 39

Slide 39 text

If you want the full power of the Elm architecture you need ... 39 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 40

Slide 40 text

DECLARATIVES UI 40 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 41

Slide 41 text

But UIKit will make your life miserable 41 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 42

Slide 42 text

guidomb/PortalView 42 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 43

Slide 43 text

A (potentially) cross-platform, declarative and immutable Swift library for building user interfaces 43 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 44

Slide 44 text

100% written in Swift 44 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 45

Slide 45 text

The declarative API is NOT coupled to UIKit 45 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 46

Slide 46 text

facebook/yoga 46 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 47

Slide 47 text

enum Message { case like case goToDetailScreen } let component: Component = container( children: [ label( text: "Hello PortalView!", style: labelStyleSheet() { base, label in base.backgroundColor = .white label.textColor = .red label.textSize = 12 }, layout: layout() { $0.flex = flex() { $0.grow = .one } $0.justifyContent = .flexEnd } ) button( properties: properties() { $0.text = "Tap to like!" $0.onTap = .like } ) button( properties: properties() { $0.text = "Tap to got to detail screen" $0.onTap = .goToDetailScreen } ) ] ) 47 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 48

Slide 48 text

label( text: "Hello PortalView!", style: labelStyleSheet() { base, label in base.backgroundColor = .white label.textColor = .red label.textSize = 12 }, layout: layout() { $0.flex = flex() { $0.grow = .one } $0.justifyContent = .flexEnd } ) 48 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 49

Slide 49 text

button( properties: properties() { $0.text = "Tap to like!" $0.onTap = .like } ) 49 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 50

Slide 50 text

public indirect enum Component { case button(ButtonProperties, StyleSheet, Layout) case label(LabelProperties, StyleSheet, Layout) case mapView(MapProperties, StyleSheet, Layout) case imageView(Image, StyleSheet, Layout) case container([Component], StyleSheet, Layout) case table(TableProperties, StyleSheet, Layout) case collection(CollectionProperties, StyleSheet, Layout) case carousel(CarouselProperties, StyleSheet, Layout) case touchable(gesture: Gesture, child: Component) case segmented(ZipList>, StyleSheet, Layout) case progress(ProgressCounter, StyleSheet, Layout) case textField(TextFieldProperties, StyleSheet, Layout) case custom(componentIdentifier: String, layout: Layout) case spinner(Bool, StyleSheet, Layout) } 50 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 51

Slide 51 text

DEMO 51 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 52

Slide 52 text

but what about state management and side-effects? 52 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 53

Slide 53 text

guidomb/PortalApplication 53 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 54

Slide 54 text

public protocol Application { associatedtype MessageType associatedtype StateType associatedtype CommandType associatedtype RouteType: Route associatedtype SubscriptionType: Equatable associatedtype NavigatorType: Navigator var initialState: StateType { get } var initialRoute: RouteType { get } func translateRouteChange(from currentRoute: RouteType, to nextRoute: RouteType) -> MessageType? func update(state: StateType, message: MessageType) -> (StateType, CommandType?)? func view(for state: StateType) -> View func subscriptions(for state: StateType) -> [Subscription] } 54 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 55

Slide 55 text

public struct View { public typealias ActionType = Action public enum Content { case alert(properties: AlertProperties) case component(Component) } public let navigator: NavigatorType public let root: RootComponent public let content: Content } 55 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 56

Slide 56 text

public indirect enum Action { case dismissNavigator(thenSend: Action?) case navigateToPreviousRoute(preformTransition: Bool) case navigate(to: RouteType) case sendMessage(MessageType) } 56 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 57

Slide 57 text

public protocol Route: Equatable { var previous: Self? { get } } public protocol Navigator: Equatable { associatedtype RouteType: Route var baseRoute: RouteType { get } } 57 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 58

Slide 58 text

public protocol CommandExecutor { associatedtype CommandType associatedtype MessageType func execute(command: CommandType, dispatch: @escaping (MessageType) -> Void) } 58 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 59

Slide 59 text

import UIKit import PortalApplication import PortalView let context = UIKitApplicationContext( application: Voices(), commandExecutor: VoicesCommandExecutor(), subscriptionManager: VoicesSubscriptionManager(), customComponentRenderer: VoidCustomComponentRenderer() ) context.registerMiddleware(TimeLogger()) PortalUIApplication.start(applicationContext: context) { message in switch message { case .didFinishLaunching(_, _): return .applicationLaunched default: return .none } } 59 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 60

Slide 60 text

DEMO 60 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 61

Slide 61 text

guidomb/PortalView guidomb/PortalApplication guidomb/SyrmoPortalExample guidomb/Voices 61 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 62

Slide 62 text

PORTAL - WARNING > Still very early stage > API will probably change > Still needs important features like UI diffing 62 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 63

Slide 63 text

PORTAL - MILESTONES > API stability > Improve performance > Cool tooling, like hot UI reload > Server side rendering? > Android support 63 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 64

Slide 64 text

you are crazy, I cannot do a full rewrite of my massive application ... 64 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 65

Slide 65 text

you can add Portal gradually into your application or ... 65 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 66

Slide 66 text

Take the key concepts from this talk and apply them to your existing architecture 66 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 67

Slide 67 text

TL; DR; > Decouple side-effects froms logic by describing effects using values > Avoid state sincronization, have a central place where state is mutated > Avoid deep view / object hierarchy, prefer wide hierarchies 67 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 68

Slide 68 text

GUIDO MARUCCI BLAS Twitter: @guidomb Blog: http://guidomb.blog GitHub: http://github.com/guidomb 68 — A Portal from Elm to Swift by Guido Marucci Blas

Slide 69

Slide 69 text

THANKS! 69 — A Portal from Elm to Swift by Guido Marucci Blas