- 🚀 Quick start
- Prebuilt dev tool types
- 👷 Custom dev tool types
- Configuration sources
- Public API
- Configuration screen
- Startup arguments
- 👷 For developers
- 📜 License
The scope of the library is to help a library consumer to manage its configuration values. DevTool
represents the main, and the single library domain object, which wraps a configuration value and encapsulates different actions(i.e., persist
, update
...) that could be performed with it.
As the configuration values might be of different types, there is a set of different prebuilt DevTool
implementations for each configuration value type in part.
The currently prebuilt list of dev tool types makes it possible to handle all configuration values of primitive types like String
, Integer
, and Floating-Point
.
Reference types are not supported yet.
Name | Config value type | Yaml | Json | Memory | Description | |
---|---|---|---|---|---|---|
Toggle | Boolean |
➕ | ➕ | ➕ | Allows to store, update, and consume boolean config values. | ![]() |
Text | String Integer Float |
➕ | ➕ | ➕ | Allows to store, update, and consume text and numeric config values. | ![]() |
Enum | String Integer Float |
➕ | ➕ | ➕ | Allows to store, update, and consume text and numeric config values. You set a limited config value options. | ![]() |
Time | Long |
➕ | ➖ | ➕ | Allows to store, update, and consume time config values. The config value is stored as Long in ms. | ![]() |
Group | DevTool |
➕ | ➕ | ➕ | Allows to group tools that belong to the same context. | ![]() |
In case the prebuilt dev tools are not sufficient, a library consumer might extend the library with its own dev tools.
Currently, the library supports 3 dev tools sources Yaml, Json, and Memory. However, in case you need to use a custom one, you might add it very merely. Check how to do this here.
🤖 Android | 🍏 iOS | |
Yaml |
val src = DevToolsSources.yaml(
assetManager = assets,
fileName = "dev-tools.yml"
) |
Not ready yet. |
---|---|---|
Json |
val src = DevToolsSources.json(
assetManager = assets,
fileName = "dev-tools.json"
) |
Not ready yet. |
Memory |
val tools: Map<String, DevTool<*>> = mapOf(
"toggle-tool" to ToggleTool(default = true),
"text-tool" to TextTool(default = 3.0),
"time-tool" to TimeTool(days = 1)
)
val src = DevToolsSources.memory(tools) |
Not ready yet. |
To add a new custom source you just need to:
-
Create a custom dev tools reader
The reader is the place where you should gather the dev tools data from your own source and convert it to a collection of key-value pairs. Where the key is a unique dev tool key and the value is the actual dev tool.
🤖 Android 🍏 iOS class MyCustomDevToolsReader : DevToolsReader { override fun getDevTools(): Map> { return mapOf( "toggle-tool" to ToggleTool(default = true), "text-tool" to TextTool(default = 3.0), "time-tool" to TimeTool(days = 1) ) } }
Not ready yet.
-
Create the actual source
You can do this by implementing DevToolsSource
🤖 Android 🍏 iOS class MyCustomSource : DevToolsSource { override fun getReader(): DevToolsReader { return MyCustomDevToolsReader() } }
Not ready yet.
To access and manipulate your configuration values programmatically from your's app code you'll need too have access to a DevTools instance.
Create a dev tools instance
You'll need to provide at least 2 parameters to create a new DevTools instance which are:
name
: a unique for your app instance dev tools id;devToolsSources
: a list of dev tools sources;onConfigUpdate
(optional): a config values update listener.
🤖 Android | 🍏 iOS |
val source = DevToolsSources.yaml(assets, "dev-tools.yml")
val devtools = DevTools.create("TOOLS", source)
// or you can provide more sources
val memory = DevToolsSources.memory(tools)
val yml = DevToolsSources.yaml(assets, "dev-tools.yml")
val json = DevToolsSources.json(assets, "dev-tools.json")
val devtools = DevTools.create("TOOLS", memory, yml, json) |
Not ready yet. |
Access configuration
🤖 Android | 🍏 iOS |
val value: Boolean = devtools.getValue("toggle-tool") |
Not ready yet. |
React on configuration changes
The call back will be invoked whenever a new configuration value gets updated.
isCriticalUpdate
will be true just in case at least one dev tool that you marked as critical using
the critical flag will be updated.
🤖 Android | 🍏 iOS |
devtools.onConfigUpdated = { isCriticalUpdate ->
/* React on configuration changes*/
} |
Not ready yet. |
Access group child configuration value
🤖 Android | 🍏 iOS |
val value: Boolean = devtools.getGroup("toggle-tool")
.getValue("toggle-tool")
// or
val value: Boolean = devtools
.getGroup("toggle-tool")
.getGroup("toggle-inner-group")
.getValue("toggle-tool") |
Not ready yet. |
Check if configuration is enabled
🤖 Android | 🍏 iOS |
val isEnabled = devtools.isEnabled("toggle-tool")
// or
val isEnabled = devtools
.getGroup("toggle-tool")
.getGroup("toggle-inner-group")
.isEnabled("toggle-tool") |
Not ready yet. |
Get all configuration as JSON
Note that the lambda parameter is nothing else than a simple predicate(a filter). You can use it to filter out the configuration values that will reach the final JSON result.
For example, you can filter and get just the enabled config, as shown in the example.
🤖 Android | 🍏 iOS |
devtools.getAllConfigAsJson { tool -> tool.isEnabled } |
Not ready yet. |
One of the easiest ways to update a configuration value is a good user interface. The library is able to generate a configuration screen dynamically based on your configuration file.
Sometimes we might need to run the app preconfigured. The most common use case could be an automated test, for example. So the best way to run the app preconfigured is to run it from a terminal and pass some startup arguments. The library provides a similar feature, but to make use of it, you must integrate it first.
If you know how to fix an issue, consider opening a pull request for it. 🙏
You can read this repository’s contributing guidelines to learn how to open a good pull request.
The library is composed of 5 modules:
-
Common: the actual multi-platform module which contains all business models and logic;
-
Library Android: an Android module which contains just Android native view implementations;
-
Library iOS: an iOS framework which contains just iOS native view implementations;
-
Sample Android: an Android library consumer which serves as an Android library features demo.
-
Sample iOS: an iOS library consumer which serves as an iOS library features demo.
Android | iOS |
---|---|
You may use ./gradlew assemble to generate a new android library. The Android library generation is straight forward. First of all, an AAR is generated from the Common module, which is then used to generate another AAR for the Android Library itself. |
The iOS framework generation is a bit more complex but not much harder than the Android one. First of all, you need to build a Fat Framework(FF) .You can do this by running ./gradlew releaseFatFramework . After this command succeeds, you'll notice the framework inside the iOS library package. Now you can build the library itself. |
Common | Android | iOS |
---|---|---|
- ktlint - detekt |
- ktlint - detekt - lint |
- SwiftLint |
./gradlew clean
will remove all build directories together with the iOS Fat Framework./gradlew assembe
will generaterelease
/debug
aar
s and also the iOSFat Framework
./gradlew releaseFatFramework
will generate the iOSFat Framework
./gradlew testDebugUnitTest
runes all JVM modules unit tests./gradlew detekt ktlint lint testDebugUnitTest assembleDebug
will run all quality checks and will assemble the frameworks./gradlew publishCommonPublicationToMavenRepository
releases the common module to maven local./gradlew publishAndroidPublicationToMavenRepository
releases the Android library to maven local
In case you're working on the library you might find useful this alias:
alias checktools='./gradlew detekt ktlint lint testDebugUnitTest assembleDebug'
It will run all style checks, unit tests, and will assemble all artifacts.
Not ready yet.
- Checkout the latest
master
branch commit - Release the project to Maven Central by running
./gradlew -Prelease publishReleasePublicationToMavenRepository
- Create and push a new tag for the new version
- Open a new PR to bump up to the library version and update the changelog file.
ℹ️ The deployment process will be automated after we hve the iOS library ready #56.