• Stars
    star
    211
  • Rank 186,867 (Top 4 %)
  • Language
    Kotlin
  • License
    MIT License
  • Created over 2 years ago
  • Updated 4 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

🍭 GithubSearchKMM - Github Repos Search - Android - iOS - Kotlin Multiplatform Mobile using Jetpack Compose, SwiftUI, FlowRedux, Coroutines Flow, Dagger Hilt, Koin Dependency Injection, shared KMP ViewModel, Clean Architecture

GithubSearchKMM

Github Repos Search - Kotlin Multiplatform Mobile using Jetpack Compose, SwiftUI, FlowRedux, Coroutines Flow, Dagger Hilt, Koin Dependency Injection, shared KMP ViewModel, Clean Architecture

Android Build CI iOS Build CI Validate Gradle Wrapper API Kotlin Hits License: MIT codecov Platform

Minimal Kotlin Multiplatform project with SwiftUI, Jetpack Compose.

  • Android (Jetpack compose)
  • iOS (SwiftUI)

Liked some of my work? Buy me a coffee (or more likely a beer)

Buy Me A Coffee

Modern Development

  • Kotlin Multiplatform
  • Jetpack Compose
  • Kotlin Coroutines & Flows
  • Dagger Hilt
  • SwiftUI
  • Koin Dependency Injection
  • FlowRedux State Management
  • Shared KMP ViewModel
  • Clean Architecture

Tech Stacks

Screenshots

Android (Light theme)

Android (Dark theme)

iOS (Light theme)

iOS (Dark theme)

Overall Architecture

What is shared?

  • domain: Domain models, UseCases, Repositories.
  • presentation: ViewModels, ViewState, ViewSingleEvent, ViewAction.
  • data: Repository Implementations, Remote Data Source, Local Data Source.
  • utils: Utilities, Logging Library

Unidirectional data flow - FlowRedux

RxRedux In a Nutshell

public sealed interface FlowReduxStore<Action, State> {
  /**
   * The state of this store.
   */
  public val stateFlow: StateFlow<State>

  /**
   * @return false if cannot dispatch action (this store was closed).
   */
  public fun dispatch(action: Action): Boolean

  /**
   * Call this method to close this store.
   * A closed store will not accept any action anymore, thus state will not change anymore.
   * All [SideEffect]s will be cancelled.
   */
  public fun close()

  /**
   * After calling [close] method, this function will return true.
   *
   * @return true if this store was closed.
   */
  public fun isClosed(): Boolean
}

Multiplatform ViewModel

open class GithubSearchViewModel(
  searchRepoItemsUseCase: SearchRepoItemsUseCase,
  private val savedStateHandle: SavedStateHandle,
) : ViewModel() {
  private val effectsContainer = GithubSearchSideEffectsContainer(searchRepoItemsUseCase)

  private val store = viewModelScope.createFlowReduxStore(
    initialState = GithubSearchState.initial(),
    sideEffects = effectsContainer.sideEffects,
    reducer = Reducer(flip(GithubSearchAction::reduce))
      .withLogger(githubSearchFlowReduxLogger())
  )

  val termStateFlow: NonNullStateFlowWrapper<String> = savedStateHandle.getStateFlow(TERM_KEY, "").wrap()
  val stateFlow: NonNullStateFlowWrapper<GithubSearchState> = store.stateFlow.wrap()
  val eventFlow: NonNullFlowWrapper<GithubSearchSingleEvent> = effectsContainer.eventFlow.wrap()

  init {
    store.dispatch(InitialSearchAction(termStateFlow.value))
  }

  @MainThread
  fun dispatch(action: GithubSearchAction): Boolean {
    if (action is GithubSearchAction.Search) {
      savedStateHandle[TERM_KEY] = action.term
    }
    return store.dispatch(action)
  }

  companion object {
    private const val TERM_KEY = "com.hoc081098.github_search_kmm.presentation.GithubSearchViewModel.term"

    /**
     * Used by non-Android platforms.
     */
    fun create(searchRepoItemsUseCase: SearchRepoItemsUseCase): GithubSearchViewModel =
      GithubSearchViewModel(searchRepoItemsUseCase, SavedStateHandle())
  }
}

Platform ViewModel

Android

Extends GithubSearchViewModel to use Dagger Constructor Injection.

@HiltViewModel
class DaggerGithubSearchViewModel @Inject constructor(
  searchRepoItemsUseCase: SearchRepoItemsUseCase,
  savedStateHandle: SavedStateHandle,
) : GithubSearchViewModel(searchRepoItemsUseCase, savedStateHandle)

