
Enables shared logic across platforms with networking capabilities using Ktor and cross-platform key-value storage utilizing datastore and multiplatform-settings. Seamlessly handles requests and data storage.
A Kotlin Multiplatform (KMP) library for shared logic and common utilities across platforms (Android, iOS)
Add the library dependency to your build.gradle.kts or build.gradle file.
dependencies {
implementation("com.paleblueapps:kmpcore:[latest-version]")
}// Create ApiManager
val apiManager = ApiManager(
baseUrl = "https://api.example.com/",
enableLogging = true,
defaultRequestConfig = {
header("X-ID-device", "android")
header("X-API-Version", "1")
},
responseValidator = { response ->
when (response.status.value) {
in 200..299 -> {}
401 -> throw Error.UnauthorizedError
in 400..499 -> throw Error.BackendResponseError
else -> throw Error.BackendError
}
},
) // Or you can pass the custom Ktor client instance
// Usage
val endpoint = Endpoint("/users", HttpMethod.Get)
val userResult: Result<User> = apiManager.call(endpoint)
userResult.onSuccess { user ->
println("User ID: ${user.id}, User Name: ${user.name}")
}.onFailure { exception ->
println("Error: ${exception.message}")
}// Create PreferencesManager
// file: commonMain/PreferencesManager.kt
val preferencesFileName = "preferences.preferences_pb" // NOTE: this file extension should be preferences_pb
val encryptedPreferencesFileName = "encrypted_preferences"
expect val preferencesManager: PreferencesManager
// file: androidMain/PreferencesManager.kt
actual val preferencesManager = PreferencesManager(
context = androidContext(), // pass the android context here either manually or using DI framework
preferencesFileName = preferencesFileName,
encryptedPreferencesFileName = encryptedPreferencesFileName,
)
// file: iosMain/PreferencesManager.kt
actual val preferencesManager = PreferencesManager(
preferencesFileName = preferencesFileName,
encryptedPreferencesFileName = encryptedPreferencesFileName,
)
// Encrypted storage example
preferencesManager.putEncryptedString("user_token", token)
val userToken = preferencesManager.getEncryptedString("user_token")
// Non encrypted storage example
preferencesManager.putString("user_id", token)
val userId = preferencesManager.getString("user_id")// Create CurrencyFormatter
val currencyFormatter = CurrencyFormatter()
// Usage
val formattedAmount = currencyFormatter.format(
amount = 1234.56,
currencyCode = "USD",
withCurrencySymbol = true,
minimumFractionDigits = 2,
maximumFractionDigits = 2
) // "$1,234.56"// Create NumberFormatter
val numberFormatter = NumberFormatter()
// Usage
val formattedNumber = numberFormatter.format(
number = 1234567.89,
localeCode = "en-US",
) // "1,234,567.89"The RatingService helps automate the process of asking users for app ratings or feedback. It tracks user actions and ensures that prompts are not shown too frequently.
In your common code, you can define the RatingService instance.
// commonMain
expect val ratingService: RatingServiceOn Android, provide the applicationContext:
// androidMain
actual val ratingService: RatingService = RatingService(applicationContext)
// In your Activity, bind it to handle dialog presentation
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
ratingService.bind(this)
}
}On iOS:
// iosMain
actual val ratingService: RatingService = RatingService()Configure the service with custom dialog messages and rules:
ratingService.configure(
ratingDialogConfig = DialogConfig(
title = "Enjoying the app?",
message = "Would you like to rate us on the store?",
positiveButtonText = "Rate Now",
negativeButtonText = "Maybe Later"
),
feedbackDialogConfig = DialogConfig(
title = "Feedback",
message = "How can we improve?",
positiveButtonText = "Send Feedback",
negativeButtonText = "Cancel"
),
snoozeDuration = 30.days,
minActionsNeededForAskingReview = 5
)Log user actions (e.g., when a user completes a task) and attempt to show the rating flow:
// Log an action
ratingService.logUserAction()
// Start the rating flow
ratingService.startRatingFlow { event ->
when (event) {
RatingEvent.OnRatingPositiveClick -> {
// Redirect to App Store / Play Store
}
RatingEvent.OnFeedbackPositiveClick -> {
// Open feedback form or email
}
else -> {
// Handle other events if needed
}
}
}A Kotlin Multiplatform (KMP) library for shared logic and common utilities across platforms (Android, iOS)
Add the library dependency to your build.gradle.kts or build.gradle file.
dependencies {
implementation("com.paleblueapps:kmpcore:[latest-version]")
}// Create ApiManager
val apiManager = ApiManager(
baseUrl = "https://api.example.com/",
enableLogging = true,
defaultRequestConfig = {
header("X-ID-device", "android")
header("X-API-Version", "1")
},
responseValidator = { response ->
when (response.status.value) {
in 200..299 -> {}
401 -> throw Error.UnauthorizedError
in 400..499 -> throw Error.BackendResponseError
else -> throw Error.BackendError
}
},
) // Or you can pass the custom Ktor client instance
// Usage
val endpoint = Endpoint("/users", HttpMethod.Get)
val userResult: Result<User> = apiManager.call(endpoint)
userResult.onSuccess { user ->
println("User ID: ${user.id}, User Name: ${user.name}")
}.onFailure { exception ->
println("Error: ${exception.message}")
}// Create PreferencesManager
// file: commonMain/PreferencesManager.kt
val preferencesFileName = "preferences.preferences_pb" // NOTE: this file extension should be preferences_pb
val encryptedPreferencesFileName = "encrypted_preferences"
expect val preferencesManager: PreferencesManager
// file: androidMain/PreferencesManager.kt
actual val preferencesManager = PreferencesManager(
context = androidContext(), // pass the android context here either manually or using DI framework
preferencesFileName = preferencesFileName,
encryptedPreferencesFileName = encryptedPreferencesFileName,
)
// file: iosMain/PreferencesManager.kt
actual val preferencesManager = PreferencesManager(
preferencesFileName = preferencesFileName,
encryptedPreferencesFileName = encryptedPreferencesFileName,
)
// Encrypted storage example
preferencesManager.putEncryptedString("user_token", token)
val userToken = preferencesManager.getEncryptedString("user_token")
// Non encrypted storage example
preferencesManager.putString("user_id", token)
val userId = preferencesManager.getString("user_id")// Create CurrencyFormatter
val currencyFormatter = CurrencyFormatter()
// Usage
val formattedAmount = currencyFormatter.format(
amount = 1234.56,
currencyCode = "USD",
withCurrencySymbol = true,
minimumFractionDigits = 2,
maximumFractionDigits = 2
) // "$1,234.56"// Create NumberFormatter
val numberFormatter = NumberFormatter()
// Usage
val formattedNumber = numberFormatter.format(
number = 1234567.89,
localeCode = "en-US",
) // "1,234,567.89"The RatingService helps automate the process of asking users for app ratings or feedback. It tracks user actions and ensures that prompts are not shown too frequently.
In your common code, you can define the RatingService instance.
// commonMain
expect val ratingService: RatingServiceOn Android, provide the applicationContext:
// androidMain
actual val ratingService: RatingService = RatingService(applicationContext)
// In your Activity, bind it to handle dialog presentation
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
ratingService.bind(this)
}
}On iOS:
// iosMain
actual val ratingService: RatingService = RatingService()Configure the service with custom dialog messages and rules:
ratingService.configure(
ratingDialogConfig = DialogConfig(
title = "Enjoying the app?",
message = "Would you like to rate us on the store?",
positiveButtonText = "Rate Now",
negativeButtonText = "Maybe Later"
),
feedbackDialogConfig = DialogConfig(
title = "Feedback",
message = "How can we improve?",
positiveButtonText = "Send Feedback",
negativeButtonText = "Cancel"
),
snoozeDuration = 30.days,
minActionsNeededForAskingReview = 5
)Log user actions (e.g., when a user completes a task) and attempt to show the rating flow:
// Log an action
ratingService.logUserAction()
// Start the rating flow
ratingService.startRatingFlow { event ->
when (event) {
RatingEvent.OnRatingPositiveClick -> {
// Redirect to App Store / Play Store
}
RatingEvent.OnFeedbackPositiveClick -> {
// Open feedback form or email
}
else -> {
// Handle other events if needed
}
}
}