SlideShare uma empresa Scribd logo
1 de 52
MVVM with Kotlin:
Making iOS and Android apps as similar as possible
Malte Bucksch 1
Malte Bucksch 2
Goal: Sharing logic between native apps
Malte Bucksch 3
Agenda
I. The problem we’re solving
II. Comparison between architecture patterns
III. Our approach with MVVM
IV. How Kotlin helps us
V. Testing with MVVM
VI. Reusability of ViewModels
Malte Bucksch 4
Malte Bucksch 5
TEAM
Mixing business logic
and view logic
Testable
app architecture
Beautiful native UI
Awesome app Sharing logic between
Android and iOS
MVC: Model-View-Controller
Malte Bucksch 6
“Model View Controller (MVC) is one of the most
quoted (and most misquoted) patterns around”
– Martin Fowler (martinfowler.com)
Malte Bucksch 7
What is MVC after all?
Malte Bucksch 8
Wikipedia Apple Martin Fowler
Common practice
with MVC
Malte Bucksch 9
View View
ControllerFragment ViewController
MVVM: Model-View-ViewModel
Malte Bucksch 10
View View Model Model
Presentation
User Input
Business
Logic
Data
User action
Update
Update
Notify
Malte Bucksch 11
Data
View
ViewModel
Our approach with MVVM
• Platform-independent ViewModels
• Functional core using Input-to-Output mapping
Malte Bucksch 12
MVC
Malte Bucksch 13
View View
ControllerFragment ViewController
MVVM
Malte Bucksch 14
View
ViewModel
View
ViewModel
I have a dream today
Malte Bucksch 15
View
ViewModel
View
I have a dream today
Malte Bucksch 16
View
ViewModel
View
ViewModel
Let’s build a translation app
Malte Bucksch 17
Let’s build a translation app
Malte Bucksch 18
Deactivated
View Models
Malte Bucksch 19
View View Model
Inputs
Outputs
Malte Bucksch 20
ViewModel
Translate
Input
Output
Combine
with
german
text
Input
Output
f(input) = output
f(english) = german
Malte Bucksch 21
ViewModel Implementation Example
Malte Bucksch 22
ViewModel Implementation
Malte Bucksch 23
ReactiveX
RxJava / RxSwift
ViewModel Interface
24
interface TranslatorViewModelInput {
val englishText: BehaviorSubject<String>
val saveTrigger: PublishSubject<Unit>
}
interface TranslatorViewModelOutput {
val germanText: Observable<String>
val isSavingAllowed: Observable<Boolean>
val savedGermanTranslation: Observable<String>
}
interface TranslatorViewModel {
val input: TranslatorViewModelInput
val output: TranslatorViewModelOutput
}
class TranslatorViewModelImpl :
TranslatorViewModel,
TranslatorViewModelInput,
TranslatorViewModelOutput {
override val input = this
override val output = this
…
Usage
val viewModel: TranslatorViewModel =
createTranslatorViewModel()
viewModel.germanText
viewModel.englishText
viewModel.output.germanText
viewModel.input.englishText
ViewModel Implementation
Malte Bucksch 25
class TranslatorViewModelImpl : TranslatorViewModel, TranslatorViewModelInput, TranslatorViewModelOutput {
override val input = this
override val output = this
// *** inputs ***
override val englishText = BehaviorSubject.createDefault("")
override val saveTrigger = PublishSubject.create<Unit>()
// *** outputs ***
override val germanText = input.englishText
.map { TranslatorEngine.translateToGerman(it) }
override val isSavingAllowed = input.englishText
.map { !it.isEmpty() }
override val savedGermanTranslation =
input.saveTrigger.withLatestFrom(germanText)
.map { (_, german) -> german }
}
Binding to ViewModels via Kotlin Fragment
Malte Bucksch 26
// *** supply inputs ***
viewModel.input.englishText.receiveTextChangesFrom(englishInputEditText)
viewModel.input.saveTrigger.receiveClicksFrom(saveTextButton)
// *** subscribe to outputs ***
viewModel.output.germanText
.subscribe { germanOutputTextView.text = it }
viewModel.output.isSavingAllowed
.subscribe { saveTextButton.isEnabled = it }
viewModel.output.savedGermanTranslation
.subscribe { germanText ->
showMessage("Saved to clipboard")
germanText.saveToClipboard()
}
How Kotlin helps us
Malte Bucksch 27
Kotlin and Swift are very similar
Malte Bucksch 28
Shared Kotlin/Swift Features
• Optionals
• String Interpolation
• Extension functions
• Functional operations for lists/arrays
• Type inference
• Lambdas
• Type alias
• …
Malte Bucksch 29
Kotlin vs. Swift: Variables and constants
Malte Bucksch 30
var myVariable = 42
myVariable = 50
let myConstant = 42
var myVariable = 42
myVariable = 50
val myConstant = 42
Kotlin vs. Swift: String interpolation
Malte Bucksch 31
let apples = 3
let oranges = 5
let fruitSummary = "I have (apples + oranges) " + "pieces of fruit."
val apples = 3
val oranges = 5
val fruitSummary = "I have ${apples + oranges} " + "pieces of fruit."
Kotlin vs. Swift: Maps
Malte Bucksch 32
val occupations = mutableMapOf( "Malcolm" to "Captain",
"Kaylee" to "Mechanic")
occupations["Jayne"] = "Public Relations"
var occupations = [ "Malcolm": "Captain",
"Kaylee": "Mechanic"]
occupations["Jayne"] = "Public Relations"
Kotlin vs Swift ViewModel
Malte Bucksch 33
interface TranslatorViewModelInput {
val englishText: BehaviorSubject<String>
val saveTrigger: PublishSubject<Unit>
}
interface TranslatorViewModelOutput {
val germanText: Observable<String>
val isSavingAllowed: Observable<Boolean>
val savedGermanTranslation: Observable<String>
}
interface TranslatorViewModel {
val input: TranslatorViewModelInput
val output: TranslatorViewModelOutput
}
protocol TranslatorViewModelInput {
var englishText: BehaviorSubject<String> { get }
var saveTrigger: PublishSubject<Void> { get }
}
protocol TranslatorViewModelOutput {
var germanText: Observable<String> { get }
var isSavingAllowed: Observable<Bool> { get }
var saveGermanTranslation: Observable<String> { get }
}
protocol TranslatorViewModel {
var input: TranslatorViewModelInput { get }
var output: TranslatorViewModelOutput { get }
}
Kotlin vs Swift ViewModel
Malte Bucksch 34
class TranslatorViewModelImpl:
TranslatorViewModel,
TranslatorViewModelInput,
TranslatorViewModelOutput {
var input: TranslatorViewModelInput { return self }
var output: TranslatorViewModelOutput { return self }
// MARK: - Inputs
var englishText = BehaviourSubject<String>(value: "")
var saveTrigger = PublishSubject<Void>()
…
class TranslatorViewModelImpl:
TranslatorViewModel,
TranslatorViewModelInput,
TranslatorViewModelOutput {
override val input = this
override val output = this
// *** inputs ***
override val englishText =
BehaviorSubject.createDefault("")
override val saveTrigger =
PublishSubject.create<Unit>()
…
Kotlin vs Swift ViewModel
Malte Bucksch 35
…
// MARK: - Outputs
lazy var germanText: Observable<String> = {
input.englishText
.map { TranslatorEngine.translateToGerman($0) }
}()
lazy var isSavingAllowed: Observable<Bool> = {
input.englishText
.map { $0.isEmpty }
}()
…
// *** outputs ***
override val germanText = input.englishText
.map { TranslatorEngine.translateToGerman(it) }
override val isSavingAllowed = input.englishText
.map { !it.isEmpty() }
override val savedGermanTranslation =
input.saveTrigger.withLatestFrom(germanText)
.map { (_, german) -> german }
Testing ViewModels
Malte Bucksch 36
View Model Tests
Malte Bucksch 37
View View Model
Input
Output
View Model Tests
Malte Bucksch 38
Unit Test View Model
Input
Output
ViewModel Tests
Malte Bucksch 39
@Test
fun testTranslation() {
val viewModel: TranslatorViewModel = TranslatorViewModelImpl()
viewModel.input.englishText.onNext("Dog")
viewModel.output.germanText.test().assertValue("Hund")
}
Local unit tests for UI testing
Malte Bucksch 40
Fast local unit tests Avoid UI testing frameworks
ViewModel reusability
Malte Bucksch 41
ViewModel reusability
Malte Bucksch 42
Android View View Model
Input
Output
ViewModel reusability
Malte Bucksch 43
Android Fragment View Model
Input
Output
ViewModel reusability
Malte Bucksch 44
Unit Test View Model
Input
Output
ViewModel reusability
Malte Bucksch 45
JavaFX View View Model
Input
Output
ViewModel reusability
Malte Bucksch 46
Java/Kotlin REST API View Model
Input
Output
ViewModel reusability
Malte Bucksch 47
Kotlinx (HTML) View View Model
Input
Output
One ViewModel to rule them all
Malte Bucksch 48
Wrap up
Advantages
• Logic can be reused within iOS and Android
• Functional way of writing UI with isolated side effects
• Great testability
Malte Bucksch 49
Wrap up
Advantages
• Logic can be reused within iOS and Android
• Functional way of writing UI with isolated side effects
• Great testability
Disadvantages
• Boiler plate for interfaces
• Steep learning curve
• Less intuitive if programmer is not used to functional-style programming
Malte Bucksch 50
Wrap up
Improvement points
• Optimize project workflow to make people reuse code
• Write ViewModels in exact same programming language
Malte Bucksch 51
Questions?
More resources on MVVM
https://github.com/quickbirdstudios
https://github.com/kickstarter/android-oss
https://github.com/kickstarter/ios-oss
https://bit.ly/2qSFPqO (Talk at UI Konf about Swift/Kotlin similarity)
malte@quickbirdstudios.com
Malte Bucksch 52

Mais conteúdo relacionado

Mais procurados

Railway Orientated Programming In C#
Railway Orientated Programming In C#Railway Orientated Programming In C#
Railway Orientated Programming In C#Tama000
 
Beginner’s tutorial (part 1) integrate redux form in react native application
Beginner’s tutorial (part 1) integrate redux form in react native applicationBeginner’s tutorial (part 1) integrate redux form in react native application
Beginner’s tutorial (part 1) integrate redux form in react native applicationKaty Slemon
 
Silverlight 2 for Developers - TechEd New Zealand 2008
Silverlight 2 for Developers - TechEd New Zealand 2008Silverlight 2 for Developers - TechEd New Zealand 2008
Silverlight 2 for Developers - TechEd New Zealand 2008Jonas Follesø
 
379008-rc217-functionalprogramming
379008-rc217-functionalprogramming379008-rc217-functionalprogramming
379008-rc217-functionalprogrammingLuis Atencio
 
Asp.net mvc training
Asp.net mvc trainingAsp.net mvc training
Asp.net mvc trainingicubesystem
 
Angular Mini Hackathon Code Talks 2019
Angular Mini Hackathon Code Talks 2019Angular Mini Hackathon Code Talks 2019
Angular Mini Hackathon Code Talks 2019Maximilian Berghoff
 
General structure of c++
General structure of c++General structure of c++
General structure of c++Ajay Chimmani
 
08. session 08 intoduction to javascript
08. session 08   intoduction to javascript08. session 08   intoduction to javascript
08. session 08 intoduction to javascriptPhúc Đỗ
 

Mais procurados (12)

Railway Orientated Programming In C#
Railway Orientated Programming In C#Railway Orientated Programming In C#
Railway Orientated Programming In C#
 
Beginner’s tutorial (part 1) integrate redux form in react native application
Beginner’s tutorial (part 1) integrate redux form in react native applicationBeginner’s tutorial (part 1) integrate redux form in react native application
Beginner’s tutorial (part 1) integrate redux form in react native application
 
Silverlight 2 for Developers - TechEd New Zealand 2008
Silverlight 2 for Developers - TechEd New Zealand 2008Silverlight 2 for Developers - TechEd New Zealand 2008
Silverlight 2 for Developers - TechEd New Zealand 2008
 
379008-rc217-functionalprogramming
379008-rc217-functionalprogramming379008-rc217-functionalprogramming
379008-rc217-functionalprogramming
 
Client sidescripting javascript
Client sidescripting javascriptClient sidescripting javascript
Client sidescripting javascript
 
Fp201 unit2 1
Fp201 unit2 1Fp201 unit2 1
Fp201 unit2 1
 
Asp.net mvc training
Asp.net mvc trainingAsp.net mvc training
Asp.net mvc training
 
Angular Mini Hackathon Code Talks 2019
Angular Mini Hackathon Code Talks 2019Angular Mini Hackathon Code Talks 2019
Angular Mini Hackathon Code Talks 2019
 
General structure of c++
General structure of c++General structure of c++
General structure of c++
 
08. session 08 intoduction to javascript
08. session 08   intoduction to javascript08. session 08   intoduction to javascript
08. session 08 intoduction to javascript
 
Function
FunctionFunction
Function
 
Angular 2.0 - What to expect
Angular 2.0 - What to expectAngular 2.0 - What to expect
Angular 2.0 - What to expect
 

Semelhante a MVVM with Kotlin: Making iOS and Android apps as similar as possible

How to build to do app using vue composition api and vuex 4 with typescript
How to build to do app using vue composition api and vuex 4 with typescriptHow to build to do app using vue composition api and vuex 4 with typescript
How to build to do app using vue composition api and vuex 4 with typescriptKaty Slemon
 
How to create an Angular builder
How to create an Angular builderHow to create an Angular builder
How to create an Angular builderMaurizio Vitale
 
Part II: LLVM Intermediate Representation
Part II: LLVM Intermediate RepresentationPart II: LLVM Intermediate Representation
Part II: LLVM Intermediate RepresentationWei-Ren Chen
 
Multiplatform shared codebase with Kotlin/Native - UA Mobile 2019
Multiplatform shared codebase with Kotlin/Native - UA Mobile 2019Multiplatform shared codebase with Kotlin/Native - UA Mobile 2019
Multiplatform shared codebase with Kotlin/Native - UA Mobile 2019Eugene Kurko
 
Multiplatform shared codebase with Kotlin/Native - UA Mobile 2019
Multiplatform shared codebase with Kotlin/Native - UA Mobile 2019Multiplatform shared codebase with Kotlin/Native - UA Mobile 2019
Multiplatform shared codebase with Kotlin/Native - UA Mobile 2019UA Mobile
 
MEF Deep Dive by Piotr Wlodek
MEF Deep Dive by Piotr WlodekMEF Deep Dive by Piotr Wlodek
MEF Deep Dive by Piotr Wlodekinfusiondev
 
Compose Camp Day 3 PPT.pptx.pdf
Compose Camp Day 3 PPT.pptx.pdfCompose Camp Day 3 PPT.pptx.pdf
Compose Camp Day 3 PPT.pptx.pdfMETDSC
 
Why Spring <3 Kotlin
Why Spring <3 KotlinWhy Spring <3 Kotlin
Why Spring <3 KotlinVMware Tanzu
 
In-Depth Model/View with QML
In-Depth Model/View with QMLIn-Depth Model/View with QML
In-Depth Model/View with QMLICS
 
Net conf BG xamarin lecture
Net conf BG xamarin lectureNet conf BG xamarin lecture
Net conf BG xamarin lectureTsvyatko Konov
 
Ekon25 mORMot 2 Server-Side Notifications
Ekon25 mORMot 2 Server-Side NotificationsEkon25 mORMot 2 Server-Side Notifications
Ekon25 mORMot 2 Server-Side NotificationsArnaud Bouchez
 
Real-world Model-View-ViewModel for WPF
Real-world Model-View-ViewModel for WPFReal-world Model-View-ViewModel for WPF
Real-world Model-View-ViewModel for WPFPaul Stovell
 
Functionnal view modelling
Functionnal view modelling Functionnal view modelling
Functionnal view modelling Hugo Saynac
 
La programmation concurrente par flux de données
La programmation concurrente par flux de donnéesLa programmation concurrente par flux de données
La programmation concurrente par flux de donnéesMicrosoft
 
Protocol-Oriented MVVM (extended edition)
Protocol-Oriented MVVM (extended edition)Protocol-Oriented MVVM (extended edition)
Protocol-Oriented MVVM (extended edition)Natasha Murashev
 
An Introductory course on Verilog HDL-Verilog hdl ppr
An Introductory course on Verilog HDL-Verilog hdl pprAn Introductory course on Verilog HDL-Verilog hdl ppr
An Introductory course on Verilog HDL-Verilog hdl pprPrabhavathi P
 
using Mithril.js + postgREST to build and consume API's
using Mithril.js + postgREST to build and consume API'susing Mithril.js + postgREST to build and consume API's
using Mithril.js + postgREST to build and consume API'sAntônio Roberto Silva
 

Semelhante a MVVM with Kotlin: Making iOS and Android apps as similar as possible (20)

iOS
iOSiOS
iOS
 
Compose in Theory
Compose in TheoryCompose in Theory
Compose in Theory
 
How to build to do app using vue composition api and vuex 4 with typescript
How to build to do app using vue composition api and vuex 4 with typescriptHow to build to do app using vue composition api and vuex 4 with typescript
How to build to do app using vue composition api and vuex 4 with typescript
 
How to create an Angular builder
How to create an Angular builderHow to create an Angular builder
How to create an Angular builder
 
Part II: LLVM Intermediate Representation
Part II: LLVM Intermediate RepresentationPart II: LLVM Intermediate Representation
Part II: LLVM Intermediate Representation
 
Multiplatform shared codebase with Kotlin/Native - UA Mobile 2019
Multiplatform shared codebase with Kotlin/Native - UA Mobile 2019Multiplatform shared codebase with Kotlin/Native - UA Mobile 2019
Multiplatform shared codebase with Kotlin/Native - UA Mobile 2019
 
Multiplatform shared codebase with Kotlin/Native - UA Mobile 2019
Multiplatform shared codebase with Kotlin/Native - UA Mobile 2019Multiplatform shared codebase with Kotlin/Native - UA Mobile 2019
Multiplatform shared codebase with Kotlin/Native - UA Mobile 2019
 
MEF Deep Dive by Piotr Wlodek
MEF Deep Dive by Piotr WlodekMEF Deep Dive by Piotr Wlodek
MEF Deep Dive by Piotr Wlodek
 
Compose Camp Day 3 PPT.pptx.pdf
Compose Camp Day 3 PPT.pptx.pdfCompose Camp Day 3 PPT.pptx.pdf
Compose Camp Day 3 PPT.pptx.pdf
 
Why Spring <3 Kotlin
Why Spring <3 KotlinWhy Spring <3 Kotlin
Why Spring <3 Kotlin
 
In-Depth Model/View with QML
In-Depth Model/View with QMLIn-Depth Model/View with QML
In-Depth Model/View with QML
 
Net conf BG xamarin lecture
Net conf BG xamarin lectureNet conf BG xamarin lecture
Net conf BG xamarin lecture
 
Ekon25 mORMot 2 Server-Side Notifications
Ekon25 mORMot 2 Server-Side NotificationsEkon25 mORMot 2 Server-Side Notifications
Ekon25 mORMot 2 Server-Side Notifications
 
Real-world Model-View-ViewModel for WPF
Real-world Model-View-ViewModel for WPFReal-world Model-View-ViewModel for WPF
Real-world Model-View-ViewModel for WPF
 
Functionnal view modelling
Functionnal view modelling Functionnal view modelling
Functionnal view modelling
 
La programmation concurrente par flux de données
La programmation concurrente par flux de donnéesLa programmation concurrente par flux de données
La programmation concurrente par flux de données
 
iOS_Presentation
iOS_PresentationiOS_Presentation
iOS_Presentation
 
Protocol-Oriented MVVM (extended edition)
Protocol-Oriented MVVM (extended edition)Protocol-Oriented MVVM (extended edition)
Protocol-Oriented MVVM (extended edition)
 
An Introductory course on Verilog HDL-Verilog hdl ppr
An Introductory course on Verilog HDL-Verilog hdl pprAn Introductory course on Verilog HDL-Verilog hdl ppr
An Introductory course on Verilog HDL-Verilog hdl ppr
 
using Mithril.js + postgREST to build and consume API's
using Mithril.js + postgREST to build and consume API'susing Mithril.js + postgREST to build and consume API's
using Mithril.js + postgREST to build and consume API's
 

Último

The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is insideshinachiaurasa2
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnAmarnathKambale
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfkalichargn70th171
 
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareJim McKeeth
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...masabamasaba
 
tonesoftg
tonesoftgtonesoftg
tonesoftglanshi9
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024VictoriaMetrics
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfonteinmasabamasaba
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...Health
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesVictorSzoltysek
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...masabamasaba
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Bert Jan Schrijver
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrandmasabamasaba
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionOnePlan Solutions
 

Último (20)

The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
 
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
 
tonesoftg
tonesoftgtonesoftg
tonesoftg
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 

MVVM with Kotlin: Making iOS and Android apps as similar as possible

  • 1. MVVM with Kotlin: Making iOS and Android apps as similar as possible Malte Bucksch 1
  • 3. Goal: Sharing logic between native apps Malte Bucksch 3
  • 4. Agenda I. The problem we’re solving II. Comparison between architecture patterns III. Our approach with MVVM IV. How Kotlin helps us V. Testing with MVVM VI. Reusability of ViewModels Malte Bucksch 4
  • 5. Malte Bucksch 5 TEAM Mixing business logic and view logic Testable app architecture Beautiful native UI Awesome app Sharing logic between Android and iOS
  • 7. “Model View Controller (MVC) is one of the most quoted (and most misquoted) patterns around” – Martin Fowler (martinfowler.com) Malte Bucksch 7
  • 8. What is MVC after all? Malte Bucksch 8 Wikipedia Apple Martin Fowler
  • 9. Common practice with MVC Malte Bucksch 9 View View ControllerFragment ViewController
  • 10. MVVM: Model-View-ViewModel Malte Bucksch 10 View View Model Model Presentation User Input Business Logic Data User action Update Update Notify
  • 12. Our approach with MVVM • Platform-independent ViewModels • Functional core using Input-to-Output mapping Malte Bucksch 12
  • 13. MVC Malte Bucksch 13 View View ControllerFragment ViewController
  • 15. I have a dream today Malte Bucksch 15 View ViewModel View
  • 16. I have a dream today Malte Bucksch 16 View ViewModel View ViewModel
  • 17. Let’s build a translation app Malte Bucksch 17
  • 18. Let’s build a translation app Malte Bucksch 18 Deactivated
  • 19. View Models Malte Bucksch 19 View View Model Inputs Outputs
  • 21. f(input) = output f(english) = german Malte Bucksch 21
  • 23. ViewModel Implementation Malte Bucksch 23 ReactiveX RxJava / RxSwift
  • 24. ViewModel Interface 24 interface TranslatorViewModelInput { val englishText: BehaviorSubject<String> val saveTrigger: PublishSubject<Unit> } interface TranslatorViewModelOutput { val germanText: Observable<String> val isSavingAllowed: Observable<Boolean> val savedGermanTranslation: Observable<String> } interface TranslatorViewModel { val input: TranslatorViewModelInput val output: TranslatorViewModelOutput } class TranslatorViewModelImpl : TranslatorViewModel, TranslatorViewModelInput, TranslatorViewModelOutput { override val input = this override val output = this … Usage val viewModel: TranslatorViewModel = createTranslatorViewModel() viewModel.germanText viewModel.englishText viewModel.output.germanText viewModel.input.englishText
  • 25. ViewModel Implementation Malte Bucksch 25 class TranslatorViewModelImpl : TranslatorViewModel, TranslatorViewModelInput, TranslatorViewModelOutput { override val input = this override val output = this // *** inputs *** override val englishText = BehaviorSubject.createDefault("") override val saveTrigger = PublishSubject.create<Unit>() // *** outputs *** override val germanText = input.englishText .map { TranslatorEngine.translateToGerman(it) } override val isSavingAllowed = input.englishText .map { !it.isEmpty() } override val savedGermanTranslation = input.saveTrigger.withLatestFrom(germanText) .map { (_, german) -> german } }
  • 26. Binding to ViewModels via Kotlin Fragment Malte Bucksch 26 // *** supply inputs *** viewModel.input.englishText.receiveTextChangesFrom(englishInputEditText) viewModel.input.saveTrigger.receiveClicksFrom(saveTextButton) // *** subscribe to outputs *** viewModel.output.germanText .subscribe { germanOutputTextView.text = it } viewModel.output.isSavingAllowed .subscribe { saveTextButton.isEnabled = it } viewModel.output.savedGermanTranslation .subscribe { germanText -> showMessage("Saved to clipboard") germanText.saveToClipboard() }
  • 27. How Kotlin helps us Malte Bucksch 27
  • 28. Kotlin and Swift are very similar Malte Bucksch 28
  • 29. Shared Kotlin/Swift Features • Optionals • String Interpolation • Extension functions • Functional operations for lists/arrays • Type inference • Lambdas • Type alias • … Malte Bucksch 29
  • 30. Kotlin vs. Swift: Variables and constants Malte Bucksch 30 var myVariable = 42 myVariable = 50 let myConstant = 42 var myVariable = 42 myVariable = 50 val myConstant = 42
  • 31. Kotlin vs. Swift: String interpolation Malte Bucksch 31 let apples = 3 let oranges = 5 let fruitSummary = "I have (apples + oranges) " + "pieces of fruit." val apples = 3 val oranges = 5 val fruitSummary = "I have ${apples + oranges} " + "pieces of fruit."
  • 32. Kotlin vs. Swift: Maps Malte Bucksch 32 val occupations = mutableMapOf( "Malcolm" to "Captain", "Kaylee" to "Mechanic") occupations["Jayne"] = "Public Relations" var occupations = [ "Malcolm": "Captain", "Kaylee": "Mechanic"] occupations["Jayne"] = "Public Relations"
  • 33. Kotlin vs Swift ViewModel Malte Bucksch 33 interface TranslatorViewModelInput { val englishText: BehaviorSubject<String> val saveTrigger: PublishSubject<Unit> } interface TranslatorViewModelOutput { val germanText: Observable<String> val isSavingAllowed: Observable<Boolean> val savedGermanTranslation: Observable<String> } interface TranslatorViewModel { val input: TranslatorViewModelInput val output: TranslatorViewModelOutput } protocol TranslatorViewModelInput { var englishText: BehaviorSubject<String> { get } var saveTrigger: PublishSubject<Void> { get } } protocol TranslatorViewModelOutput { var germanText: Observable<String> { get } var isSavingAllowed: Observable<Bool> { get } var saveGermanTranslation: Observable<String> { get } } protocol TranslatorViewModel { var input: TranslatorViewModelInput { get } var output: TranslatorViewModelOutput { get } }
  • 34. Kotlin vs Swift ViewModel Malte Bucksch 34 class TranslatorViewModelImpl: TranslatorViewModel, TranslatorViewModelInput, TranslatorViewModelOutput { var input: TranslatorViewModelInput { return self } var output: TranslatorViewModelOutput { return self } // MARK: - Inputs var englishText = BehaviourSubject<String>(value: "") var saveTrigger = PublishSubject<Void>() … class TranslatorViewModelImpl: TranslatorViewModel, TranslatorViewModelInput, TranslatorViewModelOutput { override val input = this override val output = this // *** inputs *** override val englishText = BehaviorSubject.createDefault("") override val saveTrigger = PublishSubject.create<Unit>() …
  • 35. Kotlin vs Swift ViewModel Malte Bucksch 35 … // MARK: - Outputs lazy var germanText: Observable<String> = { input.englishText .map { TranslatorEngine.translateToGerman($0) } }() lazy var isSavingAllowed: Observable<Bool> = { input.englishText .map { $0.isEmpty } }() … // *** outputs *** override val germanText = input.englishText .map { TranslatorEngine.translateToGerman(it) } override val isSavingAllowed = input.englishText .map { !it.isEmpty() } override val savedGermanTranslation = input.saveTrigger.withLatestFrom(germanText) .map { (_, german) -> german }
  • 37. View Model Tests Malte Bucksch 37 View View Model Input Output
  • 38. View Model Tests Malte Bucksch 38 Unit Test View Model Input Output
  • 39. ViewModel Tests Malte Bucksch 39 @Test fun testTranslation() { val viewModel: TranslatorViewModel = TranslatorViewModelImpl() viewModel.input.englishText.onNext("Dog") viewModel.output.germanText.test().assertValue("Hund") }
  • 40. Local unit tests for UI testing Malte Bucksch 40 Fast local unit tests Avoid UI testing frameworks
  • 42. ViewModel reusability Malte Bucksch 42 Android View View Model Input Output
  • 43. ViewModel reusability Malte Bucksch 43 Android Fragment View Model Input Output
  • 44. ViewModel reusability Malte Bucksch 44 Unit Test View Model Input Output
  • 45. ViewModel reusability Malte Bucksch 45 JavaFX View View Model Input Output
  • 46. ViewModel reusability Malte Bucksch 46 Java/Kotlin REST API View Model Input Output
  • 47. ViewModel reusability Malte Bucksch 47 Kotlinx (HTML) View View Model Input Output
  • 48. One ViewModel to rule them all Malte Bucksch 48
  • 49. Wrap up Advantages • Logic can be reused within iOS and Android • Functional way of writing UI with isolated side effects • Great testability Malte Bucksch 49
  • 50. Wrap up Advantages • Logic can be reused within iOS and Android • Functional way of writing UI with isolated side effects • Great testability Disadvantages • Boiler plate for interfaces • Steep learning curve • Less intuitive if programmer is not used to functional-style programming Malte Bucksch 50
  • 51. Wrap up Improvement points • Optimize project workflow to make people reuse code • Write ViewModels in exact same programming language Malte Bucksch 51
  • 52. Questions? More resources on MVVM https://github.com/quickbirdstudios https://github.com/kickstarter/android-oss https://github.com/kickstarter/ios-oss https://bit.ly/2qSFPqO (Talk at UI Konf about Swift/Kotlin similarity) malte@quickbirdstudios.com Malte Bucksch 52

Notas do Editor

  1. No side effects Same input always same output