iOS

Conform to ObservableObject and use @Published property wrapper.

import Foundation
import Combine
import shared
import sharedSwift

@MainActor
class IOSGithubSearchViewModel: ObservableObject {
  private let vm: GithubSearchViewModel

  @Published private(set) var state: GithubSearchState
  @Published private(set) var term: String = ""
  let eventPublisher: AnyPublisher<GithubSearchSingleEventKs, Never>

  init(vm: GithubSearchViewModel) {
    self.vm = vm

    self.eventPublisher = vm.eventFlow.asNonNullPublisher()
      .assertNoFailure()
      .map(GithubSearchSingleEventKs.init)
      .eraseToAnyPublisher()

    self.state = vm.stateFlow.value
    vm.stateFlow.subscribe(
      scope: vm.viewModelScope,
      onValue: { [weak self] in self?.state = $0 }
    )

    self.vm
      .termStateFlow
      .asNonNullPublisher(NSString.self)
      .assertNoFailure()
      .map { $0 as String }
      .assign(to: &$term)
  }

  @discardableResult
  func dispatch(action: GithubSearchAction) -> Bool {
    self.vm.dispatch(action: action)
  }

  deinit {
    Napier.d("\(self)::deinit")
    vm.clear()
  }
}

Download APK

Building & Develop

  • Android Studio Giraffe | 2022.3.1 (note: Java 17 is now the minimum version required).

  • Xcode 13.2 or later (due to use of new Swift 5.5 concurrency APIs).

  • Clone project: git clone https://github.com/hoc081098/GithubSearchKMM.git

  • Android: open project by Android Studio and run as usual.

  • iOS

    # Cd to root project directory
    cd GithubSearchKMM
    
    # Setup
    sh scripts/run_ios.sh

    There's a Build Phase script that will do the magic. 🧞
    Cmd + B to build
    Cmd + R to run.

    When you see any error like this:

    ./GithubSearchKMM/iosApp/iosApp/ContentView.swift:4:8: No such module 'sharedSwift'
    

    You can run the following commands (must select Read from disk inside Xcode):

    # go to iosApp directory
    cd iosApp
    
    # install pods
    pod install

    Then, you can build and run inside Xcode as usual.

LOC

--------------------------------------------------------------------------------
 Language             Files        Lines        Blank      Comment         Code
--------------------------------------------------------------------------------
 Kotlin                 106         7789          963          417         6409
 JSON                     7         3938            0            0         3938
 Swift                   16          903          118          102          683
 Markdown                 1          294           54            0          240
 Bourne Shell             2          250           28          116          106
 Batch                    1           92           21            0           71
 XML                      6           69            6            0           63
--------------------------------------------------------------------------------
 Total                  139        13335         1190          635        11510
--------------------------------------------------------------------------------

More Repositories

1

FlowExt

FlowExt | Kotlinx Coroutines Flow Extensions | Kotlinx Coroutines Flow Extensions. Extensions to the Kotlin Flow library | kotlin-flow-extensions | Coroutines Flow Extensions | Kotlin Flow extensions | kotlin flow extensions | Flow extensions
Kotlin
335
star
2

ComicReaderApp_MVI_Coroutine_RxKotlin_Jetpack

⚑️Comic reader app πŸ“˜ Learning MVVM / MVI with πŸŒ€ RxKotlin, Retrofit, Kotlinx Coroutine, Work Manager, Room, Firebase, AndroidX Startup, Clean Architecture, Arrow.Kt Functional Programming ... ❄️ androidx-startup, androidx-room, androidx-viewmodel, arrow-kt
Kotlin
284
star
3

node-auth-flutter-BLoC-pattern-RxDart

❀️ [active] 🌰[bloc_pattern] [rxdart] [stream] πŸ„ simple auth app flutter, server node.js, bloc pattern, rxdart 🍁🍁 functionalities: login, register, change password, change avatar, forgot password. pure rxdart bloc pattern. bloc pattern without library.
Dart
263
star
4

WeatherApp_MVI_sample

🌸[Functional reactive programming (FRP)] 🍁Simple Android weather forecast application written in Kotlin, using RxKotlin, Retrofit2, Mosby, Room Persistence ❄️MVI Pattern with Mosby Library
Kotlin
176
star
5

Refresh-Token-Sample

