All Projects → AutSoft → Krate

AutSoft / Krate

Licence: apache-2.0
A SharedPreferences wrapper powered by Kotlin delegates

Programming Languages

kotlin
9241 projects

Projects that are alternatives of or similar to Krate

Binaryprefs
Rapidly fast and lightweight re-implementation of SharedPreferences which stores each preference in files separately, performs disk operations via NIO with memory mapped byte buffers and works IPC (between processes). Written from scratch.
Stars: ✭ 484 (+127.23%)
Mutual labels:  serialization, sharedpreferences
Prefser
Wrapper for Android SharedPreferences with object serialization and RxJava Observables
Stars: ✭ 228 (+7.04%)
Mutual labels:  serialization, sharedpreferences
Oksharedprefs
通过注解生成SharedPreferences包装类,解决跨进程数据访问不同步的问题。
Stars: ✭ 183 (-14.08%)
Mutual labels:  sharedpreferences
Dart Json Mapper
Serialize / Deserialize Dart Objects to / from JSON
Stars: ✭ 206 (-3.29%)
Mutual labels:  serialization
Django Rest Marshmallow
Marshmallow schemas for Django REST framework
Stars: ✭ 198 (-7.04%)
Mutual labels:  serialization
Frideos flutter
An all-in-one Fllutter package for state management, reactive objects, animations, effects, timed widgets etc.
Stars: ✭ 187 (-12.21%)
Mutual labels:  sharedpreferences
Marshmallow Jsonapi
JSON API 1.0 (https://jsonapi.org/) formatting with marshmallow
Stars: ✭ 203 (-4.69%)
Mutual labels:  serialization
Jsons
🐍 A Python lib for (de)serializing Python objects to/from JSON
Stars: ✭ 178 (-16.43%)
Mutual labels:  serialization
Cachingframework.redis
Distributed caching based on StackExchange.Redis and Redis. Includes support for tagging and is cluster-compatible.
Stars: ✭ 209 (-1.88%)
Mutual labels:  serialization
Binaryserializer
A declarative serialization framework for controlling formatting of data at the byte and bit level using field bindings, converters, and code.
Stars: ✭ 197 (-7.51%)
Mutual labels:  serialization
Tray
a SharedPreferences replacement for Android with multiprocess support
Stars: ✭ 2,314 (+986.38%)
Mutual labels:  sharedpreferences
Typedpreferences
Preference wrappers for primitive types for Android
Stars: ✭ 191 (-10.33%)
Mutual labels:  sharedpreferences
Itsdangerous
Safely pass trusted data to untrusted environments and back.
Stars: ✭ 2,358 (+1007.04%)
Mutual labels:  serialization
Chronicle Wire
A Java Serialisation Library that supports multiple formats
Stars: ✭ 204 (-4.23%)
Mutual labels:  serialization
Android Prefs
Android preferences for WINNERS!
Stars: ✭ 183 (-14.08%)
Mutual labels:  sharedpreferences
Home
A configurable and eXtensible Xml serializer for .NET.
Stars: ✭ 208 (-2.35%)
Mutual labels:  serialization
Kau
An extensive collection of Kotlin Android Utils
Stars: ✭ 182 (-14.55%)
Mutual labels:  sharedpreferences
Rapidyaml
Rapid YAML - a library to parse and emit YAML, and do it fast.
Stars: ✭ 183 (-14.08%)
Mutual labels:  serialization
Jsonlab
JSONLab: a native JSON/UBJSON/MassagePack encoder/decoder for MATLAB/Octave
Stars: ✭ 202 (-5.16%)
Mutual labels:  serialization
Mashumaro
Fast and well tested serialization framework on top of dataclasses
Stars: ✭ 208 (-2.35%)
Mutual labels:  serialization

Krate

Build Status

Krate banner

Krate is a SharedPreferences wrapper library that uses delegated properties for convenient access to SharedPreferences values.

Here's what its basic usage looks like, extending the provided SimpleKrate class:

class UserSettings(context: Context) : SimpleKrate(context) {

    var notificationsEnabled by booleanPref("notifications_enabled", false)
    var loginCount by intPref("login_count", 0)
    var nickname by stringPref("nickname", "")

}

val settings = UserSettings(context)
settings.loginCount = 10
Log.d("LOGIN_COUNT", "Count: ${settings.loginCount}")

Dependency

You can include Krate in your project from the mavenCentral() repository, like so:

implementation 'hu.autsoft:krate:1.0.0'

Optionals vs defaults

Each stored property can be declared with or without a default value. Here's how the two options differ:

Optional values:

A property declared with the one-argument delegate function will have a nullable type. It will have a null value if no value has been set for this property yet, and its current value can be erased from SharedPreferences completely by setting it to null.

var username: String? by stringPref("username")

Default values:

A property declared with the two-argument delegate function takes its default value as the second argument, and it will have a non-nullable type. Reading from this property will return either the value it was last set to or the default value. Setting this property will update the value stored in SharedPreferences. Note that there's no way to remove these values from SharedPreferences (although you could set it explicitly to the default value).

var username: String by stringPref("username", defaultValue = "admin")

Custom Krate implementations

You can usually get away with extending SimpleKrate, as it does allow you to pass in a custom name for the SharedPreferences to be used to store your values in its constructor as an optional parameter. (If you pass in no name parameter to its constructor, it will default to using the instance returned by PreferenceManager.getDefaultSharedPreferences(context).)

However, you can also implement the Krate interface directly if you want to manage the SharedPreferences instance yourself for whatever reason - all this interface requires is a property that holds a SharedPreferences instance. With that, you can use the delegate functions the same way as shown above:

class ExampleCustomKrate(context: Context) : Krate {

    override val sharedPreferences: SharedPreferences

    init {
        sharedPreferences = context.applicationContext.getSharedPreferences("custom_krate_prefs", Context.MODE_PRIVATE)
    }

    var exampleBoolean by booleanPref("exampleBoolean", false)
    
}

For simple applications, your Activity or Fragment can easily serve as a Krate implementation:

class MainActivity : AppCompatActivity(), Krate {

    override val sharedPreferences: SharedPreferences by lazy {
        getPreferences(Context.MODE_PRIVATE) // Could also fetch a named or default SharedPrefs
    }
    
    var username by stringPref("username", "")

}

Third party implementations

You can create the SharedPreferences instance to implement Krate's interface by using third party SharedPreferences implementations as well. For example, EncryptedSharedPreferences or Harmony are such implementations.

Here's how you'd use EncryptedSharedPreferences with Krate (see this source file for the full code):

class EncryptedKrate(applicationContext: Context) : Krate {
    override val sharedPreferences: SharedPreferences

    init {
        /* ... */
        sharedPreferences = EncryptedSharedPreferences.create(applicationContext, ...)
    }

    val myStringValue: String by stringPref("my_string_value", "")
}

Validation

You can add validation rules to your Krate properties by calling validate on any of Krate's delegate functions:

var percentage: Int by intPref(
        key = "percentage",
        defaultValue = 0,
).validate { it in 0..100 }

If this validation fails, an IllegalArgumentException will be thrown.

Addons

Krate, by default, supports the types that SharedPreferences supports. These are Boolean, Float, Int, Long, String and Set<String>. You may of course want to store additional types in Krate.

If you don't find support for the library or type you're looking for, implementing your own delegate in your own project based on the code of existing delegates should be quite simple, this is very much a supported use case. If you think your type might be commonly used, you can also open an issue to ask for an addon library for that type.

Moshi support

This addon provides a moshiPref delegate which can store any arbitrary type, as long as Moshi can serialize and deserialize it.

Since Moshi supports both reflection-based serialization and code generation, there are multiple Krate artifacts for different use cases. You should always include only one of the dependencies below, otherwise you'll end up with a dexing error.

The usage of the Krate integration is the same for both setups:

class MoshiKrate(context: Context) : SimpleKrate(context) {
    var user: User? by moshiPref("user")
    var savedArticles: List<Article>? by moshiPref("articles")
}

If you want to provide your own Moshi instance that you've configured with your own custom adapters, you can set the moshi extension property on your Krate. Any moshiPref delegates within this Krate will use this instance for serialization and deserialization.

class CustomMoshiKrate(context: Context) : SimpleKrate(context) {
    init {
        moshi = Moshi.Builder().build()
    }
}

Only codegen

If you only want to use Moshi adapters that you generate via Moshi's codegen facilities, you can use the following Krate artifact in your project to make use of these adapters:

implementation 'hu.autsoft:krate-moshi-codegen:1.0.0'

This will give you a default Moshi instance created by a call to Moshi.Builder().build(). This instance will find and use any of the adapters generated by Moshi's codegen automatically.

Only reflection, or mixed use of reflection and codegen

If you rely on reflection for your Moshi serialization, and therefore need a KotlinJsonAdapterFactory included in your Moshi instance, use the following Krate Moshi dependency:

implementation 'hu.autsoft:krate-moshi-reflect:1.0.0'

The default Moshi instance from this dependency will include the aforementioned factory, and be able to serialize any Kotlin class. Note that this approach relies on the kotlin-reflect library, which is a large dependency.

You may choose to use Moshi's codegen for some classes in your project, and serialize the ones with no adapters generated with the default approach via reflection. For this mixed use case, you should also choose this dependency (unless you set your own custom Moshi instances as described above).

Kotlinx.serialization support

The krate-kotlinx artifact provides a kotlinxPref delegate which can store any arbitrary type, as long as Kotlinx.serializazion can serialize and deserialize it. This addon, like the base library, is available from mavenCentral():

implementation 'hu.autsoft:krate-kotlinx:1.0.0'

Its usage is the same as with any of the base library's delegates:

class KotlinxKrate(context: Context) : SimpleKrate(context) {
    var user: User? by kotlinxPref("user")
    var savedArticles: List<Article>? by kotlinxPref("articles")
}

By default, the Json.Default is used. If you want to provide your own customized Json instance, you can set the json extension property on your Krate. Any kotlinxPref delegates within this Krate will use this instance for serialization and deserialization.

class CustomKotlinxKrate(context: Context) : SimpleKrate(context) {
    init {
        json = Json {
           coerceInputValues = true
           ...
        }
    }

    var user: User? by kotlinxPref("user")
}

Gson support

The krate-gson artifact provides a gsonPref delegate which can store any arbitrary type, as long as Gson can serialize and deserialize it. This addon, like the base library, is available from mavenCentral():

implementation 'hu.autsoft:krate-gson:1.0.0'

Its basic usage is the same as with any of the base library's delegates:

class GsonKrate(context: Context) : SimpleKrate(context) {
    var user: User? by gsonPref("user")
    var savedArticles: List<Article>? by gsonPref("articles")
}

By default, the Gson instance created by a simple Gson() constructor call is used. If you want to provide your own Gson instance that you've configured, you can set the gson extension property on your Krate. Any gsonPref delegates within this Krate will use this instance for serialization and deserialization.

class CustomGsonKrate(context: Context) : SimpleKrate(context) {
    init {
        gson = GsonBuilder().create()
    }

    var user: User? by gsonPref("user")
}

License

Copyright 2020 AutSoft

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.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].