Djuro
07/31/2023, 12:33 PMSam
07/31/2023, 1:19 PMSam
07/31/2023, 1:19 PM// Common
expect open class ViewModel constructor(scope: CoroutineScope? = null) {
val viewModelScope: CoroutineScope
protected open fun onCleared()
protected open fun performSetup()
}
// Android
import androidx.lifecycle.ViewModel as AndroidXViewModel
import androidx.lifecycle.viewModelScope as androidXViewModelScope
actual open class ViewModel actual constructor(scope: CoroutineScope?) : AndroidXViewModel() {
actual val viewModelScope: CoroutineScope = scope ?: androidXViewModelScope
init {
viewModelScope.launch {
performSetup()
}
}
actual override fun onCleared() {
super.onCleared()
}
protected actual open fun performSetup() {
/* Perform any setup here rather than in init block */
}
actual interface StateWithGenericError {
actual interface ErrorState {
actual val state: GenericErrorState?
}
}
}
// iOS
/**
* Base class that provides a Kotlin/Native equivalent to the AndroidX `ViewModel`. In particular, this provides
* a [CoroutineScope][kotlinx.coroutines.CoroutineScope] which uses [Dispatchers.Main][kotlinx.coroutines.Dispatchers.Main]
* and can be tied into an arbitrary lifecycle by calling [clear] at the appropriate time.
*/
actual open class ViewModel actual constructor(scope: CoroutineScope?) {
actual val viewModelScope = scope ?: MainScope()
/**
* Override this to do any cleanup immediately before the internal [CoroutineScope][kotlinx.coroutines.CoroutineScope]
* is cancelled in [clear]
*/
protected actual open fun onCleared() {
/* Default No-Op */
}
/**
* Cancels the internal [CoroutineScope][kotlinx.coroutines.CoroutineScope]. After this is called, the ViewModel should
* no longer be used.
*/
fun clear() {
onCleared()
viewModelScope.cancel()
}
/**
* Create a [FlowAdapter] from this [Flow] to make it easier to interact with from Swift.
*/
fun <T : Any> Flow<T>.asCallbacks() = FlowAdapter(viewModelScope, this)
protected actual open fun performSetup() {
/* Overridden where needed */
}
}
class FlowAdapter<T : Any>(
private val scope: CoroutineScope,
private val flow: Flow<T>
) {
fun subscribe(
onEach: (item: T) -> Unit,
onComplete: () -> Unit = {},
onThrow: (error: Throwable) -> Unit = {}
): Canceller = JobCanceller(
flow.onEach { onEach(it) }
.catch { onThrow(it) }
.onCompletion { onComplete() }
.launchIn(scope)
)
}
interface Canceller {
fun cancel()
}
private class JobCanceller(private val job: Job) : Canceller {
override fun cancel() {
job.cancel()
}
}
Sam
07/31/2023, 1:20 PMTung97 Hl
07/31/2023, 2:17 PMJohn O'Reilly
07/31/2023, 2:45 PMDjuro
07/31/2023, 7:57 PMEmre
07/31/2023, 10:16 PMKashismails
08/01/2023, 6:19 AMFarid Benhaimoud
08/02/2023, 10:49 PM