Android Refresh token with Retrofit, OkHttp, Kotlin Coroutines Mutex πŸ”‚ When multiple requests hit 401 (HTTP_UNAUTHORIZED), only single Refresh token request will be executed. After successful refresh, all pending requests will be executed concurrently. Example of encryption Jetpack Proto DataStore with Tink. Secured Proto DataStore. This example app shows how you can encrypt your data when using Proto DataStore from Jetpack.
Kotlin
122
star
6

kmp-viewmodel

πŸ”† Kotlin Multiplatform ViewModel. Kotlin Multiplatform MVVM. Common/Shared ViewModel in Kotlin Multiplatform - A Kotlin Multiplatform library that provides shared MVVM for UI applications. Components are lifecycle-aware on Android. Supports Android Parcelable, Kotlin Parcelize, AndroidX SavedStateHandle for restoring state after process death.
Kotlin
122
star
7

ViewBindingDelegate

Simple one-liner ViewBinding in Fragments and Activities with Kotlin πŸ„ Simplify usage of Android View Binding with Kotlin Property Delegates and solve behavior of Fragment’s ViewLifecycleOwner 🌱 ViewBindingPropertyDelegate
Kotlin
114
star
8

load_more_flutter_BLoC_pattern_RxDart_and_RxRedux

πŸ”₯ [FUNCTIONAL & REACTIVE PROGRAMMING (FRP)] ❄️[Pure RxDart] Paging ListView flutter 🌸 Load more flutter listview 🌱 Endless scrolling flutter πŸ‘ Flutter infinite list - BLoC pattern - rxdart - reactive stream flutter - RxDart.
Dart
95
star
9

Movie-Ticket-Booking

A movie tickets booking and management application using Flutter and NestJS. Flutter BLoC pattern and RxDart, rx_redux, stream_loader for state management. Firebase authentication, socket.io. Backend using NestJS, MongoDB database and Neo4j. Recommendation using Neo4j database and Collaborative filtering via Cypher query. Movie ticket booking flutter
Dart
86
star
10

find_room_flutter_BLoC_pattern_RxDart

πŸ‘˜ [FUNCTIONAL REACTIVE PROGRAMMING].πŸ’Ž The main purpose of repository is learning. πŸ“˜ A FLUTTER app help student find room 🏠 Using BLoC pattern with RxDart library, firebase as backend, .... Star 🌟 if it is helful πŸ’“ . In progress... ⚑
Dart
74
star
11

wallpaper-flutter

🐣🐣 Simple wallpaper use flutter sdk πŸ‚πŸ‚ Firestore, rxdart, sqlite, http 🍁🍁 Method channel Kotlin + Swift
Dart
59
star
12

solivagant

πŸ”† Compose Multiplatform Navigation library - 🌸 Pragmatic, type safety navigation for Compose Multiplatform. Based on Freeletics Khonshu Navigation. β™₯️ ViewModel, SavedStateHandle, Lifecycle, Multi-Backstacks, Transitions, Back-press handling, and more...
Kotlin
59
star
13

search-book-flutter-BLoC-pattern-rxdart

❄️[Functional reactive programming (FRP)] ⚑ Flutter search book using bloc pattern, rxdart 🌺 Star if it is helpful 🌺
Dart
53
star
14

flutter_validation_login_form_BLoC_pattern_RxDart

[Functional reactive programming (FRP)]πŸ’§ πŸ’§ πŸ’§ [Pure RxDart] Validation login form by using the BLoC pattern with RxDart - A new Flutter project featuring a faked authentication interface to demonstrate validation. Implemented with BloC pattern.
Dart
49
star
15

rx_shared_preferences

πŸŒ€ Shared preferences with RxDart Stream observation ⚑️ Reactive shared preferences for Flutter 🌸Reactive stream wrapper around SharedPreferences πŸ„ Lightweight and easy-to-use 🌱 A reactive key-value store for Flutter projects. Like shared_preferences, but with Streams πŸ“• Rx Shared Preferences for Flutter 🌿 rx_shared_preferences 🌰 rx_shared_preference 🍷 Reactive SharedPreferences for Flutter 🌰 A stream based wrapper over shared_preferences, allowing reactive key-value storage.
Dart
42
star
16

sqlbrite

🌼 RxDart Reactive stream sqflite(sqlite) for Flutter - Sqlbrite for flutter - A lightweight wrapper around sqflite which introduces reactive stream semantics to SQL operations. https://pub.dev/packages/sqlbrite
Dart
28
star
17

rxdart_ext

