A Kotlin Multiplatform library that simplifies scheduling and executing periodic background jobs across different platforms (iOS, and Android). This library provides an easy-to-use API for setting up jobs that run at specified intervals, ensuring that your application can perform tasks in the background efficiently.
NOTE: This library is in pre-release phase. Stable release publishing is expected to be by February 20th 2025.
- Cross-Platform Support: Works on Android & iOS
- Simple API: Easily define periodic jobs with customizable intervals.
- Flexible Interval Setting: Supports flexible interval configuration for job execution.
- Flexible Platform Configuration: Choose between running on Android only, iOS only or on both platforms.
- Platform-Specific Implementations: Adapts to platform-specific background task mechanisms (e.g., WorkManager on Android, background task APIs on iOS).
- Customizable Job Logic: Define custom logic to be executed in background tasks.
For android this library uses Android Work Manager to schedule jobs, which has an easy setup and it's all at runtime. However on iOS side of things, the job identifiers need to be registered at compile/build time of the application. For iOS these unique identifiers are setup in the target's Info.plist file.
To achieve a common solution this uses a gradle plugin, that let you define your background job identifiers in your build setup which stays common between the platforms and provides a solution where you don't have to manually setup the identifiers in your iOS setup and copy that on Android for reference in your common/shared code.
Add the following gradle plugin in your build.gradle.kts
of shared
/common gradle module that is shared between Android & iOS
plugins {
id ("io.github.kprakash2.kmp-workmanager-gradle") version "<version>"
}
Add the following block in your build.gradle.kts
of shared
/common gradle module that is shared between Android & iOS
kmpworkmanager {
jobIdentifiers = setOf<String>(<JOB_ID1>, <JOB_ID2>, ...)
iosAppInfoPlistPath = <Path to your iOSApp's Info.plist file>
packageName = <root package name for your module's source set>
sourceSetDirectory = <path to your modules source set>
className = <background job type enum class name> // default: `BackgroundJobIdentifiers`
}
jobIdentifiers
: Set of identifiers for your background jobs. Identifiers should be all upper case and without any whitespaces.iosAppInfoPlistPath
: Path to your iOS App's Info.plist file. Usually it will be similar to../iosApp/iosApp/Info.plist
packageName
: Root Package name of your module's sourceset.sourceSetDirectory
: File property pointing to your module's common source set. Usually it will be similar toproject.file("src/commonMain/kotlin")
classNme
: This is optional, if you'd like to use a custom name of the background job type enum class name.
The above extension will configure all compile
type tasks in your module to run prepareKmpWorkManagerConfig
which will create a config file in your source set which you can use to register your jobs at runtime.
To include the library in your Kotlin Multiplatform project, add the following dependencies in your shared
module's build.gradle.kts
file:
kotlin {
sourceSets {
val commonMain by getting {
dependencies {
implementation("io.github.kprakash2:kmp-workmanager:<version>")
}
}
}
}
Once you have compiled your project with above setup, in your module's sourceset there would be enum class (BackgroundJobIdentifiers
or className
if you provided the parameter in kmpWorkManager
configuration) available with all your job identifiers.
This provider should return a BackgroundJob
type for all your background job identifiers.
class MyBackgroundJobProvider(): BackgroundJobProvider<BackgroundJobIdentifiers> {
override suspend fun <T: BackgroundJobType> getBackgroundJob(type: T): BackgroundJob {
return when (type as BackgroundJobIdentifiers) {
...
...
}
}
}
You can declare the following function or also tie it to your dependency injection framework if you're using any and then call this from each platform specific code.
Note: context
can be null for iOS, it's only required for Android platform.
// In commonMain
fun initializeBackgroundWorkRepository(context: Any?) {
BackgroundWorkRepository.initialize(
context, // This can be null for iOS
MyBackgroundJobProvider()
)
}
// In androidMain
initializeBackgroundWorkRepository(context)
// In iosMain
initializeBackgroundWorkRepository(null)
You can configure each of your background job type with multiple parameters using BackgroundJobConfiguration
val backgroundWorkRepository = BackgroundWorkRepository.getInstance()
val jobsConfiguration = BackgroundJobIdentifiers.entries.map {
it to when (it) {
BackgroundJobIdentifiers.<id> -> BackgroundJobConfiguration(...)
....
}
}
backgroundWorkRepository.registerJobs(jobsConfiguration)
BackgroundWorkRepository.getInstance()
: Provide an instance ofBackgroundWorkRepository
. Make sure to callBackgroundWorkRepository.initialize()
before this. See Background Job ConfigurationBackgroundJobConfiguration
: Represents the configuration for your background jobbackgroundWorkRepository.registerJobs(..)
: Registers all of your background job. Make sure to call this before you callbackgroundWorkRepository.schedule(...)
. This is specially required for iOS platform as we need to register all BGApp tasks before they can be scheduled. See Apple documentation for more details.
val backgroundWorkRepository = BackgroundWorkRepository.getInstance()
backgroundWorkRepository.schedule(...)
val backgroundWorkRepository = BackgroundWorkRepository.getInstance()
backgroundWorkRepository.cancelJob(...)
Example:
BackgroundJobConfiguration(
intervalInMillis = 900000,
periodic = true,
supportedPlatform = SupportedPlatform.ALL
)
intervalInMillis
: Represents interval between each periodic task run in milliseconds. Both Android and iOS only support 15 minutes of minimum interval.periodic
: If task is recurring, this should be set totrue
. If the task needs to be run just once, this should be set tofalse
.supportedPlatform
: Represents the platform on which the task should run. It can beANRDOID_ONLY
,IOS_ONLY
,ALL
. If you want your task to run on both Android and IOS, useALL
.
- Setup Github Actions
- Add publishing and publish 1st version
- Add test for
shared
module - Add test for
kmp-workmanager
plugin - Add support for high frequency periodic jobs (recurring at frequency of less than 15 mins.)
- Add support for backoff strategies
- Add support for Network constraints
- Add support for Phone Battery constraints
Copyright 2025 Kartik Prakash
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.