diff --git a/src/androidMain/kotlin/ch/dreipol/dreimultiplatform/coroutines/BackgroundTask.kt b/src/androidMain/kotlin/ch/dreipol/dreimultiplatform/coroutines/BackgroundTask.kt new file mode 100644 index 0000000..68be707 --- /dev/null +++ b/src/androidMain/kotlin/ch/dreipol/dreimultiplatform/coroutines/BackgroundTask.kt @@ -0,0 +1,7 @@ +package ch.dreipol.dreimultiplatform.coroutines + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Job +import kotlinx.coroutines.launch + +actual fun CoroutineScope.launchBackgroundTask(block: suspend CoroutineScope.() -> Unit) : Job = launch(block = block) \ No newline at end of file diff --git a/src/commonMain/kotlin/ch/dreipol/dreimultiplatform/coroutines/BackgroundTask.kt b/src/commonMain/kotlin/ch/dreipol/dreimultiplatform/coroutines/BackgroundTask.kt new file mode 100644 index 0000000..d681301 --- /dev/null +++ b/src/commonMain/kotlin/ch/dreipol/dreimultiplatform/coroutines/BackgroundTask.kt @@ -0,0 +1,8 @@ +package ch.dreipol.dreimultiplatform.coroutines + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Job + +/** A task that continues running while the app is in the background on iOS. + */ +expect fun CoroutineScope.launchBackgroundTask(block: suspend CoroutineScope.() -> Unit) : Job \ No newline at end of file diff --git a/src/iosMain/kotlin/ch/dreipol/dreimultiplatform/coroutines/BackgroundTask.kt b/src/iosMain/kotlin/ch/dreipol/dreimultiplatform/coroutines/BackgroundTask.kt new file mode 100644 index 0000000..d2c469c --- /dev/null +++ b/src/iosMain/kotlin/ch/dreipol/dreimultiplatform/coroutines/BackgroundTask.kt @@ -0,0 +1,23 @@ +package ch.dreipol.dreimultiplatform.coroutines + +import co.touchlab.kermit.Logger +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.InternalCoroutinesApi +import kotlinx.coroutines.Job +import kotlinx.coroutines.cancel +import kotlinx.coroutines.launch +import platform.UIKit.UIApplication + +actual fun CoroutineScope.launchBackgroundTask(block: suspend CoroutineScope.() -> Unit) : Job = BackgroundTask(launch(block = block)) + +private class BackgroundTask(val underlyingJob: Job) : Job by underlyingJob { + private val backgroundTaskIdentifier = UIApplication.sharedApplication.beginBackgroundTaskWithExpirationHandler { + Logger.w { "Cancelling long running background task!" } + underlyingJob.cancel("Background Task is about to expire!") + } + + @OptIn(InternalCoroutinesApi::class) + private val completionHandle = underlyingJob.invokeOnCompletion(onCancelling = true) { + UIApplication.sharedApplication.endBackgroundTask(backgroundTaskIdentifier) + } +} \ No newline at end of file