Some extension methods and classes built on top of RxDart. Companion with RxDart
Dart
25
star
18

Compose-Multiplatform-KmpViewModel-Unsplash-Sample

Compose Multiplatform and Kotlin Multiplatform ViewModel sample
Kotlin
24
star
19

node-auth-flutter

Simple flutter app: login and register | Version using BLoC pattern and RxDart: https://github.com/hoc081098/node-auth-flutter-BLoC-pattern-RxDart.git
Dart
24
star
20

sqlite_BLoC_pattern_RxDart

πŸ‚ ❀️ CRUD + sqflite + BLoC + RxDart + Clean code + Functional_Reactive_Programming πŸŒ€ ❀️
Dart
21
star
21

kotlin-channel-event-bus

A Kotlin Multiplatform library that provides a simple event bus implementation using KotlinX Coroutines Channels. Multi-keys, multi-producers, single-consumer and thread-safe event bus backed by kotlinx.coroutines.channels.Channels
Kotlin
19
star
22

rx_redux

πŸ„ Reactive redux store for Dart & Flutter 🌰 Redux implementation based on Dart Stream, with the power of RxDart
Dart
16
star
23

search-book-MVVM-MVI-RxSwift

πŸŒ€ Learning ⚑ Search book MVVM / MVI + RxSwift 🌸Just combine, filter, transform Stream...
Swift
13
star
24

disposebag

⚑ A package to help disposing StreamSubscriptions and closing Sinks. πŸŒ€
Dart
12
star
25

change_theme_language_BLoC_pattern_RxDart

[β„οΈπŸŒ€ FUNCTIONAL REACTIVE PROGRAMMING] [PURE RXDART] Change runtime theme - locale language flutter ⚑ A simple starter app with a drawer and a dynamic theme changer and persistent theme using the sharedpreferences. Change theme and language, using BLoC pattern, RxDart, SharedPreference, ... ⭐️ Flutter dynamic_theme ❀️:
Dart
12
star
26

hoc081098

Hi there πŸ‘‹, I'm Petrus Nguyα»…n ThΓ‘i Học
Dart
10
star
27

flutter_bloc_pattern

⚑ Base class, bloc provider and rxdart stream builder for BLoC pattern in flutter: https://pub.dev/packages/flutter_bloc_pattern
Dart
10
star
28

learn-graphql

πŸŒ€ Learning ⚑ Node.js GraphQL + Flutter + Angular 🌸
TypeScript
9
star
29

comic_app_server_nodejs

Node.js sever for android comic app | https://comic-app-081098.herokuapp.com/
TypeScript
9
star
30

PhDownloader

Petrus Hoc's Downloader - Simple, reactive and functional downloader for iOS Swift with the power of RxSwift, RxAlamofire - RxSwift Downloader - RxDownloader
Swift
9
star
31

dart_either

Either monad for Dart language and Flutter framework. The library for error handling and railway oriented programming. Supports `Monad comprehensions` (both `sync` and `async` versions). Supports `async map` and `async flatMap` hiding the boilerplate of working with asynchronous computations `Future<Either<L, R>>`. Error handler library for type-safe and easy work with errors on Dart and Flutter. Either is an alternative to Nullable value and Exceptions.
Dart
9
star
32

rxdart_flatmap_max_concurrent

Using `rxdart`'s `flatMap` with `maxConcurrent` to limit the number of concurrent requests.
Dart
8
star
33

node-auth-rest-api

JavaScript
8
star
34

Compose-Multiplatform-Todo-solivagant-koin-Sample

Compose Multiplatform Navigation and Kotlin Multiplatform ViewModel sample. solivagant and kmp-viewmodel sample
Kotlin
7
star
35

MovieDb-Search

Dart
6
star
36

bloc-rxdart-rx_redux-playground

⚑ BLoC RxDart playground πŸŒ€
Dart
6
star
37

number-to-Vietnamese-words

Convert number to Vietnamese words - number_to_vietnamese - Convert numbers to Vietnamese words. Supports large number, up to quintillion USAGE:
Kotlin
6
star
38

kotlin_playground

Kotlin playground with various files of examples, and personal experiments.
Kotlin
6
star
39

cancellation_token_hoc081098

Dart Cancellation Token. Inspired by CancellationToken in C#. A Dart utility package for easy async task cancellation.
Dart
6
star
40

timetable-lazylayout-jetpack-compose

Demo how to build a time table using LazyLayout API in AndroidX Jetpack Compose
Kotlin
5
star
41

