From c2ed738640679ad47427d26707ad89f3e2f6e63d Mon Sep 17 00:00:00 2001 From: Aleksey Mikhailov Date: Sat, 19 Oct 2019 11:14:56 +0700 Subject: [PATCH 1/4] ios: add support of invokeOnTimeout to UIDispatcher --- .../moko/mvvm/viewmodel/UIDispatcher.kt | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/mvvm/src/iosMain/kotlin/dev/icerock/moko/mvvm/viewmodel/UIDispatcher.kt b/mvvm/src/iosMain/kotlin/dev/icerock/moko/mvvm/viewmodel/UIDispatcher.kt index d620e3e8..5724bea7 100644 --- a/mvvm/src/iosMain/kotlin/dev/icerock/moko/mvvm/viewmodel/UIDispatcher.kt +++ b/mvvm/src/iosMain/kotlin/dev/icerock/moko/mvvm/viewmodel/UIDispatcher.kt @@ -35,4 +35,24 @@ internal class UIDispatcher : CoroutineDispatcher(), Delay { } } } + + override fun invokeOnTimeout(timeMillis: Long, block: Runnable): DisposableHandle { + var disposed = false + dispatch_after( + `when` = dispatch_time( + DISPATCH_TIME_NOW, + timeMillis * NSEC_PER_MSEC.toLong() + ), + queue = mQueue + ) { + if (disposed) return@dispatch_after + + block.run() + } + return object : DisposableHandle { + override fun dispose() { + disposed = true + } + } + } } \ No newline at end of file From 0cc9a7efb95277ff9c11d39c8ec52ff22175dade Mon Sep 17 00:00:00 2001 From: Aleksey Mikhailov Date: Sat, 19 Oct 2019 11:24:43 +0700 Subject: [PATCH 2/4] rename coroutineScope to viewModelScope as in AAC --- README.md | 4 ++-- .../kotlin/dev/icerock/moko/mvvm/viewmodel/ViewModel.kt | 4 ++-- .../kotlin/dev/icerock/moko/mvvm/viewmodel/ViewModel.kt | 2 +- .../kotlin/dev/icerock/moko/mvvm/viewmodel/ViewModel.kt | 4 ++-- .../kotlin/com/icerockdev/library/sample6/LoginViewModel.kt | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index d9f44725..0a73cd8d 100755 --- a/README.md +++ b/README.md @@ -322,7 +322,7 @@ class LoginViewModel( val emailValue = email.value val passwordValue = password.value - coroutineScope.launch { + viewModelScope.launch { _isLoading.value = true try { @@ -346,7 +346,7 @@ class LoginViewModel( } } ``` -`coroutineScope` is a field of the `ViewModel` class with a default Dispatcher - `UI` on both platforms. +`viewModelScope` is a `CoroutineScope` field of the `ViewModel` class with a default Dispatcher - `UI` on both platforms. All coroutines will be canceled in `onCleared` automatically. #### Android `LoginActivity.kt`: diff --git a/mvvm/src/androidMain/kotlin/dev/icerock/moko/mvvm/viewmodel/ViewModel.kt b/mvvm/src/androidMain/kotlin/dev/icerock/moko/mvvm/viewmodel/ViewModel.kt index 98d73959..382d8edf 100644 --- a/mvvm/src/androidMain/kotlin/dev/icerock/moko/mvvm/viewmodel/ViewModel.kt +++ b/mvvm/src/androidMain/kotlin/dev/icerock/moko/mvvm/viewmodel/ViewModel.kt @@ -11,11 +11,11 @@ import kotlinx.coroutines.cancel actual open class ViewModel actual constructor() : ViewModel() { // for now dispatcher fixed on Main. after implementing multithread coroutines on native - we can change it - protected actual val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.Main) + protected actual val viewModelScope: CoroutineScope = CoroutineScope(Dispatchers.Main) actual override fun onCleared() { super.onCleared() - coroutineScope.cancel() + viewModelScope.cancel() } } diff --git a/mvvm/src/commonMain/kotlin/dev/icerock/moko/mvvm/viewmodel/ViewModel.kt b/mvvm/src/commonMain/kotlin/dev/icerock/moko/mvvm/viewmodel/ViewModel.kt index e7ffe2b7..9eeac9f9 100644 --- a/mvvm/src/commonMain/kotlin/dev/icerock/moko/mvvm/viewmodel/ViewModel.kt +++ b/mvvm/src/commonMain/kotlin/dev/icerock/moko/mvvm/viewmodel/ViewModel.kt @@ -7,7 +7,7 @@ package dev.icerock.moko.mvvm.viewmodel import kotlinx.coroutines.CoroutineScope expect open class ViewModel() { - protected val coroutineScope: CoroutineScope + protected val viewModelScope: CoroutineScope protected open fun onCleared() } diff --git a/mvvm/src/iosMain/kotlin/dev/icerock/moko/mvvm/viewmodel/ViewModel.kt b/mvvm/src/iosMain/kotlin/dev/icerock/moko/mvvm/viewmodel/ViewModel.kt index c3e2b75a..19168a2c 100644 --- a/mvvm/src/iosMain/kotlin/dev/icerock/moko/mvvm/viewmodel/ViewModel.kt +++ b/mvvm/src/iosMain/kotlin/dev/icerock/moko/mvvm/viewmodel/ViewModel.kt @@ -9,9 +9,9 @@ import kotlinx.coroutines.cancel actual open class ViewModel actual constructor() { // for now dispatcher fixed on Main. after implementing multithread coroutines on native - we can change it - protected actual val coroutineScope: CoroutineScope = CoroutineScope(UIDispatcher()) + protected actual val viewModelScope: CoroutineScope = CoroutineScope(UIDispatcher()) protected actual open fun onCleared() { - coroutineScope.cancel() + viewModelScope.cancel() } } diff --git a/sample/mpp-library/src/commonMain/kotlin/com/icerockdev/library/sample6/LoginViewModel.kt b/sample/mpp-library/src/commonMain/kotlin/com/icerockdev/library/sample6/LoginViewModel.kt index cf633f06..5cec5def 100644 --- a/sample/mpp-library/src/commonMain/kotlin/com/icerockdev/library/sample6/LoginViewModel.kt +++ b/sample/mpp-library/src/commonMain/kotlin/com/icerockdev/library/sample6/LoginViewModel.kt @@ -31,7 +31,7 @@ class LoginViewModel( val emailValue = email.value val passwordValue = password.value - coroutineScope.launch { + viewModelScope.launch { _isLoading.value = true try { From f405ab253b9b3ce61244a94a08280597063822c2 Mon Sep 17 00:00:00 2001 From: Aleksey Mikhailov Date: Sat, 19 Oct 2019 11:42:23 +0700 Subject: [PATCH 3/4] add LiveData to Flow transform --- .../moko/mvvm/livedata/LiveDataCoroutines.kt | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 mvvm/src/commonMain/kotlin/dev/icerock/moko/mvvm/livedata/LiveDataCoroutines.kt diff --git a/mvvm/src/commonMain/kotlin/dev/icerock/moko/mvvm/livedata/LiveDataCoroutines.kt b/mvvm/src/commonMain/kotlin/dev/icerock/moko/mvvm/livedata/LiveDataCoroutines.kt new file mode 100644 index 00000000..5322a0d7 --- /dev/null +++ b/mvvm/src/commonMain/kotlin/dev/icerock/moko/mvvm/livedata/LiveDataCoroutines.kt @@ -0,0 +1,19 @@ +/* + * Copyright 2019 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license. + */ + +package dev.icerock.moko.mvvm.livedata + +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.channelFlow + +@UseExperimental(ExperimentalCoroutinesApi::class) +fun LiveData.asFlow(): Flow = channelFlow { + val observer: (T) -> Unit = { offer(it) } + + addObserver(observer) + + awaitClose { removeObserver(observer) } +} From 95f92e3d435e4bfaf71448264277cc60efbbcfde Mon Sep 17 00:00:00 2001 From: Aleksey Mikhailov Date: Sat, 19 Oct 2019 11:48:09 +0700 Subject: [PATCH 4/4] up version --- MultiPlatformLibraryMvvm.podspec | 2 +- README.md | 5 +++-- buildSrc/src/main/kotlin/Versions.kt | 2 +- sample/ios-app/Podfile | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/MultiPlatformLibraryMvvm.podspec b/MultiPlatformLibraryMvvm.podspec index fe0bdd4b..d80b17d1 100644 --- a/MultiPlatformLibraryMvvm.podspec +++ b/MultiPlatformLibraryMvvm.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |spec| spec.name = 'MultiPlatformLibraryMvvm' - spec.version = '0.1.0' + spec.version = '0.3.0' spec.homepage = 'https://github.com/icerockdev/moko-mvvm' spec.source = { :git => "https://github.com/icerockdev/moko-mvvm.git", :tag => "release/#{spec.version}" } spec.authors = 'IceRock Development' diff --git a/README.md b/README.md index 0a73cd8d..a956bf08 100755 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ This is a Kotlin Multiplatform library that provides architecture components of - kotlin 1.3.50 - 0.1.0 - 0.2.0 + - 0.3.0 ## Installation root build.gradle @@ -44,7 +45,7 @@ allprojects { project build.gradle ```groovy dependencies { - commonMainApi("dev.icerock.moko:mvvm:0.2.0") + commonMainApi("dev.icerock.moko:mvvm:0.3.0") } ``` @@ -55,7 +56,7 @@ enableFeaturePreview("GRADLE_METADATA") On iOS, in addition to the Kotlin library add in Podfile ```ruby -pod 'MultiPlatformLibraryMvvm', :git => 'https://github.com/icerockdev/moko-mvvm.git', :tag => 'release/0.2.0' +pod 'MultiPlatformLibraryMvvm', :git => 'https://github.com/icerockdev/moko-mvvm.git', :tag => 'release/0.3.0' ``` **`MultiPlatformLibraryMvvm` CocoaPod requires that the framework compiled from Kotlin be named `MultiPlatformLibrary` and be connected as a CocoaPod `MultiPlatformLibrary`. diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt index ed06e207..d2271e84 100755 --- a/buildSrc/src/main/kotlin/Versions.kt +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -22,7 +22,7 @@ object Versions { const val coroutines = "1.3.0" const val mokoCore: String = "0.1.0" const val mokoResources: String = "0.3.0" - const val mokoMvvm: String = "0.2.0" + const val mokoMvvm: String = "0.3.0" } } } \ No newline at end of file diff --git a/sample/ios-app/Podfile b/sample/ios-app/Podfile index ac8bd419..8ca660ff 100644 --- a/sample/ios-app/Podfile +++ b/sample/ios-app/Podfile @@ -13,6 +13,6 @@ target 'TestProj' do # MultiPlatformLibrary # для корректной установки фреймворка нужно сначала скомпилировать котлин библиотеку - compile-kotlin-framework.sh (в корневой директории репозитория) pod 'MultiPlatformLibrary', :path => '../mpp-library' - pod 'MultiPlatformLibraryMvvm', :git => 'https://github.com/icerockdev/moko-mvvm.git', :tag => 'release/0.2.0' + pod 'MultiPlatformLibraryMvvm', :git => 'https://github.com/icerockdev/moko-mvvm.git', :tag => 'release/0.3.0' pod 'MultiPlatformLibraryResources', :git => 'https://github.com/icerockdev/moko-resources.git', :tag => 'release/0.3.0' end