# YAZIO Engineering - Medium

The official Yazio publication on Medium. We write about technologies that excite us. Also: we are hiring! Join us on https://jobs.yazio.com - Medium

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

## A Local-to-Backend Workflow for Iterating on AI Features in Kotlin Multiplatform Apps

DevFeed: [A Local-to-Backend Workflow for Iterating on AI Features in Kotlin Multiplatform Apps](<https://devfeed.tech/articles/building-ai-features-isn-t-scary-24741.md>)

Original publisher: [Read original article](<https://medium.com/yazio-engineering/building-ai-features-isnt-scary-92817564e364?source=rss----65bd178b00af---4>)

Author: Paul Woitaschek

Published: 2026-07-17T11:49:09Z

Content type: tutorial

Language: en

Sources: [YAZIO Engineering - Medium](<https://devfeed.tech/sources/yazio-engineering-medium.md>)

Topics: [Artificial Intelligence](<https://devfeed.tech/topics/ai.md>), [Kotlin Multiplatform](<https://devfeed.tech/topics/kotlin-multiplatform.md>), [LLMs](<https://devfeed.tech/topics/llms.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Mobile](<https://devfeed.tech/topics/mobile.md>)

Tags: [ai](<https://devfeed.tech/tags/ai.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-multiplatform](<https://devfeed.tech/tags/kotlin-multiplatform.md>), [llm](<https://devfeed.tech/tags/llm.md>), [llms](<https://devfeed.tech/tags/llms.md>), [mobile](<https://devfeed.tech/tags/mobile.md>), [mobile-app-development](<https://devfeed.tech/tags/mobile-app-development.md>)

### AI overview

The article presents a workflow for building AI features in a Kotlin Multiplatform mobile app: define an app interface, implement and iterate on the prompt locally with Koog, then move the completed logic to a backend. It uses a voice-based nutrition-tracking example that converts natural-language input into typed proposed actions.

### Source excerpt

TLDR: Define the interface in the app, iterate locally with Koog, move the logic to the backend when it's done. AI features have a weird reputation among mobile developers. The model sits behind an API, the prompt lives on a server someone else owns, and every change means a ticket, a review, a deploy. So the whole topic feels like backend territory. But an AI feature is just a feature. Text in, structured data out, some logic in between. The only unusual part: the core of that logic is a prompt. And prompts are not designed, they are iterated. You try an input, look at the output, adjust, try again. Dozens of times. So the real problem is not building the feature. It's making that loop fast. The pattern I would like to show: define an interface in the app, build the real UI against it, implement it locally with Koog, iterate until the output is solid, then move the implementation to the backend. In Kotlin that last step is mostly copy paste. The example: track everything in one sentence We build Yazio, a nutrition tracking app, as Kotlin Multiplatform: one shared codebase for iOS and Android. That matters here, because everything below is written once and runs on both platforms. Tracking today is many small interactions: search a food, pick a portion, add water, log a workout. Now imagine the user just says what happened: "I had two scrambled eggs and a coffee for breakfast, drank half a liter of water, went for a 30 minute run, and for lunch I ate the same as yesterday."Users can track using voice The app answers with a list of proposed actions. The user deletes the wrong ones, speaks again to add what's missing, and confirms everything at once. Speech to text is solved on both platforms, so from our side the input is just a string. Messy natural language in, exact typed data out. That's what LLMs are good at. It's also the kind of logic you won't get right on the first try. The constraint: the key can't live in the app You can't ship an OpenAI or Anthropic API ke

## Configurable Features using Kotlin Multiplatform

DevFeed: [Configurable Features using Kotlin Multiplatform](<https://devfeed.tech/articles/configurable-features-using-kotlin-multiplatform-24742.md>)

Original publisher: [Read original article](<https://medium.com/yazio-engineering/configurable-features-using-kotlin-multiplatform-12e7c1c57221?source=rss----65bd178b00af---4>)

Author: Artem Zasypalov

Published: 2023-09-01T06:55:38Z

Content type: tutorial

Language: en

Sources: [YAZIO Engineering - Medium](<https://devfeed.tech/sources/yazio-engineering-medium.md>)

Topics: [Kotlin Multiplatform](<https://devfeed.tech/topics/kotlin-multiplatform.md>), [multiplatform](<https://devfeed.tech/topics/multiplatform.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [configuration](<https://devfeed.tech/topics/configuration.md>), [Compose](<https://devfeed.tech/topics/compose.md>), [business logic](<https://devfeed.tech/topics/business-logic.md>), [Mobile](<https://devfeed.tech/topics/mobile.md>), [client library](<https://devfeed.tech/topics/client-library.md>)

Tags: [business-logic](<https://devfeed.tech/tags/business-logic.md>), [compose](<https://devfeed.tech/tags/compose.md>), [configuration](<https://devfeed.tech/tags/configuration.md>), [development](<https://devfeed.tech/tags/development.md>), [feature-engineering](<https://devfeed.tech/tags/feature-engineering.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-multiplatform](<https://devfeed.tech/tags/kotlin-multiplatform.md>), [library](<https://devfeed.tech/tags/library.md>), [mobile](<https://devfeed.tech/tags/mobile.md>), [mobile-app-development](<https://devfeed.tech/tags/mobile-app-development.md>), [multiplatform](<https://devfeed.tech/tags/multiplatform.md>), [product-development](<https://devfeed.tech/tags/product-development.md>), [software-development](<https://devfeed.tech/tags/software-development.md>)

### AI overview

YAZIO describes using Kotlin Multiplatform to make its onboarding feature configurable. A shared module provides configuration structures and validation for both the mobile app and a Compose Desktop Flow Configurator, allowing product teams to construct and experiment with screen flows without code changes for existing screen types.

### Source excerpt

At YAZIO we love working efficiently. All business logic of our app's new features is written using Kotlin Multiplatform, and we share its code up to the ViewModels. This approach reduces engineering effort, increases stability, and conserves resources. We are always on the lookout for the next step. Some screens and even entire features require swift reactions in changing situations to provide the highest level of experience to our users. The first candidate was Onboarding. Our creative Product Team strives for excellence in first user impressions, meaning that changes in this part of the app occur more frequently than in others. That's why our Development department decided to make this feature not just flexible for content changes, but fully configurable. This means that engineering effort will be reduced to zero for changes that involve only existing Screen Types. Here comes our first term. A Screen Type is a combination of layout and business logic used for the screen in a Flow. And a Flow is a sequence of screens presented to a user in the feature. Our goal was to provide the Product team with a way to construct Flows and use them in the app without code changes. We took advantage of Kotlin Multiplatform again. First, we decided to have a single source of truth for both the app and the Flow Configurator. Configuration data structures and their validations are in a separate multiplatform module. This module is shared between our KMM client library with business logic and the Compose Desktop Flow Configurator app. In the Configurator, we can use our Screen Types to create screen instances and connect them to construct a Flow, create branching to cover all user's questions and concerns, and experiment with content and screen sequences. The saved configuration is then exported and used in the YAZIO mobile app. By delegating responsibility for screen sequences and content, we didn't neglect the safety of our solution. Each flow undergoes a series of validations to

## Why we decided on Kotlin in our Data Engineering architecture

DevFeed: [Why we decided on Kotlin in our Data Engineering architecture](<https://devfeed.tech/articles/why-we-decided-on-kotlin-in-our-data-engineering-architecture-24748.md>)

Original publisher: [Read original article](<https://medium.com/yazio-engineering/why-we-decided-on-kotlin-in-our-data-engineering-architecture-36adddb349cc?source=rss----65bd178b00af---4>)

Author: Dominik Liebler

Published: 2023-03-13T10:27:51Z

Content type: opinion

Language: en

Sources: [YAZIO Engineering - Medium](<https://devfeed.tech/sources/yazio-engineering-medium.md>)

Topics: [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [data-engineering](<https://devfeed.tech/topics/data-engineering.md>), [Kotlin Multiplatform](<https://devfeed.tech/topics/kotlin-multiplatform.md>), [Architecture & Design](<https://devfeed.tech/topics/architecture-design.md>), [Back end](<https://devfeed.tech/topics/backend.md>), [Python](<https://devfeed.tech/topics/python.md>)

Tags: [analytics](<https://devfeed.tech/tags/analytics.md>), [data-engineering](<https://devfeed.tech/tags/data-engineering.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-multiplatform](<https://devfeed.tech/tags/kotlin-multiplatform.md>), [legacy](<https://devfeed.tech/tags/legacy.md>), [maintenance](<https://devfeed.tech/tags/maintenance.md>), [mobile](<https://devfeed.tech/tags/mobile.md>), [python](<https://devfeed.tech/tags/python.md>), [scalability](<https://devfeed.tech/tags/scalability.md>), [software-architecture](<https://devfeed.tech/tags/software-architecture.md>)

### AI overview

The article explains why YAZIO chose Kotlin for its data engineering architecture. It describes dissatisfaction with Python's runtime type checking and recurring basic bugs, then outlines Kotlin's stability, consistency, JVM library ecosystem, Kotlin Multiplatform code sharing, backend experience, and opportunities for knowledge sharing with mobile developers.

### Source excerpt

Choosing or changing a software architecture is not an easy task -- it requires careful consideration of many factors. The decision can have long-lasting effects on the development process, maintenance, and scalability of the system but also on developer happiness and employer churn rate -- nobody likes working with bad legacy code or fixing architectures not scaling well to the needs of an organisation. Photo by 30daysreplay on Unsplash Turn back time to 2021 and you'd see some basic Kotlin code, a pile of Python, and some SQL as well as a lot of YAML for Kubernetes resources in our tech stack. At this point in time the team already had a lot of experience in building software in general and data systems like ETLs in particular but we weren't very happy about the current process and most of all with Python. Although it allowed us to quickly ingest new data from HTTP APIs, we often experienced bugs in our software that were very basic: an AttributeError here, an edge case resulting in a KeyError there -- typical things that can be prevented at compile time in another language. What about a typed language then? We tried annotating our code with type hints using the typing package, but they weren't enforced by the interpreter at runtime anyway and can only really be helpful if PyPi packages also provide typings. Photo by Samuel Schroth on Unsplash As mentioned earlier we already had some Kotlin code running in production due to the fact that we share code with our mobile clients for iOS as well as Android (using Kotlin Multiplatform) and we were very pleased with it. Also as most of the team already had prior experience running Kotlin backend services in production, we decided to go all-in on Kotlin (where possible™). These are the reasons why we think it's a good idea to this day: stability and consistency ability to use the vast amount of libraries for the JVM being able to share code (for event tracking) using Kotlin Multiplatform previous positive experience running

## Speeding up Kotlin Multiplatform

DevFeed: [Speeding up Kotlin Multiplatform](<https://devfeed.tech/articles/speeding-up-kotlin-multiplatform-24747.md>)

Original publisher: [Read original article](<https://medium.com/yazio-engineering/speeding-up-kotlin-multiplatform-61ebf8dae560?source=rss----65bd178b00af---4>)

Author: Paul Woitaschek

Published: 2022-05-18T09:11:24Z

Content type: tutorial

Language: en

Sources: [YAZIO Engineering - Medium](<https://devfeed.tech/sources/yazio-engineering-medium.md>)

Topics: [Kotlin Multiplatform](<https://devfeed.tech/topics/kotlin-multiplatform.md>), [build times](<https://devfeed.tech/topics/build-times.md>), [Gradle](<https://devfeed.tech/topics/gradle.md>), [ide](<https://devfeed.tech/topics/ide.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [iOS](<https://devfeed.tech/topics/ios.md>), [Android](<https://devfeed.tech/topics/android.md>), [watchOS](<https://devfeed.tech/topics/watchos.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-studio](<https://devfeed.tech/tags/android-studio.md>), [build-times](<https://devfeed.tech/tags/build-times.md>), [gradle](<https://devfeed.tech/tags/gradle.md>), [ide](<https://devfeed.tech/tags/ide.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-native](<https://devfeed.tech/tags/kotlin-native.md>), [watchos](<https://devfeed.tech/tags/watchos.md>)

### AI overview

The article describes YAZIO's use of Kotlin Multiplatform to share business logic between Android and iOS while maintaining many Gradle modules. It explains that selectively removing Apple targets during common development can reduce Gradle Sync and IDE indexing time, and that this also enables Gradle Configuration Cache in the described setup.

### Source excerpt

At YAZIO we are heavily investing into Kotlin Multiplatform and use Kotlin to share all business logic between the iOS and the Android App. Naturally this also leads to a lot of code. Since we modularize our software properly to achieve encapsulation and fast incremental build times, it also means a lot of Gradle modules. 70 modules and counting, to be more precise. And for Kotlin Multiplatform, a lot of Gradle modules means a very long Gradle Sync and IDE indexing time. We tried to mitigate some of that by switching to the latest Macbook Pros, which helped quite a bit. But with all the targets we have (1x Android, 3 x iOS, 4 x watchOS), it still takes 6 minutes for Gradle to sync after adding a new Gradle module. This is a very long time, and worse: It encourages developers to not change any build logic at all and leads to them not adding any more modules. Is moving these files into their own module really worth the six-minute wait?Selectively removing targets The idea here is simple: Fewer targets -- less sync time. We rarely need to touch the platform-specific source sets anyway and 99% of the time, we are developing solely in commonMain . This means that while developing, we can just remove the Apple targets. And it turns out: Apple targets have the most effect on sync times. This is due to the Commonizer, large native distributions and a complicated mechanism that allows you to see what's in your classpath from within the IDE. This is pretty simple to implement. First, add a new property to your gradle.properties file: https://medium.com/media/389dc8cfc03487a54eaeb6f2c62a81f9/href Now, in your build.gradle.kts file(s), simply check for that property before creating the native targets. https://medium.com/media/330ad55c6d767fbd4bfcb96822dc4639/href Et voilà -- it's not blazingly fast, but at least we can work with it. Bonus: Configuration Cache 🎉 The other big benefit that we can now make use of is Gradles Configuration Cache. With the iOS targets, Kotlin Multiplat

## Integrating Confluent Schema Registry with Apache Spark applications

DevFeed: [Integrating Confluent Schema Registry with Apache Spark applications](<https://devfeed.tech/articles/integrating-confluent-schema-registry-with-apache-spark-applications-24745.md>)

Original publisher: [Read original article](<https://medium.com/yazio-engineering/integrating-confluent-schema-registry-with-apache-spark-applications-d3426e33bc51?source=rss----65bd178b00af---4>)

Author: Dominik Liebler

Published: 2022-01-24T08:04:19Z

Content type: tutorial

Language: en

Sources: [YAZIO Engineering - Medium](<https://devfeed.tech/sources/yazio-engineering-medium.md>)

Topics: [Kafka](<https://devfeed.tech/topics/kafka.md>), [Apache Spark](<https://devfeed.tech/topics/spark.md>), [Streaming](<https://devfeed.tech/topics/streaming.md>), [data lake](<https://devfeed.tech/topics/data-lake.md>), [parquet](<https://devfeed.tech/topics/parquet.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Kubernetes](<https://devfeed.tech/topics/kubernetes.md>), [ceph](<https://devfeed.tech/topics/ceph.md>), [JSON Schema](<https://devfeed.tech/topics/json-schema.md>)

Tags: [apache-spark](<https://devfeed.tech/tags/apache-spark.md>), [backpressure](<https://devfeed.tech/tags/backpressure.md>), [ceph](<https://devfeed.tech/tags/ceph.md>), [confluent](<https://devfeed.tech/tags/confluent.md>), [data-engineering](<https://devfeed.tech/tags/data-engineering.md>), [data-lake](<https://devfeed.tech/tags/data-lake.md>), [data-pipeline](<https://devfeed.tech/tags/data-pipeline.md>), [json](<https://devfeed.tech/tags/json.md>), [kafka](<https://devfeed.tech/tags/kafka.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kubernetes](<https://devfeed.tech/tags/kubernetes.md>), [parquet](<https://devfeed.tech/tags/parquet.md>), [payload](<https://devfeed.tech/tags/payload.md>), [pipelines](<https://devfeed.tech/tags/pipelines.md>), [schema](<https://devfeed.tech/tags/schema.md>), [schemaregistry](<https://devfeed.tech/tags/schemaregistry.md>), [serialization](<https://devfeed.tech/tags/serialization.md>), [spark](<https://devfeed.tech/tags/spark.md>), [streaming](<https://devfeed.tech/tags/streaming.md>)

### AI overview

This engineering article explains YAZIO's data pipeline from mobile and web applications through Kafka and Spark Structured Streaming into a Ceph-based data lake. It discusses why schemas matter and describes replacing JSON with Apache Avro and Confluent Schema Registry to reduce message size while keeping schema information externally stored and cached.

### Source excerpt

At YAZIO, we believe in making decisions backed by data to help people live healthier lives through better nutrition. For each new and existing feature we want to evaluate how well it performs and how our users interact with it. In order to do so, we need a lot of data and we need to handle backpressure in our systems. To cope with that we use a Kafka cluster managed by Strimzi operators running in Kubernetes. The data itself is being ingested from our mobile and web apps via HTTP or TCP endpoints serialized into JSON and stored in Kafka by a small application written in Kotlin/JVM. Overview of our data pipeline architecture At the other end of the pipeline, different Spark Structured Streaming applications (also written in Kotlin) dump this information into our data lake residing in a Ceph bucket. They read data from Kafka, deserialize it, transform some of the fields and write Parquet files into the data lake using a new schema. Why schemas? Schemas play an important role in data pipelines because they give meaning and context to data. In a world without schemas we would still do random interpretations about the context and meaning of data every now and then when using it. As you might have guessed already this would lead to a lot of bugs and misunderstandings. Photo by EJ Strat https://unsplash.com/photos/VjWi56AWQ9k Similar to a legal contract that binds you to certain limits, a schema binds the data to certain limits and meaning which narrow down the need of interpretation. Choice of serialization formats At the time of writing, Confluent Schema Registry supports these three serialization formats: Apache Avro Protocol Buffers (protobuf) JSON Schema From those choices, only two really provide more than just validation of the data that is ingested and transmitted through our data pipelines. Avro and Protobuf also allow us to shrink the sizes of our topics because only the payload is contained in a message, while the repeating schema will not be stored. In the cas

## Data Binding: BindingAdapter

DevFeed: [Data Binding: BindingAdapter](<https://devfeed.tech/articles/data-binding-bindingadapter-24743.md>)

Original publisher: [Read original article](<https://medium.com/yazio-engineering/data-binding-bindingadapter-7d0824b1efff?source=rss----65bd178b00af---4>)

Author: Paul Woitaschek

Published: 2021-11-19T08:06:16Z

Content type: tutorial

Language: en

Sources: [YAZIO Engineering - Medium](<https://devfeed.tech/sources/yazio-engineering-medium.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [recyclerview](<https://devfeed.tech/topics/recyclerview.md>), [XML](<https://devfeed.tech/topics/xml.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [RxJava](<https://devfeed.tech/topics/rxjava.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-app-development](<https://devfeed.tech/tags/android-app-development.md>), [code](<https://devfeed.tech/tags/code.md>), [how-to](<https://devfeed.tech/tags/how-to.md>), [recyclerview](<https://devfeed.tech/tags/recyclerview.md>), [xml](<https://devfeed.tech/tags/xml.md>)

### AI overview

This tutorial explains how to use Android Data Binding and a BindingAdapter to apply strike-through formatting to a TextView based on a view model. The author reports reducing RecyclerView ViewHolder boilerplate by about 50%.

### Source excerpt

For a long time I did not investigate further into https://developer.android.com/tools/data-binding/guide.html but recently it just got my attention. Just like Kotlin or RxJava this was something that was constantly trying to get my attention so I decided to give it a try and to see how it works while writing my new notes app. And I must say: I'm impressed. I applied it on the ViewHolder of my RecyclerView and reduced the boilerplate code by about 50%. But there were some issues. Issues The biggest I had was manipulating the view. The grey text could be simply archieved by setting the view enabled based on the view model: android:enabled="@{!model.done()}" As the text was set to @color/abc_primary_text_material_light from the support library this automatically works. But how to set the strike through? I did not wanted to call all these `findViewById` any more as that would defeat the purpose of DataBinding. Solution It turned out there was a simple solution, called BindingAdapter> https://developer.android.com/reference/android/databinding/BindingAdapter.html Basically you just define a static method and annotate it as a binding adapter. So for strikeThrough it is: @BindingAdapter("text:strike") public static void setStrike(TextView text, boolean strike) { if (strike) { text.setPaintFlags(text.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); } else { text.setPaintFlags(text.getPaintFlags() & ~Paint.STRIKE_THRU_TEXT_FLAG); } } So now you can set it just as a regular xml attribute: android:strike="@{model.done()}" Data Binding: BindingAdapter was originally published in Yazio Engineering on Medium, where people are continuing the conversation by highlighting and responding to this story.

## Kotlin Native -- Using swift, not Objective-C

DevFeed: [Kotlin Native -- Using swift, not Objective-C](<https://devfeed.tech/articles/kotlin-native-using-swift-not-objective-c-24746.md>)

Original publisher: [Read original article](<https://medium.com/yazio-engineering/kotlin-native-using-swift-not-objective-c-d7742c040539?source=rss----65bd178b00af---4>)

Author: Paul Woitaschek

Published: 2021-11-19T08:00:42Z

Content type: tutorial

Language: en

Sources: [YAZIO Engineering - Medium](<https://devfeed.tech/sources/yazio-engineering-medium.md>)

Topics: [kotlin-native](<https://devfeed.tech/topics/kotlin-native.md>), [Code generation](<https://devfeed.tech/topics/code-generation.md>), [Swift](<https://devfeed.tech/topics/swift.md>), [Objective-C](<https://devfeed.tech/topics/objective-c.md>), [Compiler](<https://devfeed.tech/topics/compiler.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [code-generation](<https://devfeed.tech/tags/code-generation.md>), [compiler](<https://devfeed.tech/tags/compiler.md>), [interop](<https://devfeed.tech/tags/interop.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-multiplatform](<https://devfeed.tech/tags/kotlin-multiplatform.md>), [kotlin-native](<https://devfeed.tech/tags/kotlin-native.md>), [ksp](<https://devfeed.tech/tags/ksp.md>), [library](<https://devfeed.tech/tags/library.md>), [objective-c](<https://devfeed.tech/tags/objective-c.md>), [swift](<https://devfeed.tech/tags/swift.md>)

### AI overview

This tutorial explains how YAZIO uses Kotlin Native for shared business logic while providing a Swift-native iOS API. It describes the limitations of Kotlin-to-Objective-C interoperability and shows how KSP and SwiftPoet can generate Swift mappings for Kotlin types such as enums and sealed classes.

### Source excerpt

Kotlin Native -- Using Swift, not Objective-C At YAZIO we use Kotlin Native Extensively. The business logic of all new app features is exclusively written in Kotlin. In its core, every screen has one ViewModel which exposes a single Flow<ViewState> that the Android App and the iOS can consume to render the state. On Android, rendering the view state is no burden because it's the language we use in the Android App anyways. However this is different for iOS. While Swift does interop with Objective-C, the public API as seen from Swift is bad. A simple data class is exported as a regular class. The properties are not native Swift types. What should be a Bool becomes a KotlinBoolean. What should be come a Double becomes a KotlinDouble. But what we want is most of the times a struct with Swift types. These are the lesser evils, the greater ones are enums and sealed classes. In Objective-C, they both become regular classes. And therefore lose all the advantages they have when used from Swift. But what we want is a Swift enum. To overcome these restrictions for quite some time our iOS team has created mappings. There is a whole target, dedicated to mapping the Objective-C classes to Swift. Basically when developing a new feature, the whole public API is manually mapped to Swift. This is good because the result is a clean Swift-native API. But that's bad because it's extreme boilerplate and a real productivity killer. What if we could directly generate these mappings and use code generation to handle that for us? Turns out: There are two tools available that make it possible. The first one is KSP. It is basically a library that lets you implement a Kotlin compiler plugin and it gives you hooks to analyze the Kotlin Syntax Tree and generate code based on it. The second one is SwiftPoet. SwiftPoet is a library you can use to generate Swift code from Kotlin, similar to what KotlinPoet and JavaPoet do. Okay, let's get our handy dirty. For the basic setup, just follow the tutorial

## Wildcard ProGuard/R8 Rule Can Remove Android Synchronization Calls

DevFeed: [Wildcard ProGuard/R8 Rule Can Remove Android Synchronization Calls](<https://devfeed.tech/articles/how-to-break-your-android-app-with-proguard-r8-24744.md>)

Original publisher: [Read original article](<https://medium.com/yazio-engineering/how-to-break-your-android-app-with-proguard-r8-6566bc387b63?source=rss----65bd178b00af---4>)

Author: Paul Woitaschek

Published: 2021-03-02T15:19:22Z

Content type: tutorial

Language: en

Sources: [YAZIO Engineering - Medium](<https://devfeed.tech/sources/yazio-engineering-medium.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [R8](<https://devfeed.tech/topics/r8.md>), [Android Gradle Plugin](<https://devfeed.tech/topics/android-gradle-plugin.md>), [configuration](<https://devfeed.tech/topics/configuration.md>), [Testing](<https://devfeed.tech/topics/testing.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-app-development](<https://devfeed.tech/tags/android-app-development.md>), [android-gradle-plugin](<https://devfeed.tech/tags/android-gradle-plugin.md>), [androiddev](<https://devfeed.tech/tags/androiddev.md>), [configuration](<https://devfeed.tech/tags/configuration.md>), [instrumentation](<https://devfeed.tech/tags/instrumentation.md>), [proguard](<https://devfeed.tech/tags/proguard.md>), [r8](<https://devfeed.tech/tags/r8.md>), [testing](<https://devfeed.tech/tags/testing.md>)

### AI overview

An Android debugging article explains how instrumentation tests and a network call began hanging after an Android Gradle Plugin update. The cause was a ProGuard/R8 `-assumenosideeffects` rule using a wildcard for `android.util.Log`, which also matched superclass methods including synchronization methods on `Object`.

### Source excerpt

I recently updated the android gradle plugin to 4.0.0. While developing, everything went smoothly and at some point I was ready to cut a release. The very last manual testing of the release app bundle was also fine so no Proguard / R8 issues on the first sight either. Then I thought: Let me check the CI results again. Everything was fine, but: The instrumentation tests. Almost all of them were timing out. After inspecting the logs, they all hang at the end of the on-boarding. Strangely the loading spinner was loading for way longer than the timeout should be. So I tested it on my phone and faced the same results. At that time I had no idea it was caused by updating AGP, so I did a 2 hours long git bisect. Okay, now lets create a minimal self reproducible bug report because I found a huge bug in AGP, everyone should know about immediately. I created a Hello World project that was making a single network call and printed it results into a TextView. Strangely here it did not reproduce. After experimenting with the OkHttp configuration and testing if it was related to some gradle plugin, I finally had the idea that it might be related to R8. So I added my proguard configuration and now the network call hang! Let's locate the issue further. I was step by step removing lines from my proguard configuration until only a single line was left: -assumenosideeffects class android.util.Log { public * ; } Now what is this? How is that even slightly related to anything? It should remove the log spam of some third party libraries we're using. So I was asking Mads Ager. (he works on D8/R8) you have to be very careful with -assumenosideeffects The problem is that in order for -assumenosideeffects to have the effect of actually removing calls, it matches up the class hierarchy. Therefore, this rule says that anything public in android.util.Log and its superclasses has no side-effects. That include the synchronization methods defined on Object. So, please don't use * wildcards in conne