leetcode

leetcode
Kotlin
5
star
42

StickyBottomSheet

Bottom sheet dialog fragment with sticky button on bottom of dialog.
Kotlin
5
star
43

Edoctor-MVI-Arrow-RxKotlin-Coroutines-Flow

Edoctor-MVI-Arrow-RxKotlin-Coroutines-Flow. Android Clean Architecture MVI Boilerplate
Kotlin
5
star
44

demo_redux

Simple CRUD flutter app, use redux and firestore
Dart
5
star
45

flutter_provider

:octocat: Flutter generic provider using InheritedWidget. Flutter generic provider using InheritedWidget. An helper to easily exposes a value using InheritedWidget without having to write one.
Dart
5
star
46

Astar-Dijkstra-GreedyBestFirstSearch-BreadthFirstSearch-DepthFirstSearch

Kotlin
4
star
47

did_change_dependencies

Return a Stream that emits null and done event when didChangeDependencies is called for the first time.
Dart
4
star
48

hacker_news

Learn flutter udemy course - bloc pattern
Dart
4
star
49

distinct_value_connectable_stream

🌸🌸 Distinct value connectable stream for RxDart, useful for BLoC pattern 🌰🌰
Dart
4
star
50

rxdart_batch_api_demo

Demonstrates how to use the `rxdart_ext` to handle batch API calls in Flutter
C++
3
star
51

CryptocurrencyTracker

Kotlin
3
star
52

codelab-basic-android-kotlin-compose-training-reply-app

Kotlin
3
star
53

DemoModules

DemoModules
Kotlin
3
star
54

Drink-Shop-App

Java
3
star
55

android-maps-compose-sample

More with maps in your Android app with Jetpack Compose (Kotlin)
Kotlin
3
star
56

http_client_hoc081098

Simple and powerful HTTP client for Flutter and Dart application, built on top of http, rxdart_ext and cancellation_token_hoc081098 packages.
Dart
3
star
57

flutter_github_search_rx_redux

πŸ”° Flutter github search using rx_redux | Functional & reactive programming with rxdart, rx_redux
Dart
3
star
58

KMP-App-Template-solivagant

Kotlin Multiplatform app template with shared UI, using solivagant-navigation
Kotlin
3
star
59

stream_loader_demo

🌸 stream_loader example🌼 fall in love with Stream - Functional Reactive Programming πŸ‚ https://pub.dev/packages/stream_loader 🌺
Dart
3
star
60

stream_loader

πŸ‚ A Flutter plugin for loading content asynchronously with Dart stream and RxDart. RxDart loader bloc. Reactive loader bloc. Simple reactive state management container - https://pub.dev/packages/stream_loader
Dart
3
star
61

stream_animated_list

stream_animated_list = StreamBuilder + AnimatedList
Dart
2
star
62

built_value_built_list_json_sample

Dart
2
star
63

nestjs-ngrx-tasks-management

learning
TypeScript
2
star
64

google_photos_gallery_test

google_photos_gallery_test
Dart
2
star
65

DemoCoroutinesChannelResult

Use `Kotlinx Coroutines Channel` to send and receive events between Fragments.
Kotlin
2
star
66

collapsing_toolbar_fab

Collapsing toolbar with fab
Dart
2
star
67

udemy-scala-advanced

Scala
2
star
68

CryptocurrencyTrackerFlutter

Dart
1
star
69

flutter-boilerplate

A boilerplate project created in flutter using RxDart BLoC pattern, Provider, Clean architecture
1
star
70

PhDownloaderTest

RxAlamofire + RxSwift Downloader
Swift
1
star
71

track-frontmost-app-macos

This is a simple application that tracks the frontmost application on macOS with a timestamp. It is written in Swift and uses SwiftUI for the UI.
Swift
1
star
72

comic_app_bloc_pattern_rxdart

🌺🌺 Comic reader app - BLoC pattern - RxDart 🌱🌱 Functional reactive programming ⚑ ⚑ ⚑
Dart
1
star
73

hoc081098-code

Euler problems, DS & Algo | Kotlin, Ruby, Elixir, Dart, Swift, Java, Typescript, Javascript, ...
C++
1
star
74

stop_watch_flutter_bloc_rxdart

🌰🌰 Stop watch flutter bloc rxdart demo
Dart
1
star
75

nested_navigation

Flutter nested navigation with BottomNavigationBar
Dart
1
star
76

ngdart_bookmark_manager

Dart
1
star