A local storage management library for Kotlin Multiplatform Mobile iOS and android
Features
- iOS and Android local storage in one interface
- Provides general storage (UserDefaults, SharedPreferences)
- Provides secure storage (Keychain, EncryptedPreferences)
- Annotation is provided to create a custom class only by defining an interface
- Common interface available on KMM Shared
Requirements
- iOS
- Deployment target 10.0 or higher
- Android
- minSdkVersion 21
Installation
Default Gradle Settings
Add below gradle settings into your KMP (Kotlin Multiplatform Project)
build.gradle.kts in shared
plugins {
id("com.android.library")
kotlin("multiplatform")
}
val sharedStorageVersion = "1.0.1"
val sharedStorage = "com.linecorp.abc:kmm-shared-storage:$sharedStorageVersion"
kotlin {
sourceSets {
ios {
binaries
.filterIsInstance<Framework>()
.forEach {
it.transitiveExport = true
it.export(sharedStorage)
}
}
android()
val commonMain by getting {
dependencies {
implementation(sharedStorage)
}
}
val androidMain by getting {
dependencies {
implementation(sharedStorage)
api(sharedStorage)
}
}
val iosMain by getting {
dependencies {
implementation(sharedStorage)
api(sharedStorage)
}
}
}
}
Usage
To store general value
Android
SharedStorage.save(100, "key::Int")
SharedStorage.save(100f, "key::Float")
SharedStorage.save(102L, "key::Long")
SharedStorage.save(true, "key::Boolean")
SharedStorage.save("String", "key::String")
iOS
SharedStorage.Companion().save(value: 100, forKey: "key::Int")
SharedStorage.Companion().save(value: 100.0, forKey: "key::Float")
SharedStorage.Companion().save(value: 102.0, forKey: "key::Long")
SharedStorage.Companion().save(value: true, forKey: "key::Boolean")
SharedStorage.Companion().save(value: "String", forKey: "key::String")
To get general value
Android
SharedStorage.load("key::Int", 0)
SharedStorage.load("key::Float", 0f)
SharedStorage.load("key::Long", 0L)
SharedStorage.load("key::Boolean", false)
SharedStorage.load("key::String", "")
iOS
SharedStorage.Companion().load(key: "key::Int", default: 0)
SharedStorage.Companion().load(key: "key::Float", default: 0.0)
SharedStorage.Companion().load(key: "key::Long", default: 0.0)
SharedStorage.Companion().load(key: "key::Boolean", default: "")
SharedStorage.Companion().load(key: "key::String", default: "")
To store secure value
Android
SharedStorage.secureSave("SecureString", "key::SecureString")
iOS
SharedStorage.Companion().secureSave(value: "SecureString", forKey: "key::SecureString")
To get secure value
Android
SharedStorage.secureLoad("key::SecureString", "")
iOS
SharedStorage.Companion().secureLoad(key: "key::SecureString", default: "")
Advanced
To Use Annotations for Code Generating (Android only)
settings.gradle.kts in project root
val kotlinVersion = "1.5.21"
val kspVersion = "1.5.21-1.0.0-beta07"
plugins {
kotlin("jvm") version kotlinVersion
id("com.google.devtools.ksp") version kspVersion
}
build.gradle.kts in androidApp
val sharedStorageVersion = "1.0.1"
dependencies {
implementation(project(":shared"))
implementation("com.linecorp.abc.kmm-shared-storage-annotations:$sharedStorageVersion")
ksp("com.linecorp.abc:kmm-shared-storage-annotations:$sharedStorageVersion")
}
Define your interface for code generating
package androidApp.sample
import com.linecorp.abc.sharedstorage.annotations.Secure
import com.linecorp.abc.sharedstorage.annotations.SharedStorage
@SharedStorage
interface AppData {
var someInt: Int
var someFloat: Float
val someLong: Long
val someDouble: Double
val someBoolean: Boolean
val someString: String
@Secure val someSecureString: String
}
Using for your android project
SharedAppData.someInt = 501
SharedAppData.someFloat = 501.5f
SharedAppData.someLong = 500500L
SharedAppData.someBoolean = true
SharedAppData.someString = "I'm Some String"
SharedAppData.someSecureString = "I'm Encrypted String"
Integration with @propertyWrapper on iOS
struct AppData {
@General(key: "SomeInt", default: 0)
static var someInt: Int
@General(key: "SomeFloat", default: 0)
static var someFloat: Float
@General(key: "SomeDouble", default: 0)
static var someDouble: Double
@General(key: "SomeBool", default: false)
static var someBool: Bool
@General(key: "SomeString", default: "")
static var someString: String
@Secure(key: "SomeSecure", default: "")
static var secureString: String
}
@propertyWrapper
struct General<Value> {
let key: String
let `default`: Value
var wrappedValue: Value {
get { SharedStorage.Companion().load(key: key, default: `default`) as? Value ?? `default` }
set { SharedStorage.Companion().save(value: newValue, forKey: key) }
}
}
@propertyWrapper
struct Secure {
let key: String
let `default`: String
var wrappedValue: String {
get { SharedStorage.Companion().secureLoad(key: key, default: `default`) }
set { SharedStorage.Companion().secureSave(value: newValue, forKey: key) }
}
}