
Facilitates extensive code sharing between iOS and Android, focusing on non-UI components like network requests, caching, and business logic, while integrating with SwiftUI and Compose.
FiFi is a Kotlin Multiplatform (KMP) framework for sharing mobile app logic between iOS and Android: ViewModels, data models, caching, API clients, and optional token auth. UI and navigation stay in platform code (Compose / SwiftUI).
Current version: 0.0.45 (see CHANGELOG.md)
| Module | Maven artifact | Use when |
|---|---|---|
| fifi-common | com.paoapps.fifi:fifi-common |
Shared types with a Ktor server (amounts, tokens, JSON helpers) |
| fifi-framework | com.paoapps.fifi:fifi-framework |
Any KMP mobile app (ViewModels, Model, caching, DI bootstrap) |
| fifi-auth | com.paoapps.fifi:fifi-auth |
Apps with token-based authentication |
Peer dependency: blocked-cache (com.paoapps.blockedcache:blocked-cache) — used by ModelHelper for fetch/cache flows.
// build.gradle.kts (shared module)
implementation("com.paoapps.fifi:fifi-framework:0.0.45")
implementation("com.paoapps.blockedcache:blocked-cache:0.0.10")AppDefinition — environment factory, API factory, Model, Koin modules.initKoinApp(appDefinition) from Android/iOS entry points (Android: com.paoapps.fifi.koin.initKoinApp(context, …)).AbstractViewModel<Output, Event, Action>.output, action, and emitEvent().See docs/getting-started.md for a full checklist. The sample app demonstrates a non-auth setup.
Flow / FlowAdapter)emitEvent()
Helpers: viewModelOutput(), createRefreshableFetchFlow(), ActionHandler.
Models fetch and cache data via ModelHelper and blocked-cache. ViewModels request data; Models decide cache vs network.
com.paoapps.fifi.loading.Loadable maps CacheResult to a UI-agnostic loading/error/data wrapper. Apps map it to their own error components.
import com.paoapps.fifi.viewmodel.testOutput
import com.paoapps.fifi.viewmodel.testActions
viewModel.testOutput { /* assert on Output */ }
viewModel.testActions { emit -> emit(MyEvent.Tap) }Use fifi-auth: implement AuthAppDefinition, TokenDecoder, and call com.paoapps.fifi.auth.di.initKoinApp. See docs/auth-setup.md.
viewModel.clear() when the screen is dismissed (see docs/ios-integration.md).DataContainer is Android-only in-framework; iOS apps provide their own storage bridge.| Doc | Description |
|---|---|
| Getting started | Bootstrap checklist |
| Architecture | Module and data-flow overview |
| Auth setup | fifi-auth integration |
| iOS integration | SwiftUI bridge, lifecycle, persistence |
| Framework vs app | What belongs in FiFi vs your app |
| Compatibility | Versioning policy |
| Upgrading | Consumer upgrade notes |
sample/android — Compose UI wired to shared ViewModelssample/iosApp — SwiftUI reference (see README in that folder)Run Android sample: ./gradlew :sample:android:installDebug
Released to Maven Central on GitHub release. Version in gradle.properties.
See CONTRIBUTING.md.
FiFi is a Kotlin Multiplatform (KMP) framework for sharing mobile app logic between iOS and Android: ViewModels, data models, caching, API clients, and optional token auth. UI and navigation stay in platform code (Compose / SwiftUI).
Current version: 0.0.45 (see CHANGELOG.md)
| Module | Maven artifact | Use when |
|---|---|---|
| fifi-common | com.paoapps.fifi:fifi-common |
Shared types with a Ktor server (amounts, tokens, JSON helpers) |
| fifi-framework | com.paoapps.fifi:fifi-framework |
Any KMP mobile app (ViewModels, Model, caching, DI bootstrap) |
| fifi-auth | com.paoapps.fifi:fifi-auth |
Apps with token-based authentication |
Peer dependency: blocked-cache (com.paoapps.blockedcache:blocked-cache) — used by ModelHelper for fetch/cache flows.
// build.gradle.kts (shared module)
implementation("com.paoapps.fifi:fifi-framework:0.0.45")
implementation("com.paoapps.blockedcache:blocked-cache:0.0.10")AppDefinition — environment factory, API factory, Model, Koin modules.initKoinApp(appDefinition) from Android/iOS entry points (Android: com.paoapps.fifi.koin.initKoinApp(context, …)).AbstractViewModel<Output, Event, Action>.output, action, and emitEvent().See docs/getting-started.md for a full checklist. The sample app demonstrates a non-auth setup.
Flow / FlowAdapter)emitEvent()
Helpers: viewModelOutput(), createRefreshableFetchFlow(), ActionHandler.
Models fetch and cache data via ModelHelper and blocked-cache. ViewModels request data; Models decide cache vs network.
com.paoapps.fifi.loading.Loadable maps CacheResult to a UI-agnostic loading/error/data wrapper. Apps map it to their own error components.
import com.paoapps.fifi.viewmodel.testOutput
import com.paoapps.fifi.viewmodel.testActions
viewModel.testOutput { /* assert on Output */ }
viewModel.testActions { emit -> emit(MyEvent.Tap) }Use fifi-auth: implement AuthAppDefinition, TokenDecoder, and call com.paoapps.fifi.auth.di.initKoinApp. See docs/auth-setup.md.
viewModel.clear() when the screen is dismissed (see docs/ios-integration.md).DataContainer is Android-only in-framework; iOS apps provide their own storage bridge.| Doc | Description |
|---|---|
| Getting started | Bootstrap checklist |
| Architecture | Module and data-flow overview |
| Auth setup | fifi-auth integration |
| iOS integration | SwiftUI bridge, lifecycle, persistence |
| Framework vs app | What belongs in FiFi vs your app |
| Compatibility | Versioning policy |
| Upgrading | Consumer upgrade notes |
sample/android — Compose UI wired to shared ViewModelssample/iosApp — SwiftUI reference (see README in that folder)Run Android sample: ./gradlew :sample:android:installDebug
Released to Maven Central on GitHub release. Version in gradle.properties.
See CONTRIBUTING.md.