Me as a Kotlin Multiplatform composition

Overview

Me

Please note, this is not an official Google repository. It is a Kotlin multiplatform experiment that makes no guarantees about API stability or long term support. None of the works presented here are production tested, and should not be taken as anything more than its face value.

Introduction

"Me" is a Kotlin Multiplatform playground for ideas that pop into my head around app architecture. These ideas typically center around state and it's production; a repository of "what ifs?". Some of the ideas explored include:

  • Android insets and IME behavior driven by immutable state
  • Tiling as a way of loading paginated data
  • Trees as a backing data structure for app navigation
  • Mutators as abstract data types for the production and mutation of state
  • Motional Intelligence with global UI as implemented with Jetpack Compose

Demo image

The API consumed is that of my personal website. The source can be found here.

Arch

Navigation

Each destination in the app is represented by an AppRoute that exposes a single @Composable Render() function. The backing data structures for navigation a the tree like StackNav and MultiStackNav immutable classes. The root of the app is a MultiStackNav and navigation is controlled by a NavMutator defined as:

typealias NavMutator = Mutator
   
    
     , StateFlow
     
      >

     
    
   

Global UI

The app utilizes a single bottom nav, toolbar and a shared global UI state as defined by the UiState class. This is what allows for the app to have responsive navigation while accounting for visual semantic differences between Android and desktop. Android for example uses the WindowManager API to drive it's responsiveness whereas desktop just watches it's Window size. The definition for the GlobalUiMutator is:

typealias GlobalUiMutator = Mutator
   
    
     , StateFlow
     
      >

     
    
   

State restoration and process death

LOL, I'm sorry what?? Imma get back to you on that one bruh.

Lifecycles and component scoping

Lifecycles are one of the most important concepts on Android, however Jetpack Compose itself is pretty binary; a Composable is either in composition or not. Trying to expand this simplicity to Android; the app may either be in the foreground or not. Therefore, the state of the app so far can be represented as:

data class AppState(
    val nav: MultiStackNav,
    val ui: UiState,
    val isInForeground: Boolean = true
)

With the above managing the lifecycle of components scoped to navigation destinations becomes as easy as:

private data class ScopeHolder(
    val scope: CoroutineScope,
    val mutator: Any
)

object: AppDependencies {
    init {
        scope.launch {
            appMutator.state
                .map { it.nav.routes.filterIsInstance
   
    <*>>() }
                .distinctUntilChanged()
                .scan(listOf
    
     <*>>() to listOf
     
      <*>>()) { pair, newRoutes ->
                    pair.copy(first = pair.second, second = newRoutes)
                }
                .distinctUntilChanged()
                .collect { (oldRoutes, newRoutes) ->
                    oldRoutes.minus(newRoutes.toSet()).forEach { route ->
                        val holder = routeMutatorFactory.remove(route)
                        holder?.scope?.cancel()
                    }
                }
        }
    }
}

     
    
   

By watching the changes to the available routes in the MultiStackNav class, the scopes for Mutators for routes that have been removed can be cancelled.

Each navigation destination can also be informed when the app is in the background via the isInForeground field on AppState. It's Mutator can then opt to terminate it's backing flow if necessary.

I try to keep the code at a near production quality, but this often takes a back seat to convenience and whim. I'm a huge proponent of dependency injection, yet the repository uses manual service location. Also outside data classes, virtually everything else is implemented as a function, or anonymous class just because.

Again, the work presented here are the ideas of an immutable state zealot. It's far from objective, I just be doing anything tbh. Caveat emptor.

Running

Desktop: ./gradlew :desktop:run Android: ./gradlew :android:assembleDebug or run the Android target in Android Studio

License

Copyright 2021 Google LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
You might also like...
Generic AST parsing library for kotlin multiplatform

kotlinx.ast kotlinx.ast is a generic AST (Abstract Syntax Tree) parsing library, Kotlin is currently the only supported language. The library is desig

KaMP Kit by Touchlab is a collection of code and tools designed to get your mobile team started quickly with Kotlin Multiplatform.
KaMP Kit by Touchlab is a collection of code and tools designed to get your mobile team started quickly with Kotlin Multiplatform.

KaMP Kit Welcome to the KaMP Kit! About Goal The goal of the KaMP Kit is to facilitate your evaluation of Kotlin Multiplatform (aka KMP). It is a coll

Kotlin Multiplatform Mobile App Template

KMMT : Kotlin Multiplatform Mobile Template Kotlin Multiplatform Mobile Development Simplified KMMT is a KMM based project template designed to simpli

GraphQL based Jetpack Compose and SwiftUI Kotlin Multiplatform sample
GraphQL based Jetpack Compose and SwiftUI Kotlin Multiplatform sample

GraphQL based Jetpack Compose and SwiftUI Kotlin Multiplatform sample

