SlideShare uma empresa Scribd logo
1 de 105
Baixar para ler offline
@fabioCollini
Fabio Collini
Architectures in the
Compose World
Architecture
State
UI
state event
https://developer.android.com/jetpack/compose/architecture
https://developer.android.com/jetpack/compose/architecture
State
UI
state event
State
UI
state event
State
Composable
state event
ViewModel
Composable
state event
ViewModel
Composable
UseCase
state event
ViewModel
Composable
UseCase
Repository
state event
ViewModel
Composable
UseCase
Repository
state event
source of truth
ViewModel
Composable
UseCase
Repository
state event
state event
source of truth
ViewModel
Composable
UseCase
Repository
state event
state event
state event
source of truth
MVVM / MVI
MVVM
/
MVI
Both MVVM and MVI are
unidirectional data
fl
ow
architectures
MVVM
The ViewModel accepts
events and exposes the
state
MVI
The state is a single
immutable object
MVI
The state is a single
immutable object


The events are managed
using a
fl
ow
UI = f(state)
UI = f(state)
always
UI = f(state)
always


most of the times
https://medium.com/androiddevelopers/livedata-with-snackbar-navigation-and-other-events-the-singleliveevent-case-ac2622673150
https://proandroiddev.com/android-singleliveevent-redux-with-kotlin-
fl
ow-b755c70bb055
SingleLiveEvent


SharedFlow


Channel


State + LaunchedEffect
SingleLiveEvent


SharedFlow


Channel


State + LaunchedEffect


