Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

androidx.lifecycle 2.8.0 #68

Merged
merged 9 commits into from
May 9, 2024
4 changes: 3 additions & 1 deletion KMMViewModelCore/KMMViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,7 @@ import KMMViewModelCoreObjC
public protocol KMMViewModel: ObservableObject where ObjectWillChangePublisher == ObservableObjectPublisher {
/// The `ViewModelScope` of this `KMMViewModel`.
var viewModelScope: ViewModelScope { get }
func onCleared()
/// Internal KMM-ViewModel function used to clear the ViewModel.
/// - Warning: You should NOT call this yourself!
func clear()
}
2 changes: 1 addition & 1 deletion KMMViewModelCore/ObservableViewModelPublisher.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public final class ObservableViewModelPublisher: Publisher {
if let cancellable = viewModel as? Cancellable {
cancellable.cancel()
}
viewModel.onCleared()
viewModel.clear()
}
}

Expand Down
4 changes: 2 additions & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
kotlin = "1.9.23"
kotlinx-coroutines = "1.8.0"
android = "8.2.0"
androidx-lifecycle = "2.7.0"
androidx-lifecycle = "2.8.0-rc01"

# Sample versions
androidx-compose = "2023.10.01"
Expand All @@ -14,7 +14,7 @@ nativecoroutines = "1.0.0-ALPHA-26"
[libraries]
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx-coroutines" }
androidx-lifecycle-viewmodel-ktx = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", version.ref = "androidx-lifecycle" }
androidx-lifecycle-viewmodel = { module = "androidx.lifecycle:lifecycle-viewmodel", version.ref = "androidx-lifecycle" }

# Sample libraries
androidx-compose-bom = { module = "androidx.compose:compose-bom", version.ref = "androidx-compose" }
Expand Down
22 changes: 13 additions & 9 deletions kmm-viewmodel-core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,20 @@ kotlin {
@OptIn(ExperimentalKotlinGradlePluginApi::class)
applyDefaultHierarchyTemplate {
common {
group("other") {
group("androidx") {
withAndroidTarget()
group("ios")
withJvm()
withLinuxX64()
group("macos")
}
group("nonAndroidx") {
withJs()
group("linux")
withLinuxArm64()
group("mingw")
group("tvos")
withWasm()
group("watchos")
}
group("nonApple") {
withAndroidTarget()
Expand All @@ -32,7 +40,6 @@ kotlin {
}
}

//region Apple and Android targets
listOf(
macosX64(), macosArm64(),
iosArm64(), iosX64(), iosSimulatorArm64(),
Expand All @@ -48,8 +55,6 @@ kotlin {
androidTarget {
publishLibraryVariants("release")
}
//endregion
//region Other targets
jvm()
js {
browser()
Expand All @@ -64,7 +69,6 @@ kotlin {
nodejs()
d8()
}
//endregion

targets.all {
compilations.all {
Expand Down Expand Up @@ -93,9 +97,9 @@ kotlin {
}
}

androidMain {
val androidxMain by getting {
dependencies {
api(libs.androidx.lifecycle.viewmodel.ktx)
api(libs.androidx.lifecycle.viewmodel)
}
}
}
Expand All @@ -105,7 +109,7 @@ android {
namespace = "com.rickclephas.kmm.viewmodel"
compileSdk = 33
defaultConfig {
minSdk = 14
minSdk = 19
}
publishing {
singleVariant("release") {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.rickclephas.kmm.viewmodel

import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelStore
import androidx.lifecycle.viewmodel.CreationExtras
import kotlinx.coroutines.CoroutineScope
import kotlin.reflect.KClass

/**
* A Kotlin Multiplatform Mobile ViewModel.
*/
public actual abstract class KMMViewModel public actual constructor(
coroutineScope: CoroutineScope
): ViewModel(coroutineScope) {

public actual constructor(): this(DefaultCoroutineScope())

/**
* The [ViewModelScope] containing the [CoroutineScope] of this ViewModel.
*/
public actual val viewModelScope: ViewModelScope = ViewModelScope(coroutineScope)

/**
* Called when this ViewModel is no longer used and will be destroyed.
*/
public actual override fun onCleared() {
super.onCleared()
}

/**
* Internal KMM-ViewModel function used by the Swift implementation to clear the ViewModel.
* Warning: you should NOT call this yourself!
*/
@InternalKMMViewModelApi
public fun clear() {
// We can't directly call the internal clear function from AndroidX.
// To call it indirectly we use the public Store and Provider APIs instead.
val store = ViewModelStore()
ViewModelProvider.create(
store = store,
factory = object : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: KClass<T>, extras: CreationExtras): T {
@Suppress("UNCHECKED_CAST")
return this@KMMViewModel as T
}
}
)[KMMViewModel::class]
store.clear()
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.rickclephas.kmm.viewmodel

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.MainCoroutineDispatcher
import kotlinx.coroutines.SupervisorJob
import kotlin.coroutines.EmptyCoroutineContext

/**
* Creates a default [CoroutineScope] for a ViewModel,
* using the [Main.immediate][MainCoroutineDispatcher.immediate] dispatcher if available.
*
* [androidx/CloseableCoroutineScope.kt](https://cs.android.com/androidx/platform/frameworks/support/+/6a69101fd0edc8d02aa316df1f43e0552fd2d7c4:lifecycle/lifecycle-viewmodel/src/commonMain/kotlin/androidx/lifecycle/viewmodel/internal/CloseableCoroutineScope.kt;l=51-66)
*/
@Suppress("FunctionName")
internal fun DefaultCoroutineScope(): CoroutineScope {
val dispatcher = try {
Dispatchers.Main.immediate
} catch (_: NotImplementedError) {
EmptyCoroutineContext
} catch (_: IllegalStateException) {
EmptyCoroutineContext
}
return CoroutineScope(SupervisorJob() + dispatcher)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,13 @@ import kotlinx.coroutines.CoroutineScope

/**
* A Kotlin Multiplatform Mobile ViewModel.
*
* On Android this is a subclass of the Jetpack ViewModel.
*/
public expect abstract class KMMViewModel() {
public expect abstract class KMMViewModel(coroutineScope: CoroutineScope) {

public constructor()

/**
* The [ViewModelScope] containing the [CoroutineScope] of this ViewModel.
*
* On Android this is bound to `Dispatchers.Main.immediate`,
* where on Apple platforms it is bound to `Dispatchers.Main`.
*/
public val viewModelScope: ViewModelScope

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.rickclephas.kmm.viewmodel

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.cancel

/**
* A Kotlin Multiplatform Mobile ViewModel.
*/
public actual abstract class KMMViewModel public actual constructor(coroutineScope: CoroutineScope) {

public actual constructor(): this(DefaultCoroutineScope())

/**
* The [ViewModelScope] containing the [CoroutineScope] of this ViewModel.
*/
public actual val viewModelScope: ViewModelScope = ViewModelScope(coroutineScope)

/**
* Called when this ViewModel is no longer used and will be destroyed.
*/
public actual open fun onCleared() { }

/**
* Should be called to clear the ViewModel once it's no longer being used.
*/
public fun clear() {
viewModelScope.coroutineScope.cancel()
onCleared()
}
}

This file was deleted.