Upgrade to Pro — share decks privately, control downloads, hide ads and more …

An Android Dev start to Kotlin MPP

An Android Dev start to Kotlin MPP

Roberto Orgiu

November 16, 2020
Tweet

More Decks by Roberto Orgiu

Other Decks in Programming

Transcript

  1. An Android Dev
    start to
    Kotlin MPP

    View Slide

  2. Premises
    I want to reuse my knowledge
    I am an Android Dev
    I don’t want to be x-plat

    View Slide


  3. What about languages?

    View Slide

  4. Or actually any other example
    Empire State Building
    Lights Calendar
    App

    View Slide

  5. Architecture
    Activity ViewModel
    Repository

    View Slide

  6. Libraries
    Repository
    Retrofit
    Gson / Moshi

    View Slide

  7. Libraries
    Repository
    Retrofit
    Gson / Moshi
    Ktor
    kotlinx.serializer

    View Slide

  8. Modularization
    Activity ViewModel
    Repository
    Native module
    Shared module

    View Slide

  9. Modularization
    Repository
    Shared module

    View Slide

  10. View Slide

  11. There is an app a plugin for that.
    PROJECT SETUP
    1

    View Slide

  12. Install
    &
    Profit

    View Slide

  13. Create
    the project

    View Slide

  14. Create
    the project

    View Slide

  15. WRITE SOME CODE
    2

    View Slide

  16. expect
    actual
    IDE only helps after the directories have
    been created.

    View Slide

  17. @Serializable
    data class DayLight(
    val image: String,
    val color: String,
    val reason: String,
    val date: String
    )
    @Serializable
    data class Lights(
    val todayColor: String,
    val picture: String,
    val calendar: List
    )
    :shared

    View Slide

  18. class LightRepository {
    private val httpClient = HttpClient {
    install(JsonFeature) {
    val json = Json { ignoreUnknownKeys = true }
    serializer = KotlinxSerializer(json)
    }
    }
    suspend fun getLights() : Lights =
    httpClient.get(LIGHTS_ENDPOINT)
    }
    :shared

    View Slide

  19. :android
    class LightsViewModel : ViewModel() {
    private val repository by lazy {
    LightRepository()
    }
    private val _state : MutableLiveData> = MutableLiveData()
    val state : LiveData>
    get() = _state
    fun loadLights() {
    _state.postValue(Lce.Loading)
    viewModelScope.launch {
    try {
    val lights = repository.getLights()
    _state.postValue(Lce.Success(lights))
    } catch(e: Exception) {
    _state.postValue(Lce.Error(e))
    }
    }
    }
    }

    View Slide

  20. val state : LiveData>
    get() = _state
    fun loadLights() {
    _state.postValue(Lce.Loading)
    viewModelScope.launch {
    try {
    val lights = repository.getLights()
    _state.postValue(Lce.Success(lights))
    } catch(e: Exception) {
    _state.postValue(Lce.Error(e))
    }
    }

    View Slide

  21. They will happen
    WEIRD ERRORS
    3

    View Slide

  22. View Slide

  23. Delete all .iml files in the project
    Close project and IDE
    Delete .idea directory
    Re-import the project

    View Slide

  24. View Slide

  25. upgrade Gradle to 6.7 (KT-43039)

    View Slide

  26. View Slide

  27. bit.ly/KMM-Codelab

    View Slide

  28. USE COROUTINES
    4

    View Slide

  29. View Slide

  30. REMEMBER
    You cannot use extension
    functions

    View Slide

  31. extension ContentView {
    enum LoadableLights {
    case loading
    case result(Lights)
    case error(String)
    }
    class ViewModel: ObservableObject {
    let repo : LightRepository
    @Published var lights = LoadableLights.loading
    init(repo: LightRepository){
    self.repo = repo
    self.loadLights()
    }
    func loadLights() {
    self.lights = .loading
    repo.getLights(completionHandler: { lights, error in
    if let lights = lights {
    self.lights = .result(lights)
    } else {
    self.lights = .error(error?.localizedDescription ?? "error")
    }
    })
    }
    }
    }

    View Slide

  32. self.repo = repo
    self.loadLights()
    }
    func loadLights() {
    self.lights = .loading
    repo.getLights(completionHandler: { lights, error in
    if let lights = lights {
    self.lights = .result(lights)
    } else {
    self.lights = .error(error?.localizedDescription ?? "e
    }
    })
    }

    View Slide

  33. private func listView() -> AnyView {
    switch viewModel.lights {
    case .loading:
    return AnyView(Text("Loading...").multilineTextAlignment(.center))
    case .result(let lodableLights):
    return AnyView(LightsView(lights: lodableLights))
    case .error(let description):
    return AnyView(Text(description).multilineTextAlignment(.center))
    }
    }

    View Slide

  34. View Slide

  35. View Slide

  36. Hello!
    I Am Rob
    Follow me at @_tiwiz

    View Slide

  37. Q&A

    View Slide