Lots of edge cases :(


Not an of
fi
cial solution yet
State
MVI
The state is a single
immutable object
data class State(

val notes: List<Note>,

/
/
.
.
.


)
data class State(

val notes: List<Note>,

/
/
.
.
.


)

data class Note(

val id: Int,

val title: String,

val checked: Boolean

)
@Composable

fun Notes(state: State, onCheckedChange: (Note)
-
>
Unit) {

/
/
.
.
.


}
Notes(

state = state,

onCheckedChange = { noteToToggle
-
>


state = state.copy(

notes = state.notes

.map { note
-
>


if (note.id
=
=
noteToToggle.id) {

note.copy(checked = !note.checked)

} else {

note

}

}

)

}

)
Notes(

state = state,

onCheckedChange = { noteToToggle
-
>


state = state.copy(

notes = state.notes

.map { note
-
>


if (note.id
=
=
noteToToggle.id) {

note.copy(checked = !note.checked)

} else {

note

}

}

)

}

)
data class Note(

val id: Int,

val title: String,

val checked: Boolean

)
data class Note(

val id: Int,

val title: String,

var checked: Boolean

)_
data class Note(

val id: Int,

val title: String,

var checked: Boolean

)_

Notes(

state = state,

onCheckedChange = { noteToToggle
-
>


state = state.copy(

notes = state.notes

.map { note
-
>


if (note.id
=
=
noteToToggle.id) {

note.copy(checked = !note.checked)

} else {

note

}

}

)

}

)
data class Note(

val id: Int,

val title: String,

var checked: Boolean

)

Notes(

state = state,

onCheckedChange = { noteToToggle
-
>


noteToToggle.checked = !noteToToggle.checked

}

)
Not
so
easy…
https://developer.android.com/reference/kotlin/androidx/compose/runtime/Immutable
https://developer.android.com/reference/kotlin/androidx/compose/runtime/Stable
data class Note(

val id: Int,

val title: String,

var checked: Boolean

)

Notes(

state = state,

onCheckedChange = { noteToToggle
-
>


noteToToggle.checked = !noteToToggle.checked

}

)
data class Note(

val id: Int,

val title: String,

) {

var checked: Boolean by mutableStateOf(false)

}

Notes(

state = state,

onCheckedChange = { noteToToggle
-
>


noteToToggle.checked = !noteToToggle.checked

}

)
Composable
Xml
fi
les Composables
Xml
fi
les


Custom Views
Composables
Xml
fi
les


Custom Views


Fragments
Composables
Xml
fi
les


Custom Views


Fragments


Activities
Composables
Xml
fi
les Composables
Xml
fi
les
Composables


with


state hoisting
Custom Views Composables
Custom Views
Composables


with


remember /


rememberSavable
Fragments


Activities
Composables
Fragments


Activities
Screens


with


ViewModel
Fragments


Activities
Screens


with


ViewModel
Composables


with


remember /


rememberSavable
Custom Views
Composables


with


state hoisting
Xml
fi
les
Screen
class MyFragment : Fragment() {

override fun onCreateView(
.
.
.
) = 

ComposeView(requireContext()).apply {

setContent {

MyScreen()

}

}

}
class MyFragment : Fragment() {

override fun onCreateView(
.
.
.
) = 

ComposeView(requireContext()).apply {

setContent {

MyScreen()

}
_
_


}_

}

@Composable

fun MyScreen() {

/
/
.
.
.


}
class MyFragment : Fragment() {

override fun onCreateView(
.
.
.
) = 

ComposeView(requireContext()).apply {

viewLifecycleOwner.lifecycleScope.launch {

/
/
.
.
.


}

setContent {

MyScreen()

}
_
_


}_

}

@Composable

fun MyScreen() {

/
/
.
.
.


}
class MyFragment : Fragment() {

override fun onCreateView(
.
.
.
) = 

ComposeView(requireContext()).apply {

viewLifecycleOwner.lifecycleScope.launch {

/
/
.
.
.


}

setContent {

MyScreen()

}

}

}

@Composable

fun MyScreen() {

/
/
.
.
.


val scope = rememberCoroutineScope()

}
class MyFragment : Fragment() {

override fun onCreateView(
.
.
.
) = 

ComposeView(requireContext()).apply {

viewLifecycleOwner.lifecycleScope.launch {

/
/
.
.
.


}

setContent {

MyScreen()

}

}

}

@Composable

fun MyScreen() {

/
/
.
.
.


val scope = rememberCoroutineScope()

LaunchedEffect("
.
.
.
") {

/
/
.
.
.


}

}
https://developer.android.com/jetpack/compose/lifecycle
https://developer.android.com/jetpack/compose/lifecycle
@Singleton

class MyClass @Inject constructor() {

/
/
.
.
.


}
@Singleton

class MyClass @Inject constructor() {

/
/
.
.
.


}

@AndroidEntryPoint

class MyFragment : Fragment() {

@Inject

lateinit var myInstance: MyClass

/
/
.
.
.


}
@Singleton

class MyClass @Inject constructor() {

/
/
.
.
.


}
@Singleton

class MyClass @Inject constructor() {

/
/
.
.
.


}

@InstallIn(SingletonComponent
:
:
class)

@EntryPoint

interface MyEntryPoint {

val myInstance: MyClass

}
@Composable

inline fun <reified T : Any> rememberSingletonEntryPoint(): T {

val context = LocalContext.current

return remember {

EntryPointAccessors.fromApplication(context, T
:
:
class.java)

}

}
@Singleton

class MyClass @Inject constructor() {

/
/
.
.
.


}

@InstallIn(SingletonComponent
:
:
class)

@EntryPoint

interface MyEntryPoint {

val myInstance: MyClass

}
@Singleton

class MyClass @Inject constructor() {

/
/
.
.
.


}

@InstallIn(SingletonComponent
:
:
class)

@EntryPoint

interface MyEntryPoint {

val myInstance: MyClass

}

@Composable

fun MyScreen() {

val entryPoint = rememberSingletonEntryPoint<MyEntryPoint>()

val myInstance = entryPoint.myInstance

}
@ActivityScoped

class MyClass @Inject constructor() {

/
/
.
.
.


}

@InstallIn(ActivityComponent
:
:
class)

@EntryPoint

interface MyEntryPoint {

val myInstance: MyClass

}

@Composable

fun MyScreen() {

val entryPoint = rememberActivityEntryPoint<MyEntryPoint>()

val myInstance = entryPoint.myInstance

}
@ComposableScoped

class MyClass @Inject constructor() {

/
/
.
.
.


}

@InstallIn(ActivityComponent
:
:
class)

@EntryPoint

interface MyEntryPoint {

val myInstance: MyClass

}

@Composable

fun MyScreen() {

val entryPoint = rememberActivityEntryPoint<MyEntryPoint>()

val myInstance = entryPoint.myInstance

}
@ComposableScoped
@Scope

annotation class ComposableScoped
@Scope

annotation class ComposableScoped

@ComposableScoped

@DefineComponent(parent = ActivityComponent
:
:
class)

interface ComposableComponent_
@Scope

annotation class ComposableScoped

@ComposableScoped

@DefineComponent(parent = ActivityComponent
:
:
class)

interface ComposableComponent_

@DefineComponent.Builder

interface ComposableComponentBuilder {

fun build(): ComposableComponent

}
@Scope

annotation class ComposableScoped

@ComposableScoped

@DefineComponent(parent = ActivityComponent
:
:
class)

interface ComposableComponent_

@DefineComponent.Builder

interface ComposableComponentBuilder {

fun build(): ComposableComponent

}

@EntryPoint

@InstallIn(ActivityComponent
:
:
class)

interface ComposableComponentBuilderEntryPoint {

val componentBuilder: ComposableComponentBuilder

}_
@Composable

inline fun <reified T : Any> rememberComposableEntryPoint(): T {

val context = LocalContext.current

return remember {

val entryPoint = EntryPointAccessors.fromActivity(

context.getActivity(), ComposableComponentBuilderEntryPoint
:
:
class.java

)

EntryPoints.get(entryPoint.componentBuilder.build(), T
:
:
class.java)

}

}
@ComposableScoped

class MyClass @Inject constructor() {

/
/
.
.
.


}
@ComposableScoped

class MyClass @Inject constructor() {

/
/
.
.
.


}

@InstallIn(ComposableComponent
:
:
class)

@EntryPoint

interface MyEntryPoint {

val myInstance: MyClass

}
@ComposableScoped

class MyClass @Inject constructor() {

/
/
.
.
.


}

@InstallIn(ComposableComponent
:
:
class)

@EntryPoint

interface MyEntryPoint {

val myInstance: MyClass

}

@Composable

fun MyScreen() {

val entryPoint = rememberComposableEntryPoint<MyEntryPoint>()

val myInstance = entryPoint.myInstance

}
ViewModel
Are ViewModels


necessary


(or useful)


using Compose?
https://www.youtube.com/watch?v=rmv2ug-wW4U
val navController = rememberNavController()

NavHost(navController = navController) {

}_
val navController = rememberNavController()

NavHost(navController = navController, startDestination = "home") {

composable("home") {

HomeScreen()

}

}_
val navController = rememberNavController()

NavHost(navController = navController, startDestination = "home") {

composable("home") {

HomeScreen()

}

composable(

route = "detail/{id}",

arguments = listOf(navArgument("id") { type = IntType })

) {

DetailScreen()

}

}_
val navController = rememberNavController()

NavHost(navController = navController, startDestination = "home") {

composable("home") {

HomeScreen(onClick = { navController.navigate("detail/123") })

}

composable(

route = "detail/{id}",

arguments = listOf(navArgument("id") { type = IntType })

) {

DetailScreen()

}

}_
class DetailViewModel constructor(

) : ViewModel() {

}_
@HiltViewModel

class DetailViewModel @Inject constructor(

private val myUseCase: MyUseCase,

) : ViewModel() {

}_
@HiltViewModel

class DetailViewModel @Inject constructor(

private val myUseCase: MyUseCase,

savedStateHandle: SavedStateHandle

) : ViewModel() {

init {

val id = savedStateHandle.get<Int>("id")

}

}_
@HiltViewModel

class DetailViewModel @Inject constructor(

private val myUseCase: MyUseCase,

savedStateHandle: SavedStateHandle

) : ViewModel() {

init {

val id = savedStateHandle.get<Int>("id")

viewModelScope.launch {

myUseCase.suspendMethod(id)

}

}

}_
@HiltViewModel

class DetailViewModel @Inject constructor(

private val myUseCase: MyUseCase,

savedStateHandle: SavedStateHandle

) : ViewModel() {

var state by mutableStateOf("")

private set

init {

val id = savedStateHandle.get<Int>("id")

viewModelScope.launch {

state = myUseCase.suspendMethod(id)

}

}

}_
@Composable

fun DetailScreen() {

}_
@Composable

fun DetailScreen() {

val viewModel = hiltViewModel<DetailViewModel>()

}_
@Composable

fun DetailScreen() {

val viewModel = hiltViewModel<DetailViewModel>()

val stateConnectedToViewModelLifecycle = viewModel.state

}_
@Composable

fun DetailScreen() {

val viewModel = hiltViewModel<DetailViewModel>()

val stateConnectedToViewModelLifecycle = viewModel.state

val remembered = remember {

"executed again on configuration change and when navigating back"

}

}_
@Composable

fun DetailScreen() {

val viewModel = hiltViewModel<DetailViewModel>()

val stateConnectedToViewModelLifecycle = viewModel.state

val remembered = remember {

"executed again on configuration change and when navigating back"

}

val saveable = rememberSaveable {

"saved in a bundle"

}

}_
@Composable

fun DetailScreen() {

val viewModel = hiltViewModel<DetailViewModel>()

val stateConnectedToViewModelLifecycle = viewModel.state

val remembered = remember {

"executed again on configuration change and when navigating back"

}

val saveable = rememberSaveable {

"saved in a bundle"

}

LaunchedEffect(Unit) {

/
/
executed again on configuration change and when navigating back

}

}_
https://proandroiddev.com/viewmodels-using-compose-mutablestate
fl
ows-or-mutablestates-64d34ba548c5
Wrapping
up
Wrapping
up
unidirectional data
fl
ow
Wrapping
up
unidirectional data
fl
ow


screens instead of fragments
Wrapping
up
unidirectional data
fl
ow


screens instead of fragments


viewModels are still useful
Links
&
contacts
Architecting your Compose UI


developer.android.com/jetpack/compose/architecture


Jose Alcérreca - LiveData with SnackBar, Navigation and other events (the SingleLiveEvent case)


medium.com/androiddevelopers/livedata-with-snackbar-navigation-and-other-events-the-singleliveevent-case-ac2622673150


Michael Ferguson - Android SingleLiveEvent Redux with Kotlin Flow


proandroiddev.com/android-singleliveevent-redux-with-kotlin-flow-b755c70bb055


Lifecycle of composables


developer.android.com/jetpack/compose/lifecycle


Manuel Vivo - A Compose state of mind: Using Jetpack Compose's automatic state observation


www.youtube.com/watch?v=rmv2ug-wW4U


Fabio Collini - ViewModels using Compose: MutableStateFlows or MutableStates?


proandroiddev.com/viewmodels-using-compose-mutablestateflows-or-mutablestates-64d34ba548c5
@fabioCollini


linkedin.com/in/fabiocollini


github.com/fabioCollini


medium.com/@fabioCollini
THANKS
FOR YOUR
ATTENTION
QUESTIONS?
@fabioCollini

Mais conteúdo relacionado

Mais procurados

Testing Android apps based on Dagger and RxJava
Testing Android apps based on Dagger and RxJavaTesting Android apps based on Dagger and RxJava
Testing Android apps based on Dagger and RxJavaFabio Collini
 
Workshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testingWorkshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testingVisual Engineering
 
Swift Delhi: Practical POP
Swift Delhi: Practical POPSwift Delhi: Practical POP
Swift Delhi: Practical POPNatasha Murashev
 
Protocol-Oriented MVVM (extended edition)
Protocol-Oriented MVVM (extended edition)Protocol-Oriented MVVM (extended edition)
Protocol-Oriented MVVM (extended edition)Natasha Murashev
 
Practical Protocol-Oriented-Programming
Practical Protocol-Oriented-ProgrammingPractical Protocol-Oriented-Programming
Practical Protocol-Oriented-ProgrammingNatasha Murashev
 
Advanced javascript
Advanced javascriptAdvanced javascript
Advanced javascriptDoeun KOCH
 
Practical Protocols with Associated Types
Practical Protocols with Associated TypesPractical Protocols with Associated Types
Practical Protocols with Associated TypesNatasha Murashev
 
Reactive, component 그리고 angular2
Reactive, component 그리고  angular2Reactive, component 그리고  angular2
Reactive, component 그리고 angular2Jeado Ko
 
Workshop 25: React Native - Components
Workshop 25: React Native - ComponentsWorkshop 25: React Native - Components
Workshop 25: React Native - ComponentsVisual Engineering
 
Taming Core Data by Arek Holko, Macoscope
Taming Core Data by Arek Holko, MacoscopeTaming Core Data by Arek Holko, Macoscope
Taming Core Data by Arek Holko, MacoscopeMacoscope
 
Daggerate your code - Write your own annotation processor
Daggerate your code - Write your own annotation processorDaggerate your code - Write your own annotation processor
Daggerate your code - Write your own annotation processorBartosz Kosarzycki
 
Workshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScriptWorkshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScriptVisual Engineering
 
Protocol Oriented MVVM - Auckland iOS Meetup
Protocol Oriented MVVM - Auckland iOS MeetupProtocol Oriented MVVM - Auckland iOS Meetup
Protocol Oriented MVVM - Auckland iOS MeetupNatasha Murashev
 
Reactive Programming with JavaScript
Reactive Programming with JavaScriptReactive Programming with JavaScript
Reactive Programming with JavaScriptCodemotion
 
Redux Sagas - React Alicante
Redux Sagas - React AlicanteRedux Sagas - React Alicante
Redux Sagas - React AlicanteIgnacio Martín
 

Mais procurados (19)

Testing Android apps based on Dagger and RxJava
Testing Android apps based on Dagger and RxJavaTesting Android apps based on Dagger and RxJava
Testing Android apps based on Dagger and RxJava
 
Workshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testingWorkshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testing
 
droidparts
droidpartsdroidparts
droidparts
 
Swift Delhi: Practical POP
Swift Delhi: Practical POPSwift Delhi: Practical POP
Swift Delhi: Practical POP
 
Protocol-Oriented MVVM (extended edition)
Protocol-Oriented MVVM (extended edition)Protocol-Oriented MVVM (extended edition)
Protocol-Oriented MVVM (extended edition)
 
Practical Protocol-Oriented-Programming
Practical Protocol-Oriented-ProgrammingPractical Protocol-Oriented-Programming
Practical Protocol-Oriented-Programming
 
Advanced javascript
Advanced javascriptAdvanced javascript
Advanced javascript
 
Practical Protocols with Associated Types
Practical Protocols with Associated TypesPractical Protocols with Associated Types
Practical Protocols with Associated Types
 
Reactive, component 그리고 angular2
Reactive, component 그리고  angular2Reactive, component 그리고  angular2
Reactive, component 그리고 angular2
 
Workshop 25: React Native - Components
Workshop 25: React Native - ComponentsWorkshop 25: React Native - Components
Workshop 25: React Native - Components
 
Angular2 + rxjs
Angular2 + rxjsAngular2 + rxjs
Angular2 + rxjs
 
Taming Core Data by Arek Holko, Macoscope
Taming Core Data by Arek Holko, MacoscopeTaming Core Data by Arek Holko, Macoscope
Taming Core Data by Arek Holko, Macoscope
 
Daggerate your code - Write your own annotation processor
Daggerate your code - Write your own annotation processorDaggerate your code - Write your own annotation processor
Daggerate your code - Write your own annotation processor
 
Workshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScriptWorkshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScript
 
Protocol-Oriented MVVM
Protocol-Oriented MVVMProtocol-Oriented MVVM
Protocol-Oriented MVVM
 
Protocol Oriented MVVM - Auckland iOS Meetup
Protocol Oriented MVVM - Auckland iOS MeetupProtocol Oriented MVVM - Auckland iOS Meetup
Protocol Oriented MVVM - Auckland iOS Meetup
 
Typescript barcelona
Typescript barcelonaTypescript barcelona
Typescript barcelona
 
Reactive Programming with JavaScript
Reactive Programming with JavaScriptReactive Programming with JavaScript
Reactive Programming with JavaScript
 
Redux Sagas - React Alicante
Redux Sagas - React AlicanteRedux Sagas - React Alicante
Redux Sagas - React Alicante
 

Semelhante a Architectures in the compose world

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
 
Declarative presentations UIKonf
Declarative presentations UIKonfDeclarative presentations UIKonf
Declarative presentations UIKonfNataliya Patsovska
 
Property wrapper and how to use them with mvvm in swift ui i copy
Property wrapper and how to use them with mvvm in swift ui i copyProperty wrapper and how to use them with mvvm in swift ui i copy
Property wrapper and how to use them with mvvm in swift ui i copyWannitaTolaema
 
[22]Efficient and Testable MVVM pattern
[22]Efficient and Testable MVVM pattern[22]Efficient and Testable MVVM pattern
[22]Efficient and Testable MVVM patternNAVER Engineering
 
KMM survival guide: how to tackle struggles between Kotlin and Swift
KMM survival guide: how to tackle struggles between Kotlin and SwiftKMM survival guide: how to tackle struggles between Kotlin and Swift
KMM survival guide: how to tackle struggles between Kotlin and SwiftCommit University
 
Practialpop 160510130818
Practialpop 160510130818Practialpop 160510130818
Practialpop 160510130818Shahzain Saeed
 
MCE^3 - Natasha Murashev - Practical Protocol-Oriented Programming in Swift
MCE^3 - Natasha Murashev - Practical Protocol-Oriented Programming in SwiftMCE^3 - Natasha Murashev - Practical Protocol-Oriented Programming in Swift
MCE^3 - Natasha Murashev - Practical Protocol-Oriented Programming in SwiftPROIDEA
 
Qtp Training Deepti 3 Of 44256
Qtp Training Deepti 3 Of 44256Qtp Training Deepti 3 Of 44256
Qtp Training Deepti 3 Of 44256Azhar Satti
 
Migrating Objective-C to Swift
Migrating Objective-C to SwiftMigrating Objective-C to Swift
Migrating Objective-C to SwiftElmar Kretzer
 
20150516 modern web_conf_tw
20150516 modern web_conf_tw20150516 modern web_conf_tw
20150516 modern web_conf_twTse-Ching Ho
 
Compose로 Android:Desktop 멀티플랫폼 만들기.pdf
Compose로 Android:Desktop 멀티플랫폼 만들기.pdfCompose로 Android:Desktop 멀티플랫폼 만들기.pdf
Compose로 Android:Desktop 멀티플랫폼 만들기.pdfssuserb6c2641
 
Using Reflections and Automatic Code Generation
Using Reflections and Automatic Code GenerationUsing Reflections and Automatic Code Generation
Using Reflections and Automatic Code GenerationIvan Dolgushin
 
Protocol-Oriented Programming in Swift
Protocol-Oriented Programming in SwiftProtocol-Oriented Programming in Swift
Protocol-Oriented Programming in SwiftOleksandr Stepanov
 
303 TANSTAAFL: Using Open Source iPhone UI Code
303 TANSTAAFL: Using Open Source iPhone UI Code303 TANSTAAFL: Using Open Source iPhone UI Code
303 TANSTAAFL: Using Open Source iPhone UI Codejonmarimba
 
Does testability imply good design - Andrzej Jóźwiak - TomTom Dev Day 2022
Does testability imply good design - Andrzej Jóźwiak - TomTom Dev Day 2022Does testability imply good design - Andrzej Jóźwiak - TomTom Dev Day 2022
Does testability imply good design - Andrzej Jóźwiak - TomTom Dev Day 2022Andrzej Jóźwiak
 
MBLTDev15: Egor Tolstoy, Rambler&Co
MBLTDev15: Egor Tolstoy, Rambler&CoMBLTDev15: Egor Tolstoy, Rambler&Co
MBLTDev15: Egor Tolstoy, Rambler&Coe-Legion
 

Semelhante a Architectures in the compose world (20)

Flutter
FlutterFlutter
Flutter
 
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
 
Declarative presentations UIKonf
Declarative presentations UIKonfDeclarative presentations UIKonf
Declarative presentations UIKonf
 
Unit testing UIView
Unit testing UIViewUnit testing UIView
Unit testing UIView
 
iOS Talks 6: Unit Testing
iOS Talks 6: Unit TestingiOS Talks 6: Unit Testing
iOS Talks 6: Unit Testing
 
Property wrapper and how to use them with mvvm in swift ui i copy
Property wrapper and how to use them with mvvm in swift ui i copyProperty wrapper and how to use them with mvvm in swift ui i copy
Property wrapper and how to use them with mvvm in swift ui i copy
 
[22]Efficient and Testable MVVM pattern
[22]Efficient and Testable MVVM pattern[22]Efficient and Testable MVVM pattern
[22]Efficient and Testable MVVM pattern
 
KMM survival guide: how to tackle struggles between Kotlin and Swift
KMM survival guide: how to tackle struggles between Kotlin and SwiftKMM survival guide: how to tackle struggles between Kotlin and Swift
KMM survival guide: how to tackle struggles between Kotlin and Swift
 
Practialpop 160510130818
Practialpop 160510130818Practialpop 160510130818
Practialpop 160510130818
 
MCE^3 - Natasha Murashev - Practical Protocol-Oriented Programming in Swift
MCE^3 - Natasha Murashev - Practical Protocol-Oriented Programming in SwiftMCE^3 - Natasha Murashev - Practical Protocol-Oriented Programming in Swift
MCE^3 - Natasha Murashev - Practical Protocol-Oriented Programming in Swift
 
Qtp Training Deepti 3 Of 44256
Qtp Training Deepti 3 Of 44256Qtp Training Deepti 3 Of 44256
Qtp Training Deepti 3 Of 44256
 
Qtp Training
Qtp Training Qtp Training
Qtp Training
 
Migrating Objective-C to Swift
Migrating Objective-C to SwiftMigrating Objective-C to Swift
Migrating Objective-C to Swift
 
20150516 modern web_conf_tw
20150516 modern web_conf_tw20150516 modern web_conf_tw
20150516 modern web_conf_tw
 
Compose로 Android:Desktop 멀티플랫폼 만들기.pdf
Compose로 Android:Desktop 멀티플랫폼 만들기.pdfCompose로 Android:Desktop 멀티플랫폼 만들기.pdf
Compose로 Android:Desktop 멀티플랫폼 만들기.pdf
 
Using Reflections and Automatic Code Generation
Using Reflections and Automatic Code GenerationUsing Reflections and Automatic Code Generation
Using Reflections and Automatic Code Generation
 
Protocol-Oriented Programming in Swift
Protocol-Oriented Programming in SwiftProtocol-Oriented Programming in Swift
Protocol-Oriented Programming in Swift
 
303 TANSTAAFL: Using Open Source iPhone UI Code
303 TANSTAAFL: Using Open Source iPhone UI Code303 TANSTAAFL: Using Open Source iPhone UI Code
303 TANSTAAFL: Using Open Source iPhone UI Code
 
Does testability imply good design - Andrzej Jóźwiak - TomTom Dev Day 2022
Does testability imply good design - Andrzej Jóźwiak - TomTom Dev Day 2022Does testability imply good design - Andrzej Jóźwiak - TomTom Dev Day 2022
Does testability imply good design - Andrzej Jóźwiak - TomTom Dev Day 2022
 
MBLTDev15: Egor Tolstoy, Rambler&Co
MBLTDev15: Egor Tolstoy, Rambler&CoMBLTDev15: Egor Tolstoy, Rambler&Co
MBLTDev15: Egor Tolstoy, Rambler&Co
 

Mais de Fabio Collini

Using Dagger in a Clean Architecture project
Using Dagger in a Clean Architecture projectUsing Dagger in a Clean Architecture project
Using Dagger in a Clean Architecture projectFabio Collini
 
SOLID principles in practice: the Clean Architecture - Devfest Emila Romagna
SOLID principles in practice: the Clean Architecture - Devfest Emila RomagnaSOLID principles in practice: the Clean Architecture - Devfest Emila Romagna
SOLID principles in practice: the Clean Architecture - Devfest Emila RomagnaFabio Collini
 
SOLID principles in practice: the Clean Architecture
SOLID principles in practice: the Clean ArchitectureSOLID principles in practice: the Clean Architecture
SOLID principles in practice: the Clean ArchitectureFabio Collini
 
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf MilanFrom Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf MilanFabio Collini
 
Async code on kotlin: rx java or/and coroutines - Kotlin Night Turin
Async code on kotlin: rx java or/and coroutines - Kotlin Night TurinAsync code on kotlin: rx java or/and coroutines - Kotlin Night Turin
Async code on kotlin: rx java or/and coroutines - Kotlin Night TurinFabio Collini
 
Recap Google I/O 2018
Recap Google I/O 2018Recap Google I/O 2018
Recap Google I/O 2018Fabio Collini
 
From java to kotlin beyond alt+shift+cmd+k - Droidcon italy
From java to kotlin beyond alt+shift+cmd+k - Droidcon italyFrom java to kotlin beyond alt+shift+cmd+k - Droidcon italy
From java to kotlin beyond alt+shift+cmd+k - Droidcon italyFabio Collini
 
From java to kotlin beyond alt+shift+cmd+k
From java to kotlin beyond alt+shift+cmd+kFrom java to kotlin beyond alt+shift+cmd+k
From java to kotlin beyond alt+shift+cmd+kFabio Collini
 
Android Data Binding in action using MVVM pattern - droidconUK
Android Data Binding in action using MVVM pattern - droidconUKAndroid Data Binding in action using MVVM pattern - droidconUK
Android Data Binding in action using MVVM pattern - droidconUKFabio Collini
 
Data Binding in Action using MVVM pattern
Data Binding in Action using MVVM patternData Binding in Action using MVVM pattern
Data Binding in Action using MVVM patternFabio Collini
 
Android Wear CodeLab - GDG Firenze
Android Wear CodeLab - GDG FirenzeAndroid Wear CodeLab - GDG Firenze
Android Wear CodeLab - GDG FirenzeFabio Collini
 
Testable Android Apps using data binding and MVVM
Testable Android Apps using data binding and MVVMTestable Android Apps using data binding and MVVM
Testable Android Apps using data binding and MVVMFabio Collini
 
Introduction to Retrofit and RxJava
Introduction to Retrofit and RxJavaIntroduction to Retrofit and RxJava
Introduction to Retrofit and RxJavaFabio Collini
 
Testable Android Apps DroidCon Italy 2015
Testable Android Apps DroidCon Italy 2015Testable Android Apps DroidCon Italy 2015
Testable Android Apps DroidCon Italy 2015Fabio Collini
 
Clean android code - Droidcon Italiy 2014
Clean android code - Droidcon Italiy 2014Clean android code - Droidcon Italiy 2014
Clean android code - Droidcon Italiy 2014Fabio Collini
 
Librerie su Android: come non reinventare la ruota @ whymca 2012
Librerie su Android: come non reinventare la ruota @ whymca 2012 Librerie su Android: come non reinventare la ruota @ whymca 2012
Librerie su Android: come non reinventare la ruota @ whymca 2012 Fabio Collini
 
Android Widget @ whymca 2011
Android Widget @ whymca 2011Android Widget @ whymca 2011
Android Widget @ whymca 2011Fabio Collini
 

Mais de Fabio Collini (17)

Using Dagger in a Clean Architecture project
Using Dagger in a Clean Architecture projectUsing Dagger in a Clean Architecture project
Using Dagger in a Clean Architecture project
 
SOLID principles in practice: the Clean Architecture - Devfest Emila Romagna
SOLID principles in practice: the Clean Architecture - Devfest Emila RomagnaSOLID principles in practice: the Clean Architecture - Devfest Emila Romagna
SOLID principles in practice: the Clean Architecture - Devfest Emila Romagna
 
SOLID principles in practice: the Clean Architecture
SOLID principles in practice: the Clean ArchitectureSOLID principles in practice: the Clean Architecture
SOLID principles in practice: the Clean Architecture
 
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf MilanFrom Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
 
Async code on kotlin: rx java or/and coroutines - Kotlin Night Turin
Async code on kotlin: rx java or/and coroutines - Kotlin Night TurinAsync code on kotlin: rx java or/and coroutines - Kotlin Night Turin
Async code on kotlin: rx java or/and coroutines - Kotlin Night Turin
 
Recap Google I/O 2018
Recap Google I/O 2018Recap Google I/O 2018
Recap Google I/O 2018
 
From java to kotlin beyond alt+shift+cmd+k - Droidcon italy
From java to kotlin beyond alt+shift+cmd+k - Droidcon italyFrom java to kotlin beyond alt+shift+cmd+k - Droidcon italy
From java to kotlin beyond alt+shift+cmd+k - Droidcon italy
 
From java to kotlin beyond alt+shift+cmd+k
From java to kotlin beyond alt+shift+cmd+kFrom java to kotlin beyond alt+shift+cmd+k
From java to kotlin beyond alt+shift+cmd+k
 
Android Data Binding in action using MVVM pattern - droidconUK
Android Data Binding in action using MVVM pattern - droidconUKAndroid Data Binding in action using MVVM pattern - droidconUK
Android Data Binding in action using MVVM pattern - droidconUK
 
Data Binding in Action using MVVM pattern
Data Binding in Action using MVVM patternData Binding in Action using MVVM pattern
Data Binding in Action using MVVM pattern
 
Android Wear CodeLab - GDG Firenze
Android Wear CodeLab - GDG FirenzeAndroid Wear CodeLab - GDG Firenze
Android Wear CodeLab - GDG Firenze
 
Testable Android Apps using data binding and MVVM
Testable Android Apps using data binding and MVVMTestable Android Apps using data binding and MVVM
Testable Android Apps using data binding and MVVM
 
Introduction to Retrofit and RxJava
Introduction to Retrofit and RxJavaIntroduction to Retrofit and RxJava
Introduction to Retrofit and RxJava
 
Testable Android Apps DroidCon Italy 2015
Testable Android Apps DroidCon Italy 2015Testable Android Apps DroidCon Italy 2015
Testable Android Apps DroidCon Italy 2015
 
Clean android code - Droidcon Italiy 2014
Clean android code - Droidcon Italiy 2014Clean android code - Droidcon Italiy 2014
Clean android code - Droidcon Italiy 2014
 
Librerie su Android: come non reinventare la ruota @ whymca 2012
Librerie su Android: come non reinventare la ruota @ whymca 2012 Librerie su Android: come non reinventare la ruota @ whymca 2012
Librerie su Android: come non reinventare la ruota @ whymca 2012
 
Android Widget @ whymca 2011
Android Widget @ whymca 2011Android Widget @ whymca 2011
Android Widget @ whymca 2011
 

Último

The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfonteinmasabamasaba
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfVishalKumarJha10
 
LEVEL 5 - SESSION 1 2023 (1).pptx - PDF 123456
LEVEL 5   - SESSION 1 2023 (1).pptx - PDF 123456LEVEL 5   - SESSION 1 2023 (1).pptx - PDF 123456
LEVEL 5 - SESSION 1 2023 (1).pptx - PDF 123456KiaraTiradoMicha
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park masabamasaba
 
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfAzure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfryanfarris8
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfproinshot.com
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech studentsHimanshiGarg82
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...Jittipong Loespradit
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerThousandEyes
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park masabamasaba
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...SelfMade bd
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
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
 
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
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
 
ManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide DeckManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide DeckManageIQ
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxComplianceQuest1
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisamasabamasaba
 

Último (20)

The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
 
LEVEL 5 - SESSION 1 2023 (1).pptx - PDF 123456
LEVEL 5   - SESSION 1 2023 (1).pptx - PDF 123456LEVEL 5   - SESSION 1 2023 (1).pptx - PDF 123456
LEVEL 5 - SESSION 1 2023 (1).pptx - PDF 123456
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfAzure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdf
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
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 🔝✔️✔️
 
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
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
ManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide DeckManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide Deck
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 

Architectures in the compose world