# kotlinmultiplatform

Published articles for kotlinmultiplatform.

This is one page of public article previews, not the complete archive. Follow Next page to continue. Summaries are not the original full articles.

## Antigravity TagSpotter - KotlinMultiPlatform evolve

DevFeed: [Antigravity TagSpotter - KotlinMultiPlatform evolve](<https://devfeed.tech/articles/antigravity-tagspotter-kotlinmultiplatform-evolve-32038.md>)

Original publisher: [Read original article](<https://www.maiatoday.net/p/antigravity-tagspotter-kotlinmultiplatform-evolve/>)

Published: 2026-06-14T19:10:33Z

Content type: opinion

Language: en

Sources: [maiatoday](<https://devfeed.tech/sources/maiatoday.md>)

Topics: [kotlinmultiplatform](<https://devfeed.tech/topics/kotlinmultiplatform.md>), [multiplatform](<https://devfeed.tech/topics/multiplatform.md>), [Android](<https://devfeed.tech/topics/android.md>), [compose-multiplatform](<https://devfeed.tech/topics/compose-multiplatform.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [iOS](<https://devfeed.tech/topics/ios.md>), [Gradle](<https://devfeed.tech/topics/gradle.md>), [Web](<https://devfeed.tech/topics/web.md>), [Open Source](<https://devfeed.tech/topics/open-source.md>)

Tags: [ai](<https://devfeed.tech/tags/ai.md>), [ai-agents](<https://devfeed.tech/tags/ai-agents.md>), [android](<https://devfeed.tech/tags/android.md>), [antigravity](<https://devfeed.tech/tags/antigravity.md>), [code](<https://devfeed.tech/tags/code.md>), [compose](<https://devfeed.tech/tags/compose.md>), [compose-multiplatform](<https://devfeed.tech/tags/compose-multiplatform.md>), [git](<https://devfeed.tech/tags/git.md>), [kmp](<https://devfeed.tech/tags/kmp.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlinmultiplatform](<https://devfeed.tech/tags/kotlinmultiplatform.md>), [migration](<https://devfeed.tech/tags/migration.md>), [tests](<https://devfeed.tech/tags/tests.md>)

### AI overview

The article documents an attempt to migrate the TagSpotter Android app toward Kotlin Multiplatform using Antigravity 2.0 and parallel agents. It describes preparation such as modularizing the codebase, adding tests, researching KMP migration, and planning support for iOS, Android, Desktop, and Web, while retaining Android-specific features such as the Wear app.

### Source excerpt

The Challenge - bring on the subagents Can I make my TagSpotter Android app be multi-platform in a weekend using Antigravity 2.0 and a swarm of agents running in parallel? Can I do this even though I don't know how to use Xcode and I don't want to break my existing app. This was the question I had. TagSpotter is medium featured Android app I built two weeks ago. I use it to capture interesting and favourite spots in the city like unusual graffiti or yarn bombed sculptures. It has a fair few features including: Capture the places by camera with location Upload a photo AI lookup to find info on the internet from the photo, links, title, artist and suggested tags Export the spots in a zip file and import them again. This is how I share my favourite spots with friends. Make field notes by typing or speaking Share my favourites to Google maps for easy navigation Good category and location based filtering Wear app that can list started spots and navigate to a spot on the watch A good challenge because it isn't just a hello world app. The prep Because the clock would be ticking, I did a little bit of prep to make sure I had everything ready. Prep the codebase Clean up the app, no warnings, lint issues or unused imports Make sure the screens work in landscape, desktop mode will need this Split the app into feature based and pure kotlin modules. I know Compose multiplatform and pure kotlin modules can easily be re-used. Put some tests in place Checked everything works and make a tag in git incase Antigravity borked the project. Light research I collected a few salient links about KMP migration. A good blog post, some info on project structure and a link to the open source kmp libraries I might need. Nitty Gritty Friday evening, let's go. Make a plan I want to convert this app to a KMP app that supports iOS, Android, Desktop and Web. The other platforms do not have to support all features, e.g. the wear app. But Android still has to support this feature. I want to share as mu

## Kotlin 1.9.20: Streamlining Source Sets in Multiplatform Project

DevFeed: [Kotlin 1.9.20: Streamlining Source Sets in Multiplatform Project](<https://devfeed.tech/articles/kotlin-1-9-20-streamlining-source-sets-in-multiplatform-project-24717.md>)

Original publisher: [Read original article](<https://dev.to/touchlab/kotlin-1920-streamlining-source-sets-in-multiplatform-project-27ak>)

Author: Jigar Brahmbhatt

Published: 2024-03-26T13:57:17Z

Content type: release

Language: en

Sources: [Touchlab](<https://devfeed.tech/sources/touchlab.md>)

Topics: [Kotlin Multiplatform](<https://devfeed.tech/topics/kotlin-multiplatform.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Gradle](<https://devfeed.tech/topics/gradle.md>), [Boilerplate](<https://devfeed.tech/topics/boilerplate.md>), [configuration](<https://devfeed.tech/topics/configuration.md>), [Code](<https://devfeed.tech/topics/code.md>)

Tags: [apple](<https://devfeed.tech/tags/apple.md>), [coding](<https://devfeed.tech/tags/coding.md>), [community](<https://devfeed.tech/tags/community.md>), [configuration](<https://devfeed.tech/tags/configuration.md>), [development](<https://devfeed.tech/tags/development.md>), [efficiency](<https://devfeed.tech/tags/efficiency.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [gradle](<https://devfeed.tech/tags/gradle.md>), [gradle-plugin](<https://devfeed.tech/tags/gradle-plugin.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [kmp](<https://devfeed.tech/tags/kmp.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-multiplatform](<https://devfeed.tech/tags/kotlin-multiplatform.md>), [kotlinmultiplatform](<https://devfeed.tech/tags/kotlinmultiplatform.md>), [multiplatform](<https://devfeed.tech/tags/multiplatform.md>), [readability](<https://devfeed.tech/tags/readability.md>), [software](<https://devfeed.tech/tags/software.md>)

### AI overview

Kotlin 1.9.20 makes Kotlin Multiplatform stable and introduces a default source set hierarchy template through the Kotlin Gradle Plugin. The update simplifies iOS target configuration, custom source sets, dependency setup, and IDE code completion while reducing boilerplate.

### Source excerpt

The release of Kotlin 1.9.20 marked a significant milestone for Kotlin Multiplatform enthusiasts, as this update moved Kotlin Multiplatform to Stable. Kotlin 1.9.20 introduces several notable features and enhancements. Among these updates, the new source set hierarchy template by the Kotlin Gradle Plugin stands out to me for its ability to simplify configuration complexities. It was launched as experimental in Kotlin 1.8.20 and has been made default in Kotlin 1.9.20. Simplified iOS Target Configuration In the common Kotlin Multiplatform project set-up, you would have seen specific source set setup for two or three iOS targets like for X64, Arm64. Instead of the common and confusing 'ios()' target, one must always declare specific targets like 'iosArm64()' as required. Once one of the iOS targets is declared, the default template would automatically create iosMain source set. So no more val iosMain by creating boilerplate required. Before 1.9.20 After 1.9.20 kotlin { ios() iosSimulatorArm64() sourceSets { val commonMain by getting val iosMain by creating { dependsOn(commonMain) } val iosX64Main by getting { dependsOn(iosMain) } val iosArm64Main by getting { dependsOn(iosMain) } val iosSimulatorArm64Main by getting { dependsOn(iosMain) } } } kotlin { iosX64() iosArm64() iosSimulatorArm64() // The iosMain source set is now created automatically // You can directly use the reference now iosMain.dependencies { implementation("...") } } If you've an old KMP project and still have reference of darwinMain, you can simply rename it to appleMain now as that encapsulates all other apple targets. Checkout the full hierarchy template! Streamlined Custom Source Sets Managing custom source sets in Kotlin Multiplatform projects is now more straightforward with Kotlin 1.9.20. The update simplifies the process of setting up dependencies between source sets, reducing the need for extensive boilerplate code and enhancing overall readability. For example, let's assume that you already h

## Kermit Now Supports WASM

DevFeed: [Kermit Now Supports WASM](<https://devfeed.tech/articles/kermit-now-supports-wasm-24715.md>)

Original publisher: [Read original article](<https://dev.to/touchlab/kermit-now-supports-wasm-356p>)

Author: Jigar Brahmbhatt

Published: 2023-10-30T19:09:32Z

Content type: article

Language: en

Sources: [Touchlab](<https://devfeed.tech/sources/touchlab.md>)

Topics: [Kotlin Multiplatform](<https://devfeed.tech/topics/kotlin-multiplatform.md>), [WebAssembly](<https://devfeed.tech/topics/web-assembly.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Compiler](<https://devfeed.tech/topics/compiler.md>), [browsers](<https://devfeed.tech/topics/browsers.md>), [web browsers](<https://devfeed.tech/topics/web-browsers.md>), [Gradle](<https://devfeed.tech/topics/gradle.md>)

Tags: [browsers](<https://devfeed.tech/tags/browsers.md>), [coding](<https://devfeed.tech/tags/coding.md>), [community](<https://devfeed.tech/tags/community.md>), [compiler](<https://devfeed.tech/tags/compiler.md>), [development](<https://devfeed.tech/tags/development.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [gradle](<https://devfeed.tech/tags/gradle.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [integration](<https://devfeed.tech/tags/integration.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-multiplatform](<https://devfeed.tech/tags/kotlin-multiplatform.md>), [kotlinmultiplatform](<https://devfeed.tech/tags/kotlinmultiplatform.md>), [libraries](<https://devfeed.tech/tags/libraries.md>), [logging](<https://devfeed.tech/tags/logging.md>), [software](<https://devfeed.tech/tags/software.md>), [web-browsers](<https://devfeed.tech/tags/web-browsers.md>), [webassembly](<https://devfeed.tech/tags/webassembly.md>)

### AI overview

This article describes adding WebAssembly support to Kermit, a Kotlin Multiplatform library. It explains the Kotlin/Wasm context, the need to verify dependency support, and the use of shared source sets for Kotlin/JS and Kotlin/Wasm.

### Source excerpt

What is Kotlin/Wasm? For Kotlin Multiplatform developers, the conversation has shifted to WebAssembly -- a notable addition to the Kotlin Multiplatform (KMP) ecosystem. WebAssembly, often abbreviated as WASM, is a binary instruction format tailored for web browsers. Its main goal is to execute high-performance code at speeds close to native applications. WebAssembly enjoys broad support across modern browsers, boasting approximately 96% coverage according to caniuse. While it's not meant to be directly written, there's a fascinating aspect called WebAssembly Text Format (.wat). This format allows developers to represent code in a readable text format. For those curious minds, delve deeper into this format by reading Mozilla's guide. While WebAssembly isn't a newcomer, ongoing developments, such as the anticipated WebAssembly Garbage Collection (WASM GC), make it an evolving technology. Kotlin, recognizing the potential of WebAssembly, has embraced it with the Kotlin/WASM compiler. The Kotlin team is actively ensuring they stay ahead of the curve with the Kotlin/WASM compiler, already incorporating support for features like WASM GC. What makes Kotlin/WASM noteworthy is its ability to allow developers to write code in their preferred language and seamlessly compile it into a WebAssembly binary. Kermit Steps into the Wasm Arena Given Kermit's popularity in the Kotlin Multiplatform (KMP) realm, the community asked for Wasm support. It was exciting to gain firsthand experience with WASM for integration into Kermit. Step #1 - Adding the Wasm Target The initial step seemed straightforward: add the wasm target in our build scripts. However, reality hit when we discovered that some of Kermit's dependencies lacked support for Wasm. This underscored a critical lesson for library developers: ensure upstream libraries are compatible with all KMP targets your project aims to include. import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl kotlin { ... @OptIn(Experime

## Customize Kermit Logger syntax in Kotlin Multiplatform

DevFeed: [Customize Kermit Logger syntax in Kotlin Multiplatform](<https://devfeed.tech/articles/logger-i-not-your-style-customize-kermit-logger-24718.md>)

Original publisher: [Read original article](<https://dev.to/touchlab/loggeri-not-your-style-customize-kermit-logger-4fik>)

Author: Jigar Brahmbhatt

Published: 2023-10-24T02:19:28Z

Content type: tutorial

Language: en

Sources: [Touchlab](<https://devfeed.tech/sources/touchlab.md>)

Topics: [Kotlin Multiplatform](<https://devfeed.tech/topics/kotlin-multiplatform.md>), [Library](<https://devfeed.tech/topics/library.md>), [Logging](<https://devfeed.tech/topics/logging.md>), [Code](<https://devfeed.tech/topics/code.md>)

Tags: [coding](<https://devfeed.tech/tags/coding.md>), [community](<https://devfeed.tech/tags/community.md>), [development](<https://devfeed.tech/tags/development.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-multiplatform](<https://devfeed.tech/tags/kotlin-multiplatform.md>), [kotlinmultiplatform](<https://devfeed.tech/tags/kotlinmultiplatform.md>), [library](<https://devfeed.tech/tags/library.md>), [logging](<https://devfeed.tech/tags/logging.md>), [mobile](<https://devfeed.tech/tags/mobile.md>), [software](<https://devfeed.tech/tags/software.md>)

### AI overview

This tutorial shows how to create a custom Logger class around Kermit for Kotlin Multiplatform. It demonstrates replacing Kermit's Logger.i syntax with custom methods such as Logger.info and Logger.error, while noting that the example is a simplified version of the full Logger API.

### Source excerpt

In the realm of Kotlin Multiplatform logging, the Kermit library stands as a trusted companion for developers. However, some find its conventional logger.i syntax less appealing. What if you could improve your logging experience with a touch of personalization? Enter the world of custom logger, where logger.info becomes a reality. Diving into Custom Logging The journey begins with a glance at a custom code snippet that transforms the Kermit logging experience. This code introduces a custom Logger class adorned with methods like info, and error--a testament to the flexibility Kermit provides for tailoring logging to your liking. Note that example code below is a very toned down version of full Logger API. It helps with keeping the code minimal while still delivering the idea behind it. import co.touchlab.kermit.BaseLogger import co.touchlab.kermit.LoggerConfig import co.touchlab.kermit.Severity import co.touchlab.kermit.mutableLoggerConfigInit import co.touchlab.kermit.platformLogWriter open class Logger( config: LoggerConfig, open val tag: String = "MyDefaultTag" ) : BaseLogger(config) { inline fun info(throwable: Throwable? = null, tag: String = this.tag, message: () -> String) { logBlock(Info, tag, throwable, message) } inline fun error(throwable: Throwable? = null, tag: String = this.tag, message: () -> String) { logBlock(Error, tag, throwable, message) } inline fun info(messageString: String, throwable: Throwable? = null, tag: String = this.tag) { log(Info, tag, throwable, messageString) } inline fun error(messageString: String, throwable: Throwable? = null, tag: String = this.tag) { log(Error, tag, throwable, messageString) } companion object : Logger(mutableLoggerConfigInit(listOf(platformLogWriter()))) } Now instead of calling Kermit's API, you can call your own methods. Call Logger.info(...) rather than Logger.i(...) Kermit-core This flexiblity comes from the modularized kermit components. If you prefer to have custom logger then you need to only depends on k

## Optimizing Gradle Builds in Multi-module Projects

DevFeed: [Optimizing Gradle Builds in Multi-module Projects](<https://devfeed.tech/articles/optimizing-gradle-builds-in-multi-module-projects-24719.md>)

Original publisher: [Read original article](<https://dev.to/touchlab/optimizing-gradle-builds-in-multi-module-projects-3ijp>)

Author: Jigar Brahmbhatt

Published: 2023-10-16T20:31:31Z

Content type: tutorial

Language: en

Sources: [Touchlab](<https://devfeed.tech/sources/touchlab.md>)

Topics: [Gradle](<https://devfeed.tech/topics/gradle.md>), [build times](<https://devfeed.tech/topics/build-times.md>), [build performance](<https://devfeed.tech/topics/build-performance.md>), [Kotlin Multiplatform](<https://devfeed.tech/topics/kotlin-multiplatform.md>), [multiplatform](<https://devfeed.tech/topics/multiplatform.md>), [Android Studio](<https://devfeed.tech/topics/android-studio.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Cache](<https://devfeed.tech/topics/cache.md>), [ci](<https://devfeed.tech/topics/ci.md>)

Tags: [android-studio](<https://devfeed.tech/tags/android-studio.md>), [build-performance](<https://devfeed.tech/tags/build-performance.md>), [build-times](<https://devfeed.tech/tags/build-times.md>), [cache](<https://devfeed.tech/tags/cache.md>), [ci](<https://devfeed.tech/tags/ci.md>), [coding](<https://devfeed.tech/tags/coding.md>), [community](<https://devfeed.tech/tags/community.md>), [development](<https://devfeed.tech/tags/development.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [gradle](<https://devfeed.tech/tags/gradle.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-multiplatform](<https://devfeed.tech/tags/kotlin-multiplatform.md>), [kotlinmultiplatform](<https://devfeed.tech/tags/kotlinmultiplatform.md>), [mobile](<https://devfeed.tech/tags/mobile.md>), [multiplatform](<https://devfeed.tech/tags/multiplatform.md>), [software](<https://devfeed.tech/tags/software.md>), [tech-debt](<https://devfeed.tech/tags/tech-debt.md>)

### AI overview

A practical guide to improving Gradle build times in multi-module Kotlin Multiplatform projects. It recommends benchmarking with the build cache disabled, using Gradle Build Scan and Android Studio Build Analyser, addressing legacy configuration such as Jetifier, and enabling parallel builds. The authors report more than a 50% speed improvement for a client with over 100 modules.

### Source excerpt

You're not alone if you've also struggled with sluggish Gradle builds in a multi-module project. Recently, we undertook the challenge of significantly reducing build times for a client with over 100 Kotlin Multiplatform modules, and achieved a more than 50% boost in speed across platforms. In this post, we'll walk you through the steps we took. We hope it proves valuable to fellow developers facing similar challenges. Benchmark Your Builds Before diving into optimizations, it's crucial to understand the baseline. Gather build times from all team members, ensuring the Gradle build cache is disabled. Use handy --no-build-cache option to any Gradle task command to run without build cache. Unsurprisingly, in our case, the Intel-based mac machines were really slow compared to Apple chip ones and we didn't have anyone with a Windows machine. This information is key for later comparison and improvement assessment. Note: One thing we realized that, some optimizations below might be more applicable to legacy or tech-debt-laden projects. Tools for Insight Gradle Build Scan Utilize the power of Gradle Build Scan to delve into the details of your builds. In my opinion, it's not just a diagnostic tool; it's a learning tool. In our case, we uncovered insights into the sluggishness of ios link tasks in the Kotlin Multiplatform setup. Comparing build scans on different CI machines helped identify the fastest configuration for a machine to use on our CI. Enabling parallel builds and analyzing the results through build scan reports further validated our improvements. Android Studio Build Analyser Android Studio provides a built-in analyser tool. It inspects build performance and provides warning around potential issues. Disable Jetifier Using this, we noticed the lingering android.enableJetifier=true usage due to outdated Picasso library that didn't use AndroidX libraries. That might have hindered build speed too. Addressing this involved updating Picasso and removing the jetifier fl

## KMM: A Use case for common UI behavior

DevFeed: [KMM: A Use case for common UI behavior](<https://devfeed.tech/articles/kmm-a-use-case-for-common-ui-behavior-24716.md>)

Original publisher: [Read original article](<https://dev.to/touchlab/kmm-a-use-case-for-common-ui-behavior-2mi3>)

Author: Jigar Brahmbhatt

Published: 2023-01-30T20:03:37Z

Content type: tutorial

Language: en

Sources: [Touchlab](<https://devfeed.tech/sources/touchlab.md>)

Topics: [Kotlin Multiplatform](<https://devfeed.tech/topics/kotlin-multiplatform.md>), [Code](<https://devfeed.tech/topics/code.md>), [Refactoring](<https://devfeed.tech/topics/refactoring.md>), [ui](<https://devfeed.tech/topics/ui.md>), [Web](<https://devfeed.tech/topics/web.md>)

Tags: [code](<https://devfeed.tech/tags/code.md>), [coding](<https://devfeed.tech/tags/coding.md>), [community](<https://devfeed.tech/tags/community.md>), [developer](<https://devfeed.tech/tags/developer.md>), [development](<https://devfeed.tech/tags/development.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [implementation](<https://devfeed.tech/tags/implementation.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [kmm](<https://devfeed.tech/tags/kmm.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-multiplatform](<https://devfeed.tech/tags/kotlin-multiplatform.md>), [kotlinmultiplatform](<https://devfeed.tech/tags/kotlinmultiplatform.md>), [mobile](<https://devfeed.tech/tags/mobile.md>), [multiplatform](<https://devfeed.tech/tags/multiplatform.md>), [platforms](<https://devfeed.tech/tags/platforms.md>), [regex](<https://devfeed.tech/tags/regex.md>), [sdk](<https://devfeed.tech/tags/sdk.md>), [software](<https://devfeed.tech/tags/software.md>), [ui](<https://devfeed.tech/tags/ui.md>), [ux](<https://devfeed.tech/tags/ux.md>), [web](<https://devfeed.tech/tags/web.md>)

### AI overview

The article describes implementing auto-formatting for a phone number field across Android, iOS, and ReactJS in a Kotlin Multiplatform SDK. After platform-specific implementations exposed repeated cursor-position edge cases, the authors refactored the string and cursor-position logic into common code.

### Source excerpt

This post demonstrates how we used common KMP code for a common UI feature across three platforms. Requirement Recently, we got a new feature requirement for the SDK we're developing using Kotlin Multiplatform (KMP). The SDK has a typical UI form with a variety of fields in it that the user fills out. One of the fields is a phone number field. The requirement was to auto-format the number as the user types it out. The end behavior would be like this, How we did it initially We usually divide KMP work based on UI stories for each platform and a task for any required work in the commonMain layer. For deeper dive into how we divide KMP work, checkout Kevin's post about it Following the same approach, first, we added a couple of utility methods in common code to format and unformat the phone number. commonMain fun formatPhoneNumber(number: String): String { // return formatted number using regex } fun unformatPhoneNumber(number: CharSequence): String { // return unformatted number using regex } Then we worked on individual platform UI implementation. Android We implemented a custom TextWatcher and handled the logic in beforeTextChanged and afterTextChanged methods. iOS On iOS, we used @objc func textFieldDidChange(_ sender: UITextField) to handle formatting while entering the number entering, and func textField() with the shouldChangeCharactersIn option to format the number when deleting. Web On ReactJS, we used onChange of the TextField to implement custom logic for formatting. What worked and what went wrong What worked was that each platform performed the same for the general use case of entering and deleting the number due to having common knowledge and JIRA tickets for them. What differed between each platform was how the individual developer approached edge cases around entering and deleting the input from a specific cursor position. For example, consider the input like this (123) 456-7890. Now user wants to remove the number 6 and manually sets the cursor positio

## Multiplatform Settings 1.0.0

DevFeed: [Multiplatform Settings 1.0.0](<https://devfeed.tech/articles/multiplatform-settings-1-0-0-24999.md>)

Original publisher: [Read original article](<https://dev.to/russhwolf/multiplatform-settings-100-5eoa>)

Author: Russell Wolf

Published: 2023-01-15T03:12:17Z

Content type: release

Language: en

Sources: [DEV Community 👩💻👨💻: Russell Wolf](<https://devfeed.tech/sources/dev-community-russell-wolf.md>)

Topics: [kotlin-multiplatform-libraries](<https://devfeed.tech/topics/kotlin-multiplatform-libraries.md>), [Kotlin Multiplatform](<https://devfeed.tech/topics/kotlin-multiplatform.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Library](<https://devfeed.tech/topics/library.md>), [Android](<https://devfeed.tech/topics/android.md>), [iOS](<https://devfeed.tech/topics/ios.md>), [macOS](<https://devfeed.tech/topics/macos.md>), [tvOS](<https://devfeed.tech/topics/tvos.md>), [watchOS](<https://devfeed.tech/topics/watchos.md>), [Windows](<https://devfeed.tech/topics/windows.md>), [Web](<https://devfeed.tech/topics/web.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [coding](<https://devfeed.tech/tags/coding.md>), [community](<https://devfeed.tech/tags/community.md>), [development](<https://devfeed.tech/tags/development.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [ios](<https://devfeed.tech/tags/ios.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-multiplatform](<https://devfeed.tech/tags/kotlin-multiplatform.md>), [kotlin-multiplatform-libraries](<https://devfeed.tech/tags/kotlin-multiplatform-libraries.md>), [kotlinmultiplatform](<https://devfeed.tech/tags/kotlinmultiplatform.md>), [library](<https://devfeed.tech/tags/library.md>), [macos](<https://devfeed.tech/tags/macos.md>), [release](<https://devfeed.tech/tags/release.md>), [software](<https://devfeed.tech/tags/software.md>), [watchos](<https://devfeed.tech/tags/watchos.md>), [web](<https://devfeed.tech/tags/web.md>), [windows](<https://devfeed.tech/tags/windows.md>)

### AI overview

The author announces version 1.0.0 of Multiplatform Settings, a Kotlin Multiplatform library for persisting simple, unstructured key-value data. The release commits to maintaining non-experimental APIs until a possible 2.0 release and compares the library's platform-API interoperation with Google's preview multiplatform DataStore library.

### Source excerpt

Today, I've released version 1.0.0 of Multiplatform Settings. That means I'm committed to maintaining the current API surface of everything not marked as experimental until there's a 2.0 release (which I don't currently have plans for). If you need to save simple, unstructured key-value data in your multiplatform apps, I hope you'll consider using it. A lot of you already are! russhwolf / multiplatform-settings A Kotlin Multiplatform library for saving simple key-value data Multiplatform Settings This is a Kotlin library for Multiplatform apps, so that common code can persist key-value data. A Korean translation of this readme is available separately, maintained by @wooram-yang Table of contents Usage Implementation Summary Creating a Settings instance Platform constructors Factories No-arg module Settings API Listeners Testing Other platforms Experimental API Experimental Implementations Serialization module Coroutine APIs DataStore Make-Observable module Adding to your project Building License Usage The Settings interface has implementations on the Android, iOS, macOS, watchOS, tvOS, JS, WasmJS, JVM, and Windows platforms. Implementation Summary The following table shows the names of implementing classes and what platforms they're available on. Class Backing API Platforms KeychainSettings2 Apple Keychain iOS, macOS, watchOS, tvOS NSUserDefaultsSettings1 User Defaults iOS, macOS, watchOS, tvOS PreferencesSettings1 java.util.prefs.Preferences JVM PropertiesSettings java.util.Properties JVM SharedPreferencesSettings1 android.content.SharedPreferences Android StorageSettings Web Storage (localStorage) JS, WasmJS RegistrySettings2 Windows Registry MingwX64 DataStoreSettings3 androidx.datastore.core.DataStore Android, ... View on GitHub Some History Multiplatform Settings was one of the first Kotlin Multiplatform libraries ever released, with the first version published on May 28, 2018. I called that first version 0.1-alpha, though I would later drop the alpha from the ve

## Introducing KMMBridge For Teams

DevFeed: [Introducing KMMBridge For Teams](<https://devfeed.tech/articles/introducing-kmmbridge-for-teams-24712.md>)

Original publisher: [Read original article](<https://dev.to/touchlab/introducing-kmmbridge-for-teams-32ad>)

Author: Touchlab

Published: 2022-10-10T19:25:17Z

Content type: release

Language: en

Sources: [Touchlab](<https://devfeed.tech/sources/touchlab.md>)

Topics: [Kotlin Multiplatform](<https://devfeed.tech/topics/kotlin-multiplatform.md>), [Mobile](<https://devfeed.tech/topics/mobile.md>), [Tooling](<https://devfeed.tech/topics/tooling.md>), [iOS](<https://devfeed.tech/topics/ios.md>), [kotlin-multiplatform-libraries](<https://devfeed.tech/topics/kotlin-multiplatform-libraries.md>)

Tags: [build](<https://devfeed.tech/tags/build.md>), [coding](<https://devfeed.tech/tags/coding.md>), [community](<https://devfeed.tech/tags/community.md>), [development](<https://devfeed.tech/tags/development.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [ios](<https://devfeed.tech/tags/ios.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-multiplatform](<https://devfeed.tech/tags/kotlin-multiplatform.md>), [kotlinmultiplatform](<https://devfeed.tech/tags/kotlinmultiplatform.md>), [mobile](<https://devfeed.tech/tags/mobile.md>), [sdk](<https://devfeed.tech/tags/sdk.md>), [software](<https://devfeed.tech/tags/software.md>), [tooling](<https://devfeed.tech/tags/tooling.md>)

### AI overview

Touchlab announces KMMBridge, a build-tools suite in its Faktory1 tooling suite. KMMBridge helps mobile teams pre-build and publish Kotlin Multiplatform Mobile Xcode Frameworks as internal SDKs for iOS integration.

### Source excerpt

Introducing KMMBridge for Teams Today we are announcing KMMBridge, part of Touchlab's new Faktory1 tooling suite. This set of build tools allows mobile teams to successfully publish shared code faster than ever with Kotlin Multiplatform Mobile. Specifically targeted at iOS publishing, teams can now implement the Internal SDK Flow approach, today's best practice to quickly integrate KMM into production app builds. To try it for yourself, visit https://github.com/touchlab/KMMBridge KMMBridge allows teams to publish and integrate Kotlin Multiplatform Mobile (KMM) Xcode Frameworks as an internal SDK. When you're ready, head to our Quickstart Guide to KMMBridge to get started! Why We Built a Team-Focused Tool Touchlab has spent years working with teams at different stages of their Kotlin Multiplatform journey. Evaluating KMP, putting KMP into production, and yes, even a fair bit of time talking to teams who looked at KMP and decided against it. One of the key lessons we've learned seems obvious in retrospect. Different types of teams work in different ways. Of course, every team is different. Every situation will be different. However, there are common patterns. Out of the box, the KMP and the Kotlin/Native toolkit will let you build an Xcode Framework, then integrate it locally into your Xcode project. This works well if everybody on the team builds Kotlin. And in an ideal world, everybody would be able to build Kotlin. But in the real world, most teams who have succeeded followed the Internal SDK Flow approach. The Internal SDK Flow Approach As with adopting any technology on a team, early wins help build momentum and confidence so the team can unlock the full potential over time. The Internal SDK Flow has emerged as the best practice to get faster ROI when adopting KMM. At its simplest, this approach means the Kotlin Xcode Framework is pre-built and published as an internal SDK (a private module shared with your team) so iOS developers can include it without building

## Looking toward Multiplatform Settings 1.0.0

DevFeed: [Looking toward Multiplatform Settings 1.0.0](<https://devfeed.tech/articles/looking-toward-multiplatform-settings-1-0-0-24998.md>)

Original publisher: [Read original article](<https://dev.to/russhwolf/looking-toward-multiplatform-settings-100-10aa>)

Author: Russell Wolf

Published: 2022-07-25T00:02:18Z

Content type: release

Language: en

Sources: [DEV Community 👩💻👨💻: Russell Wolf](<https://devfeed.tech/sources/dev-community-russell-wolf.md>)

Topics: [Kotlin Multiplatform](<https://devfeed.tech/topics/kotlin-multiplatform.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Library](<https://devfeed.tech/topics/library.md>), [Mobile](<https://devfeed.tech/topics/mobile.md>), [consistency](<https://devfeed.tech/topics/consistency.md>)

Tags: [coding](<https://devfeed.tech/tags/coding.md>), [community](<https://devfeed.tech/tags/community.md>), [consistency](<https://devfeed.tech/tags/consistency.md>), [development](<https://devfeed.tech/tags/development.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [implementation](<https://devfeed.tech/tags/implementation.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-multiplatform](<https://devfeed.tech/tags/kotlin-multiplatform.md>), [kotlinmultiplatform](<https://devfeed.tech/tags/kotlinmultiplatform.md>), [library](<https://devfeed.tech/tags/library.md>), [mobile](<https://devfeed.tech/tags/mobile.md>), [multiplatform](<https://devfeed.tech/tags/multiplatform.md>), [software](<https://devfeed.tech/tags/software.md>)

### AI overview

The article announces preparations for Multiplatform Settings 1.0.0, including breaking API changes, migration aids, and a recent 0.9 release for users who are not ready to migrate. It describes the Kotlin Multiplatform library's platform implementations and planned API updates.

### Source excerpt

The first version of Multiplatform Settings was released in May 2018. At that time I imagined I would leave it in some form of prerelease 0.x state until Kotlin/Native and Kotlin Multiplatform were fully stable. But it's been over four years now, and plenty of other libraries in the ecosystem have gone 1.0. With the Kotlin Multiplatform Mobile beta on the horizon, I've decided it's about time for Multiplatform Settings to have a stable release. In preparation for that, I recently released version 1.0.0-alpha01. This includes a number of breaking changes in order to make the API a bit more consistent and intuitive. I've done my best to provide migration aids in the form of @Deprecated annotations which in most cases will allow users to update automatically. But if for some reason you're not ready to do that, version 0.9 was also released recently with almost all the same functionality and none of the breakage. If you've never heard of Multiplatform Settings or you'd like to take a closer look, be sure check it out on Github! russhwolf / multiplatform-settings A Kotlin Multiplatform library for saving simple key-value data Multiplatform Settings This is a Kotlin library for Multiplatform apps, so that common code can persist key-value data. A Korean translation of this readme is available separately, maintained by @wooram-yang Table of contents Usage Implementation Summary Creating a Settings instance Platform constructors Factories No-arg module Settings API Listeners Testing Other platforms Experimental API Experimental Implementations Serialization module Coroutine APIs DataStore Make-Observable module Adding to your project Building License Usage The Settings interface has implementations on the Android, iOS, macOS, watchOS, tvOS, JS, WasmJS, JVM, and Windows platforms. Implementation Summary The following table shows the names of implementing classes and what platforms they're available on. Class Backing API Platforms KeychainSettings2 Apple Keychain iOS, macOS,

## Different ways to distribute and integrate Kotlin/JS library

DevFeed: [Different ways to distribute and integrate Kotlin/JS library](<https://devfeed.tech/articles/different-ways-to-distribute-and-integrate-kotlin-js-library-24710.md>)

Original publisher: [Read original article](<https://dev.to/touchlab/different-ways-to-distribute-and-integrate-kotlinjs-library-1hg3>)

Author: Jigar Brahmbhatt

Published: 2022-07-11T20:24:11Z

Content type: tutorial

Language: en

Sources: [Touchlab](<https://devfeed.tech/sources/touchlab.md>)

Topics: [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Library](<https://devfeed.tech/topics/library.md>), [Gradle](<https://devfeed.tech/topics/gradle.md>), [JavaScript](<https://devfeed.tech/topics/javascript.md>), [Webpack](<https://devfeed.tech/topics/webpack.md>), [npm](<https://devfeed.tech/topics/npm.md>), [TypeScript](<https://devfeed.tech/topics/typescript.md>), [browser](<https://devfeed.tech/topics/browser.md>)

Tags: [browser](<https://devfeed.tech/tags/browser.md>), [coding](<https://devfeed.tech/tags/coding.md>), [community](<https://devfeed.tech/tags/community.md>), [development](<https://devfeed.tech/tags/development.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [gradle](<https://devfeed.tech/tags/gradle.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [javascript](<https://devfeed.tech/tags/javascript.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlinjs](<https://devfeed.tech/tags/kotlinjs.md>), [kotlinmultiplatform](<https://devfeed.tech/tags/kotlinmultiplatform.md>), [library](<https://devfeed.tech/tags/library.md>), [npm](<https://devfeed.tech/tags/npm.md>), [software](<https://devfeed.tech/tags/software.md>), [typescript](<https://devfeed.tech/tags/typescript.md>), [webpack](<https://devfeed.tech/tags/webpack.md>)

### AI overview

A tutorial on distributing and integrating Kotlin/JS libraries in a Kotlin Multiplatform setup. It explains browser and Node.js targets, library and executable binaries, Gradle distribution tasks, Webpack bundles, and publishing output as an npm module with JavaScript and TypeScript usage.

### Source excerpt

Note that examples in this post use Kotlin 1.7.0 In the previous post in the Kotlin/JS series, we learned about @JsExport to expose Kotlin code on the JS side. Now, we would look at various ways to distribute a JS library code through a KMP setup. Table Of Contents Gradle Setup Webpack Node Module npm-publish Using the library Use webpack executable HTML JavaScript TypeScript Use as node module HTML JavaScript TypeScript Gradle Setup If you don't already have a JS target in your KMP library project, then you should check out this blog post first. Let's look at common options to use for JS target, js(IR) { browser() nodejs() binaries.library() binaries.executable() } browser() It sets the JavaScript target execution environment as browser. It provides a Gradle task--jsBrowserTest that runs all js tests inside the browser using karma and webpack. nodejs() It sets the JavaScript target execution environment as nodejs. It provides a Gradle task--jsNodeTest that runs all js tests inside nodejs using the built-in test framework. binaries.library() It tells the Kotlin compiler to produce Kotlin/JS code as a distributable node library. Depending on which target you've used along with this, you would get Gradle tasks to generate library distribution files. Kotlin browser tasks -------------------- jsBrowserDevelopmentLibraryDistribution jsBrowserDevelopmentLibraryPrepare jsBrowserProductionLibraryDistribution jsBrowserProductionLibraryPrepare Kotlin node tasks ----------------- jsNodeDevelopmentLibraryDistribution jsNodeDevelopmentLibraryPrepare jsNodeDevelopmentRun jsNodeProductionLibraryDistribution jsNodeProductionLibraryPrepare jsNodeProductionRun jsNodeRun EitherjsBrowserProductionLibraryDistribution or jsNodeProductionLibraryDistribution task generates output files in <YourLibModule>/build/productionLibrary folder binaries.executable() It tells the Kotlin compiler to produce Kotlin/JS code as webpack executable .js files. Enabling this option generates the following Grad

## @JsExport guide for exposing Kotlin to JS

DevFeed: [@JsExport guide for exposing Kotlin to JS](<https://devfeed.tech/articles/jsexport-guide-for-exposing-kotlin-to-js-24714.md>)

Original publisher: [Read original article](<https://dev.to/touchlab/jsexport-guide-for-exposing-kotlin-to-js-20l9>)

Author: Jigar Brahmbhatt

Published: 2022-03-14T16:19:31Z

Content type: tutorial

Language: en

Sources: [Touchlab](<https://devfeed.tech/sources/touchlab.md>)

Topics: [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [JavaScript](<https://devfeed.tech/topics/javascript.md>)

Tags: [coding](<https://devfeed.tech/tags/coding.md>), [community](<https://devfeed.tech/tags/community.md>), [compiler](<https://devfeed.tech/tags/compiler.md>), [development](<https://devfeed.tech/tags/development.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [experimental](<https://devfeed.tech/tags/experimental.md>), [guide](<https://devfeed.tech/tags/guide.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [javascript](<https://devfeed.tech/tags/javascript.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlinjs](<https://devfeed.tech/tags/kotlinjs.md>), [kotlinmultiplatform](<https://devfeed.tech/tags/kotlinmultiplatform.md>), [software](<https://devfeed.tech/tags/software.md>)

### AI overview

A guide to exposing Kotlin code to JavaScript through Kotlin/JS using the experimental @JsExport annotation. It explains that Kotlin declarations are hidden from JavaScript by default, demonstrates annotating a Greeting class, and notes that the generated .js and .d.ts files then include the class reference.

### Source excerpt

Note that this post focuses on JS output for Kotlin. There is also a Typescript output (.d.ts file) with some unique issues that this post doesn't cover in detail. In the previous post, we added Kotlin/JS support to an existing KMM library. Now, we would add code that works on the JS side. Table Of Contents Usage @ExperimentalJsExport vs @JsExport Limitations Collections Long Interface Solution - Using Implementation class Solution - Using Expect-Actual Enum Sealed classes Code mangling Suspended functions Usage It is critical to understand @JsExport annotation and all the issues around it if you expose Kotlin code through Kotlin/JS as an external JS library With the new IR compiler, Kotlin declarations do not get exposed to JavaScript by default. To make Kotlin declarations visible to JavaScript, they must be annotated with @JsExport. Note that @JsExport is experimental as of the posted date of this post (with Kotlin 1.6.10) Let's start with a very basic example, // commonMain - Greeting.kt class Greeting { fun greeting(): String { return "Hello World!" } } At this point, the generated .js library file would not have any reference to the Greeting class. The reason is that it is missing the @JsExport annotation. You can generate JS library code via ./gradlew jsBrowserDistribution. You would find the .js, .d.ts and map file in root/build/js/packages/<yourlibname>/kotlin folder. Now, add the annotation to generate JS code for it, import kotlin.js.ExperimentalJsExport import kotlin.js.JsExport @ExperimentalJsExport @JsExport class Greeting { fun greeting(): String { return "Hello World!" } } The .js and .d.ts files would now contain the Greeting reference. Generated .js file ```javascript function Greeting() { } Greeting.prototype.greeting = function () { return 'Hello World!'; }; Greeting.$metadata$ = { simpleName: 'Greeting', kind: 'class', interfaces: [] }; - **Generated .d.ts file** ```typescript export namespace jabbar.jigariyo.kmplibrary { class Greeting { constr

## Trying out the experimental new Kotlin/Native memory model

DevFeed: [Trying out the experimental new Kotlin/Native memory model](<https://devfeed.tech/articles/trying-out-the-experimental-new-kotlin-native-memory-model-25004.md>)

Original publisher: [Read original article](<https://dev.to/touchlab/trying-out-the-experimental-new-kotlin-native-memory-model-235k>)

Author: Russell Wolf

Published: 2021-08-07T15:54:36Z

Content type: tutorial

Language: en

Sources: [DEV Community 👩💻👨💻: Russell Wolf](<https://devfeed.tech/sources/dev-community-russell-wolf.md>)

Topics: [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Concurrency](<https://devfeed.tech/topics/concurrency.md>), [Compiler](<https://devfeed.tech/topics/compiler.md>), [Gradle](<https://devfeed.tech/topics/gradle.md>), [Coroutines](<https://devfeed.tech/topics/coroutines.md>)

Tags: [coding](<https://devfeed.tech/tags/coding.md>), [community](<https://devfeed.tech/tags/community.md>), [compiler](<https://devfeed.tech/tags/compiler.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [development](<https://devfeed.tech/tags/development.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [experimental](<https://devfeed.tech/tags/experimental.md>), [gradle](<https://devfeed.tech/tags/gradle.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-native](<https://devfeed.tech/tags/kotlin-native.md>), [kotlinmultiplatform](<https://devfeed.tech/tags/kotlinmultiplatform.md>), [native](<https://devfeed.tech/tags/native.md>), [software](<https://devfeed.tech/tags/software.md>)

### AI overview

This article explores the experimental new Kotlin/Native memory model available in the Kotlin 1.5.30 early-access release. It explains how to enable the model, disable compiler caching, use coroutines with it, and mutate unfrozen state across threads while noting that freeze semantics still apply in some cases.

### Source excerpt

Photo by Victor Serban on Unsplash Update Aug 12, 2021: This article has been updated with a new section about using the new memory model with kotlinx-coroutines. If you've been following Kotlin/Native at all over the last couple of years, you'll know that it's memory model has been controversial. Last year, the Kotlin team committed to redesigning it, and this year they promised a preview by the end of the summer. Well, there hasn't been an official announcement yet, but that preview is present in the Kotlin 1.5.30 early-access release. TL,DR Update your Kotlin version to 1.5.30-RC Add kotlinOptions.freeCompilerArgs += listOf("-memory-model", "experimental") to your Kotlin/Native compilations Add kotlin.native.cacheKind=none to gradle.properties To use coroutines with the new model, add https://maven.pkg.jetbrains.space/public/p/kotlinx-coroutines/maven to repositories and use version 1.5.1-new-mm-dev1. Mutate unfrozen objects from different threads Wait, what?! Yup! The memory model is controlled with the -memory-model command-line flag. Pass experimental for the new model or strict for the existing one*. Due to current limitations, you also need to disable compiler caching with the kotlin.native.cacheKind=none gradle property. *You can also pass relaxed, but it's probably not a good idea. You can pass the flag to all your Kotlin/Native targets by doing something like this from Gradle: kotlin { targets.withType<KotlinNativeTarget>().all { compilations.all { kotlinOptions.freeCompilerArgs += listOf("-memory-model", "experimental") } } } Now you can freely mutate unfrozen state across threads. Let's see what that looks like. Testing the two models In the current strict memory model, if you wanted to write a function to run code in a background thread, it might look something like this: fun <T> doInBackground(action: () -> T): T { val worker = Worker.start() val future = worker.execute( TransferMode.SAFE, { action.freeze() }, { it() } ) return future.result } The fun

## Kotlin Coroutines and Swift, revisited

DevFeed: [Kotlin Coroutines and Swift, revisited](<https://devfeed.tech/articles/kotlin-coroutines-and-swift-revisited-25003.md>)

Original publisher: [Read original article](<https://dev.to/touchlab/kotlin-coroutines-and-swift-revisited-j5h>)

Author: Russell Wolf

Published: 2021-06-04T20:50:38Z

Content type: tutorial

Language: en

Sources: [DEV Community 👩💻👨💻: Russell Wolf](<https://devfeed.tech/sources/dev-community-russell-wolf.md>)

Topics: [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [kotlin-coroutines](<https://devfeed.tech/topics/kotlin-coroutines.md>), [Coroutines](<https://devfeed.tech/topics/coroutines.md>), [Swift](<https://devfeed.tech/topics/swift.md>), [iOS](<https://devfeed.tech/topics/ios.md>), [reactive](<https://devfeed.tech/topics/reactive.md>), [implementation](<https://devfeed.tech/topics/implementation.md>)

Tags: [article](<https://devfeed.tech/tags/article.md>), [code](<https://devfeed.tech/tags/code.md>), [coding](<https://devfeed.tech/tags/coding.md>), [community](<https://devfeed.tech/tags/community.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [development](<https://devfeed.tech/tags/development.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [implementation](<https://devfeed.tech/tags/implementation.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-coroutines](<https://devfeed.tech/tags/kotlin-coroutines.md>), [kotlinmultiplatform](<https://devfeed.tech/tags/kotlinmultiplatform.md>), [reactive](<https://devfeed.tech/tags/reactive.md>), [software](<https://devfeed.tech/tags/software.md>), [swift](<https://devfeed.tech/tags/swift.md>)

### AI overview

This article revisits interoperability patterns between Kotlin coroutines and Swift on iOS. It updates a callback wrapper by moving CoroutineScope management into a Kotlin constructor, adds a Swift wrapper to hide Kotlin implementation details, and discusses adapting callback-based streams for reactive frameworks including Combine.

### Source excerpt

Last year I wrote about a pattern for interop between Kotlin coroutines and RxSwift. I appreciate the attention it received, particularly where people have applied it to other reactive frameworks, and even including a code-generation plugin using the same ideas. I figure it's about time I talk about my own updated thinking on these patterns. If you haven't read the previous article, I suggest going through that first for context. Kotlin updates We'll stick to the same repository class as the original article, and walk through exposing it to iOS. class ThingRepository { suspend fun getThing(succeed: Boolean): Thing { delay(100) if (succeed) { return Thing(0) } else { error("oh no!") } } fun getThingStream( count: Int, succeed: Boolean ): Flow<Thing> = flow { repeat(count) { delay(100) emit(Thing(it)) } if (!succeed) error("oops!") } } In the previous article, I suggested the following pattern for wrapping suspend functions with callbacks that could run on iOS class SuspendWrapper<T>(private val suspender: suspend () -> T) { init { freeze() } fun subscribe( scope: CoroutineScope, onSuccess: (item: T) -> Unit, onThrow: (error: Throwable) -> Unit ): Job = scope.launch { try { onSuccess(suspender().freeze()) } catch (error: Throwable) { onThrow(error.freeze()) } }.freeze() } After having played with these patterns more, a drawback to this emerged. This class expects a CoroutineScope to be supplied by the caller (which will be in Swift) at subscription time. This can be nice for flexibility if it might be called in different contexts, but in the vast majority of cases in practice this will live in some sort of class with its own scope, and it's much more pleasant to work with the scope from Kotlin than from Swift. So let's make the scope a constructor parameter instead. class SuspendWrapper<T : Any>( private val scope: CoroutineScope, private val suspender: suspend () -> T ) { init { freeze() } fun subscribe( onSuccess: (item: T) -> Unit, onThrow: (error: Throwable) -> Un

## Multiplatform Settings version 0.7 is out!

DevFeed: [Multiplatform Settings version 0.7 is out!](<https://devfeed.tech/articles/multiplatform-settings-version-0-7-is-out-25001.md>)

Original publisher: [Read original article](<https://dev.to/russhwolf/multiplatform-settings-version-0-7-is-out-2l0>)

Author: Russell Wolf

Published: 2020-12-27T00:37:48Z

Content type: release

Language: en

Sources: [DEV Community 👩💻👨💻: Russell Wolf](<https://devfeed.tech/sources/dev-community-russell-wolf.md>)

Topics: [multiplatform](<https://devfeed.tech/topics/multiplatform.md>), [Coroutines](<https://devfeed.tech/topics/coroutines.md>), [releases](<https://devfeed.tech/topics/releases.md>), [Android](<https://devfeed.tech/topics/android.md>), [Jetpack](<https://devfeed.tech/topics/jetpack.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [coding](<https://devfeed.tech/tags/coding.md>), [community](<https://devfeed.tech/tags/community.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [database](<https://devfeed.tech/tags/database.md>), [development](<https://devfeed.tech/tags/development.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [jetpack](<https://devfeed.tech/tags/jetpack.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlinmultiplatform](<https://devfeed.tech/tags/kotlinmultiplatform.md>), [multiplatform](<https://devfeed.tech/tags/multiplatform.md>), [news](<https://devfeed.tech/tags/news.md>), [release](<https://devfeed.tech/tags/release.md>), [serialization](<https://devfeed.tech/tags/serialization.md>), [software](<https://devfeed.tech/tags/software.md>)

### AI overview

The article announces Multiplatform Settings version 0.7. It describes kotlinx.serialization integration for storing serializable values, Flow extensions, and coroutine-based interfaces intended to work with suspend-based key-value storage such as Jetpack DataStore.

### Source excerpt

Today I've released version 0.7 of Multiplatform Settings! There's a lot of new features in this one, including integrations with some of the kotlinx libraries which have been incubating in PRs for a long time, so I'm excited to hear what people think. TL;DR links Release Notes Maven Central Read on for more details on what's new. Serialization I've had the idea in my head for a while that I'd like to generalize the existing delegate APIs to enable storing non-primitive data. Thanks to some suggestions from Eugenio Marletti and Leonid Startsev I came to realize how that could be done using kotlinx.serialization, by using its custom format APIs. There's been a PR open for a while which I iterated on as the serialization library adjusted those APIs and approached it's first stable release. Now that the library has reached 1.0, even if most of the encoder/decoder APIs are still experimental, it feels like the right time to release the integration with Multiplatform Settings. With this, if you have a serializable class like @Serializable class User(val nickname: String?) you can save an instance to Settings by calling settings.encodeValue(User.serializer(), "user", user) and retrieve it with val user: User = settings.decodeValue( User.serializer(), "user", defaultValue ) val nullableUser: User? = settings.decodeValueOrNull( User.serializer(), "user" ) or you could do both via a delegate api var user by settings.serializedValue(User.serializer(), "user") Of course, it's no substitute for a structured database like sqlite if you need atomicity for more complex data, but for simple use-cases I hope people find it helpful. I also think it's also a neat demonstration of some less well-known parts of kotlinx.serialization, so I hope it can inspire other interesting custom formats as well. Coroutines Similar to serialization, there's been a PR up for a while with Flow extensions on ObservableSettings. That's finally merged in 0.7, with two different artifacts depending on whet

## Working with Kotlin Coroutines and RxSwift

DevFeed: [Working with Kotlin Coroutines and RxSwift](<https://devfeed.tech/articles/working-with-kotlin-coroutines-and-rxswift-25005.md>)

Original publisher: [Read original article](<https://dev.to/touchlab/working-with-kotlin-coroutines-and-rxswift-24fa>)

Author: Russell Wolf

Published: 2020-06-15T19:07:18Z

Content type: tutorial

Language: en

Sources: [DEV Community 👩💻👨💻: Russell Wolf](<https://devfeed.tech/sources/dev-community-russell-wolf.md>)

Topics: [kotlin-coroutines](<https://devfeed.tech/topics/kotlin-coroutines.md>), [Coroutines](<https://devfeed.tech/topics/coroutines.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Swift](<https://devfeed.tech/topics/swift.md>), [iOS](<https://devfeed.tech/topics/ios.md>), [reactive](<https://devfeed.tech/topics/reactive.md>), [Code](<https://devfeed.tech/topics/code.md>)

Tags: [asynchronous](<https://devfeed.tech/tags/asynchronous.md>), [coding](<https://devfeed.tech/tags/coding.md>), [community](<https://devfeed.tech/tags/community.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [development](<https://devfeed.tech/tags/development.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [flow](<https://devfeed.tech/tags/flow.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [interop](<https://devfeed.tech/tags/interop.md>), [ios](<https://devfeed.tech/tags/ios.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-coroutines](<https://devfeed.tech/tags/kotlin-coroutines.md>), [kotlinmultiplatform](<https://devfeed.tech/tags/kotlinmultiplatform.md>), [memory-leaks](<https://devfeed.tech/tags/memory-leaks.md>), [reactive](<https://devfeed.tech/tags/reactive.md>), [reactive-streams](<https://devfeed.tech/tags/reactive-streams.md>), [software](<https://devfeed.tech/tags/software.md>), [suspend](<https://devfeed.tech/tags/suspend.md>), [swift](<https://devfeed.tech/tags/swift.md>)

### AI overview

This tutorial explains interoperability between Kotlin coroutines in shared code and RxSwift on iOS. It describes coroutine limitations on Kotlin/Native, including single-threaded release use and experimental multithreading risks, and discusses Swift and Objective-C interop constraints. Example repository code demonstrates single-event and stream operations, success and error cases, and cancellation.

### Source excerpt

A recent client engagement involved interop between Kotlin coroutines in shared code, and RxSwift on the iOS side. We did some work to ensure that this could be done in a way that is type-safe and thread-safe. Whether or not you use RxSwift, hopefully this can provide some useful patterns for interop code. Coroutines are a Kotlin language feature that allows asynchronous code to be written in a way that looks like synchronous code, avoiding the nesting that often comes with callback-based APIs. They're available on all Kotlin platforms, but have some limitations on the native side. The release version of native coroutines is limited to single-threaded use-cases, though there are experimental releases available that are multithreaded with some risk of memory leaks. But while they're a fully-supported language feature of Kotlin, they don't translate to Objective-C and Swift. RxSwift is a Swift implementation of the Reactive Streams specification. It's one way to handle asynchronous code on Swift, and has many operators for combining and transforming event streams. Though some of the names are different, much of the API will feel familiar to Kotlin developers who have experience with RxJava. Since Coroutines will almost always be present in shared code, and RxSwift is a common option on the iOS side, hopefully the motivation to communicate between them is clear. So let's start writing some code. Common Repository We'll work with a dummy repository class that looks like this, defined in src/commonMain class ThingRepository { suspend fun getThing(succeed: Boolean): Thing { delay(100) if (succeed) { return Thing(0) } else { error("oh no!") } } fun getThingStream(count: Int, succeed: Boolean): Flow<Thing> = flow { repeat(count) { delay(100) emit(Thing(it)) } if (!succeed) error("oops!") } } From the outside this looks roughly like a real repository might, but with inputs that let us control the output a bit more directly for demonstration purposes. It gives us the ability

## Multiplatform Settings version 0.6 is out!

DevFeed: [Multiplatform Settings version 0.6 is out!](<https://devfeed.tech/articles/multiplatform-settings-version-0-6-is-out-25000.md>)

Original publisher: [Read original article](<https://dev.to/russhwolf/multiplatform-settings-version-0-6-is-out-2i41>)

Author: Russell Wolf

Published: 2020-04-26T20:03:33Z

Content type: release

Language: en

Sources: [DEV Community 👩💻👨💻: Russell Wolf](<https://devfeed.tech/sources/dev-community-russell-wolf.md>)

Topics: [multiplatform](<https://devfeed.tech/topics/multiplatform.md>), [configuration](<https://devfeed.tech/topics/configuration.md>), [Windows](<https://devfeed.tech/topics/windows.md>), [implementation](<https://devfeed.tech/topics/implementation.md>)

Tags: [coding](<https://devfeed.tech/tags/coding.md>), [community](<https://devfeed.tech/tags/community.md>), [configuration](<https://devfeed.tech/tags/configuration.md>), [development](<https://devfeed.tech/tags/development.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [experimental](<https://devfeed.tech/tags/experimental.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlinmultiplatform](<https://devfeed.tech/tags/kotlinmultiplatform.md>), [multiplatform](<https://devfeed.tech/tags/multiplatform.md>), [news](<https://devfeed.tech/tags/news.md>), [platform](<https://devfeed.tech/tags/platform.md>), [release](<https://devfeed.tech/tags/release.md>), [software](<https://devfeed.tech/tags/software.md>), [thread](<https://devfeed.tech/tags/thread.md>), [threads](<https://devfeed.tech/tags/threads.md>), [windows](<https://devfeed.tech/tags/windows.md>)

### AI overview

Multiplatform Settings 0.6 adds a Windows implementation that stores data in the registry, a no-argument module for common code, size and keys APIs, and improved thread safety for update listeners on Apple platforms. Some listener and Windows functionality remains limited or experimental.

### Source excerpt

Today I've released version 0.6 of Multiplatform Settings! I thought I'd write a few words about what's been added and what's still to come. Windows One major new feature is a Windows implementation which stores data in the registry. For that I'm thankful for the initial contribution from Andrew Mikhaylov, without which I wouldn't have known how any of the Windows APIs work. It currently doesn't implement the listener APIs in ObservableSettings, but it should be possible to get something working in the future, using something like RegNotifyChangeKeyValue. Contributions welcome. If you do native Windows work, let me know if it meets your needs. no-arg Another new feature is a new module called multiplatform-settings-no-arg. This is in response to a longstanding friction I've heard of from some users, where configuration can seem too complicated. I've generally focused the design of Multiplatform Settings around platform interop, with the expectation that you probably have some existing key-value storage that you want to use from both your shared and platform-specific code. But if that doesn't matter for your use-case, needing to configure things separately from each platform can be frustrating. So the no-arg module lets you call Settings() from common code. Note that this is not currently implemented on Windows, but it is available for other existing platforms. More details in the readme keys and size APIs A minor update is the addition of size and keys APIs, which have been a longstanding to-do item of mine. I held off for a while because they behave unintuitively on Apple platforms, where after a clear() call some keys are still present. However, after realizing that this might already be confusing for the hasKey() API that already exists, I decided that it wasn't a reason to keep them out of the library. Listener updates Finally, this release brings better thread-safety for update listeners on Apple platforms. This is something I've been wanting to get back and im

## Kotlin 1.3.70: Reactions to Incremental Improvements and Multiplatform Compatibility

DevFeed: [Kotlin 1.3.70: Reactions to Incremental Improvements and Multiplatform Compatibility](<https://devfeed.tech/articles/kotlin-1-3-70-reactions-25002.md>)

Original publisher: [Read original article](<https://dev.to/touchlab/kotlin-1-3-70-reactions-3de3>)

Author: Russell Wolf

Published: 2020-03-05T18:11:44Z

Content type: opinion

Language: en

Sources: [DEV Community 👩💻👨💻: Russell Wolf](<https://devfeed.tech/sources/dev-community-russell-wolf.md>)

Topics: [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [multiplatform](<https://devfeed.tech/topics/multiplatform.md>), [Development](<https://devfeed.tech/topics/development.md>), [Library](<https://devfeed.tech/topics/library.md>), [Data structures](<https://devfeed.tech/topics/data-structures.md>), [Gradle](<https://devfeed.tech/topics/gradle.md>), [FIRST](<https://devfeed.tech/topics/first.md>), [Template](<https://devfeed.tech/topics/template.md>)

Tags: [coding](<https://devfeed.tech/tags/coding.md>), [community](<https://devfeed.tech/tags/community.md>), [dependencies](<https://devfeed.tech/tags/dependencies.md>), [development](<https://devfeed.tech/tags/development.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [experimental](<https://devfeed.tech/tags/experimental.md>), [gradle](<https://devfeed.tech/tags/gradle.md>), [improvements](<https://devfeed.tech/tags/improvements.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [incremental](<https://devfeed.tech/tags/incremental.md>), [jetbrains](<https://devfeed.tech/tags/jetbrains.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-native](<https://devfeed.tech/tags/kotlin-native.md>), [kotlinmultiplatform](<https://devfeed.tech/tags/kotlinmultiplatform.md>), [multiplatform](<https://devfeed.tech/tags/multiplatform.md>), [news](<https://devfeed.tech/tags/news.md>), [quality](<https://devfeed.tech/tags/quality.md>), [release](<https://devfeed.tech/tags/release.md>), [software](<https://devfeed.tech/tags/software.md>)

### AI overview

A commentary on Kotlin 1.3.70, focusing on incremental quality-of-life improvements, renamed opt-in annotations, and new common implementations of data structures. It also cautions Kotlin/Native Multiplatform users that binaries are incompatible across versions and recommends waiting for compatible library dependencies before updating.

### Source excerpt

Kotlin 1.3.70 is here! As the release blog post says, there's not much in the way of major landmark new features, but lots of incremental improvements and some interesting little quality-of-life stuff which I'm excited about. It's the first new language version since KotlinConf so it's cool to see some of the things JetBrains has been working on since then, even if a lot of the big-ticket stuff won't come until 1.4. Before we jump in, a quick reminder for Multiplatform users: Since Kotlin/Native is still in Beta, binaries are not compatible across versions. This means that you shouldn't update your Multiplatform projects until all of your library dependencies have Kotlin 1.3.70-compatible versions. If you're a KaMPKit user, you can follow this issue to see when the libraries we use in that template are ready. Here's a couple of items in the blog post I thought were noteworthy. Renaming of experimental annotations I've been using @Experimental and @UseExperimental for over a year now in Multiplatform Settings, and find it to be a really nice way for libraries to mark more volatile APIs. Simply create an annotation class MyExperimentalApi and annotate it with @Experimental, and then consumers of anything marked @MyExperimentalApi will have to explicitly opt-in to their dependence on experimental behavior. But I've also noticed some usage in the wild (including in JetBrains' own libraries) where it was more about marking internal APIs they didn't want other people depending on, rather than just APIs that might be unstable. So I'm not surprised that they're renaming these to @RequiresOptIn and @OptIn to broaden the usage. A side note here since I've seen people miss this: A @RequiresOptIn annotation deliberately leaks to callers so that they're forced to opt-in as well. If you don't want to do that (for instance, because the experimental usage is just an internal implementation detail), you should use @OptIn(MyExperimentalApi::class) instead so you only need to annotate