{"id":13902483,"url":"https://github.com/zsmb13/requireKTX","last_synced_at":"2025-07-18T00:31:36.874Z","repository":{"id":50119101,"uuid":"371439219","full_name":"zsmb13/requireKTX","owner":"zsmb13","description":"Extensions that make it easier to deal with otherwise nullable APIs, for Android and Kotlin Multiplatform","archived":false,"fork":false,"pushed_at":"2024-05-18T13:42:14.000Z","size":295,"stargazers_count":112,"open_issues_count":0,"forks_count":3,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-07-27T09:34:56.609Z","etag":null,"topics":["android","compose-multiplatform","compose-multiplatform-library","kotlin","kotlin-multiplatform","kotlin-multiplatform-library","utility-library"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zsmb13.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-05-27T16:33:27.000Z","updated_at":"2024-06-16T21:01:02.000Z","dependencies_parsed_at":"2024-05-16T21:53:03.181Z","dependency_job_id":null,"html_url":"https://github.com/zsmb13/requireKTX","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zsmb13%2FrequireKTX","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zsmb13%2FrequireKTX/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zsmb13%2FrequireKTX/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zsmb13%2FrequireKTX/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zsmb13","download_url":"https://codeload.github.com/zsmb13/requireKTX/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":214260257,"owners_count":15707069,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","compose-multiplatform","compose-multiplatform-library","kotlin","kotlin-multiplatform","kotlin-multiplatform-library","utility-library"],"created_at":"2024-08-06T22:01:10.164Z","updated_at":"2024-11-25T10:32:13.307Z","avatar_url":"https://github.com/zsmb13.png","language":"Kotlin","funding_links":[],"categories":["Kotlin"],"sub_categories":[],"readme":"# requireKTX\n\n**requireKTX** is a collection of small utility functions to make it easier to work with **values that should always exist** on Android and Kotlin Multiplatform, in the style of [`requireContext`](https://developer.android.com/reference/androidx/fragment/app/Fragment.html#requireContext()), [`requireArguments`](https://developer.android.com/reference/androidx/fragment/app/Fragment.html#requireArguments()), and other similar Android SDK methods.\n\nTypes that requireKTX provides extensions for:\n\n- [Bundle](#bundle) (Kotlin Multiplatform)\n- [NavBackStackEntry](#navbackstackentry) (Kotlin Multiplatform)\n- [Intent](#intent) (Android)\n- [WorkManager Data](#workmanager-data) (Android)\n\n## Why?\n\nTake the example of grabbing a Bundle and reading a String ID from it that should always be there: the Bundle APIs give you a nullable result, which means you'll have to do some kind of null handling.\n\n```kotlin\n// Without requireKTX 😥\nval id: String = argumentBundle.getString(\"user_id\")!!\n```\n\nThe exception potentially thrown by this code also won't be too helpful in tracking down the problem, as it won't tell you details such as whether the value was missing, or if it was the wrong type for the request.\n\nAnother problem with Bundles is accessing primitive values, as they're always returned as non-nullable, defaulting to `0` (or even worse, `false` for Booleans) if the key is not found or its associated value has the wrong type:\n\n```kotlin\nval bundle = Bundle()\nbundle.putDouble(\"count\", 123.0)\n\n// These both pass 😱\nassertEquals(0, bundle.getInt(\"count\"))\nassertEquals(0, bundle.getInt(\"score\"))\n```\n\nThis makes it difficult to know if what you received was a real `0` value, or if something silently went wrong.\n\n---\n\nInstead of using these methods, requireKTX provides extensions such as `requireString`, which you can use to *require* a value that must always be there:\n\n```kotlin\n// With requireKTX 🥳\nval id: String = argumentBundle.requireString(\"user_id\")\nval count: Int = argumentBundle.requireInt(\"count\")\n```\n\nThese methods give you non-nullable return types. If the key isn't set or the value doesn't have the expected type, they throw meaningful exceptions based on the error that occurred. This is true for accessing primitive values as well.\n\n### getOrNull\n\nrequireKTX **also includes `getOrNull` style methods for everything that it covers with `require` style methods**,to make the nullable case more obvious and explicit. These match the conventions of the Kotlin Standard Library, and can make it clearer that `null` is returned if a value for a key couldn't be fetched.\n\n```kotlin\nval userId: String? = requireArguments().getStringOrNull(\"user_id\")\nval count: Int? = requireArguments().getIntOrNull(\"count\")\n```\n\n## Dependencies\n\nrequireKTX is published on [Maven Central](https://repo1.maven.org/maven2/co/zsmb/).\n\n```kotlin\nrepositories {\n    mavenCentral()\n}\n```\n\nThere are several artifacts you can import depending on which types you want to get extensions for - see the module descriptions below to learn more.\n\n```kotlin\ndependencies {\n    // commonMain or Android\n    implementation(\"co.zsmb:requirektx-bundle:2.0.0-alpha03\")\n    implementation(\"co.zsmb:requirektx-navigation:2.0.0-alpha03\")\n\n    // Android only\n    implementation(\"co.zsmb:requirektx-intent:2.0.0-alpha03\")\n    implementation(\"co.zsmb:requirektx-work:2.0.0-alpha03\")\n}\n```\n\n## Available modules and extensions\n\n### Bundle\n\n*The `requirektx-bundle` artifact works with the `androidx.core.bundle.Bundle` type, available on Android and other Kotlin Multiplatform targets from `org.jetbrains.androidx.core:core-bundle`.*\n\nGiven a `Bundle`, you can require the following types of values:\n\n```kotlin\n// Primitives (examples)\nbundle.requireBoolean()\nbundle.requireByte()\nbundle.requireChar()\nbundle.requireDouble()\nbundle.requireFloat()\n\n// Reference types\nbundle.requireString()\nbundle.requireBundle()\nbundle.requireCharSequence()\nbundle.requireParcelable()\nbundle.requireSerializable()\n\n// Arrays (examples)\nbundle.requireBooleanArray()\nbundle.requireByteArray()\nbundle.requireCharArray()\nbundle.requireDoubleArray()\nbundle.requireFloatArray()\n```\n\n... and many more!\n\n### NavBackStackEntry\n\n*The `requirektx-navigation` artifact works with the `androidx.navigation.NavBackStackEntry` type, available on Android and other Kotlin Multiplatform targets from `org.jetbrains.androidx.navigation:navigation-runtime`.*\n\n*This is compatible with both the [Jetpack Navigation component on Android](https://developer.android.com/guide/navigation) (with or without Compose) and the [Compose Multiplatform navigation library](https://www.jetbrains.com/help/kotlin-multiplatform-dev/compose-navigation-routing.html).*\n\nTo get the bundle of arguments from an entry, use `requireArguments`:\n\n```kotlin\nval args: Bundle = navBackStackEntry.requireArguments()\n```\n\nHere's an example of using this with Compose Navigation, in combination with the [Bundle extensions](#bundle):\n\n```kotlin\ncomposable(\n    \"detail/{objectId}\",\n    arguments = listOf(navArgument(\"objectId\") { type = NavType.IntType }),\n) { backStackEntry -\u003e\n    val args = backStackEntry.requireArguments()\n    val objectId = args.requireInt(\"objectId\")\n    // UI implementation\n}\n```\n\n### Intent\n\n*The `requirektx-intent` artifact works with the [`android.content.Intent`](https://developer.android.com/reference/android/content/Intent) type, available on Android only.*\n\nGiven an `Intent`, you can require its extras `Bundle` (and then require values from it as seen above):\n\n```kotlin\nval extras: Bundle = intent.requireExtras()\n```\n\nOr you can require specific extras directly for various types of values:\n\n```kotlin\n// Primitives (examples)\nintent.requireBooleanExtra()\nintent.requireByteExtra()\nintent.requireCharExtra()\nintent.requireDoubleExtra()\nintent.requireFloatExtra()\n\n// Reference types\nintent.requireStringExtra()\nintent.requireBundleExtra()\nintent.requireCharSequenceExtra()\nintent.requireParcelableExtra()\nintent.requireSerializableExtra()\n\n// Arrays (examples)\nintent.requireBooleanArrayExtra()\nintent.requireByteArrayExtra()\nintent.requireCharArrayExtra()\nintent.requireDoubleArrayExtra()\nintent.requireFloatArrayExtra()\n```\n\n... and many more!\n\n### WorkManager Data\n\n*The `requirektx-work` artifact provides extensions for the [`androidx.work.Data`](https://developer.android.com/reference/androidx/work/Data) type, available on Android only.*\n\nGiven a WorkManager `Data` object (such as `inputData` inside a worker), you can require the following types of values:\n\n```kotlin\nclass SomeWorker : Worker() {\n    override fun doWork(): Result {\n        // Values\n        inputData.requireBoolean()\n        inputData.requireByte()\n        inputData.requireDouble()\n        inputData.requireFloat()\n        inputData.requireInt()\n        inputData.requireLong()\n        inputData.requireString()\n\n        // Arrays\n        inputData.requireBooleanArray()\n        inputData.requireByteArray()\n        inputData.requireDoubleArray()\n        inputData.requireFloatArray()\n        inputData.requireIntArray()\n        inputData.requireLongArray()\n        inputData.requireStringArray()\n\n        // ...\n    }\n}\n```\n\n## License\n\n    Copyright 2021 Márton Braun\n\n    Licensed under the Apache License, Version 2.0 (the \"License\");\n    you may not use this file except in compliance with the License.\n    You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing, software\n    distributed under the License is distributed on an \"AS IS\" BASIS,\n    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n    See the License for the specific language governing permissions and\n    limitations under the License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzsmb13%2FrequireKTX","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzsmb13%2FrequireKTX","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzsmb13%2FrequireKTX/lists"}