Playground for learning Kotlin Multiplatform Mobile
Playground for learning Kotlin Multiplatform Mobile

This is a playground for learning KMP (KMM Plugin for android studio). Requirements Android Studio Canary 8 Architecture Thanks https://twitter.com/jo

Kotlin Multiplatform project that gets network data from Food2Fork.ca
Kotlin Multiplatform project that gets network data from Food2Fork.ca

Food2Fork Recipe App This is the codebase for a Kotlin Multiplatform Mobile course. [Watch the course](https://codingwithmitch.com/courses/kotlin-mult

Ethereum Web3 implementation for mobile (android & ios) Kotlin Multiplatform development

Mobile Kotlin web3 This is a Kotlin MultiPlatform library that ... Table of Contents Features Requirements Installation Usage Samples Set Up Locally C

The most essential libraries for Kotlin Multiplatform development
The most essential libraries for Kotlin Multiplatform development

Essenty The most essential libraries for Kotlin Multiplatform development. Supported targets: android jvm js (IR and LEGACY) iosArm64, iosX64 watchosA

Simple Kotlin Multiplatform PrayerTimes App for iOS and Android

Kotlin Multiplatform ___ _______ ___ / _ \_______ ___ _____ ___/_ __(_)_ _ ___ ___ / _ | __

Comments
  • `dropTarget` on a `Row` does not work after switching monitor

    `dropTarget` on a `Row` does not work after switching monitor

    Environment

    • JetBrains Compose org.jetbrains.compose 1.1.1
    • Microsoft Windows 10.0.22616
    • Two monitors with different density.

    Steps to Reproduce

    1. Add dropParent modifier on a surface.
    2. Create a row in this surface, adding dropTarget modifier.
    3. Run application. Then drag and drop function only works before I move the window into another monitor.

    However, if I add dropTarget to TextField, it works correctly.

    Example code

    https://gist.github.com/KiruyaMomochi/04585a662b0167529c6bd03fbc3794fc

    opened by KiruyaMomochi 0
Owner
Adetunji Dahunsi
Adetunji Dahunsi
Opinionated Redux-like implementation backed by Kotlin Coroutines and Kotlin Multiplatform Mobile

CoRed CoRed is Redux-like implementation that maintains the benefits of Redux's core idea without the boilerplate. No more action types, action creato

Kittinun Vantasin 28 Dec 10, 2022
An app architecture for Kotlin/Native on Android/iOS. Use Kotlin Multiplatform Mobile.

An app architecture for Kotlin/Native on Android/iOS. Use Kotlin Multiplatform Mobile. 项目架构主要分为原生系统层、Android/iOS业务SDK层、KMM SDK层、KMM业务逻辑SDK层、iOS sdkfra

libill 4 Nov 20, 2022
A Bluetooth kotlin multiplatform "Cross-Platform" library for iOS and Android

Blue-Falcon A Bluetooth "Cross Platform" Kotlin Multiplatform library for iOS, Android, MacOS, Raspberry Pi and Javascript. Bluetooth in general has t

Andrew Reed 220 Dec 28, 2022
Mobile client for official Nextcloud News App written as Kotlin Multiplatform Project

Newsout Android and iOS mobile client for Nextcloud news App. The Android client is already available to download in the Play Store. F-Droid and Apple

Simon Schubert 118 Oct 3, 2022
Kotlin Multiplatform Application to show Crypto Coins

This is the codebase of Crypto currency Tracking Kotlin Multiplatform App. Components Shared Components Ktor (Network Client) SQL Delight (Local DB) A

Aman Bansal 10 Oct 31, 2022
Dependency Injection library for Kotlin Multiplatform, support iOS and Android

Multiplatform-DI library for Kotlin Multiplatform Lightweight dependency injection framework for Kotlin Multiplatform application Dependency injection

Anna Zharkova 32 Nov 10, 2022
Kotlin multiplatform library template.

template-kmp-library Kotlin multiplatform library template. Has a baseline setup for a multiplatform library supporting all kotlin targets except andr

Martynas Petuška 51 Nov 21, 2022
BuildConfig for Kotlin Multiplatform Project

BuildKonfig BuildConfig for Kotlin Multiplatform Project. It currently supports embedding values from gradle file. Table Of Contents Motivation Usage

Yasuhiro SHIMIZU 331 Jan 4, 2023
Kotlin multiplatform benchmarking toolkit

NOTE: Starting from version 0.3.0 of the library: The library runtime is published to Maven Central and no longer published to Bintray. The Gradle plu

Kotlin 310 Jan 2, 2023
Gradle plugin for simplify Kotlin Multiplatform mobile configurations

Mobile Multiplatform gradle plugin This is a Gradle plugin for simple setup of Kotlin Multiplatform mobile Gradle modules. Setup buildSrc/build.gradle

IceRock Development 78 Sep 27, 2022