Intro In my previous article, I covered building a design system in SwiftUI that mirrors Jetpack Compose’s MaterialTheme. I mentioned that with this foundation in place, adding dynamic themes would be straightforward. Well, I recently implemented exactly that, and I wanted to share how the design system made this possible with minimal platform-specific code.
Android iOS Why Dynamic Theming? Beyond the standard light and dark modes, I wanted to give users more personality options.Intro While building Tv Maniac, a Kotlin Multiplatform project, I needed consistent styling across Android and iOS. On Android, Jetpack Compose gives us MaterialTheme out of the box. On iOS? We have to build our own. This article walks through the approach I took to create a design system in SwiftUI that mirrors the ergonomics of Compose theming.
If you’d like to see the code, here’s the pull request.
The Problem In Jetpack Compose, accessing design tokens is straightforward:Intro If you’ve built apps that rely on authentication tokens, you’ve likely dealt with the challenge of keeping those tokens fresh. Tokens expire, and if your user opens the app after being away for a while, they might get hit with an unexpected logout. Not a great experience.
Background tasks solve this problem. They allow your app to do work even when it’s not in the foreground—refreshing tokens, syncing data, or fetching updates.In Part 1, I walked through different approaches for handling environment variables in Kotlin Multiplatform projects. Fast forward a couple of years, and I’ve learned quite a bit about what works at scale and what doesn’t. In this article, I’ll share how I evolved my configuration approach in Tv-Maniac and why I eventually moved to a custom BuildConfig plugin.
The Problem with YAML Files The YAML based approach I described in Part 1 worked well initially, but as the project grew, some pain points became apparent:In my previous post, I walked through publishing Gradle plugins to Maven Central. While that worked, the manual process was tedious. Every release meant updating versions, creating tags, running publish commands, and writing release notes. Today, we’re eliminating all that toil by automating the entire release pipeline with GitHub Actions.
What is Continuous Delivery(CI/CD)? Continuous Delivery (CD) is the practice of automating software releases so that code can be deployed to production at any time.Intro If you’ve been following my TvManiac journey, you know I’m a fan of keeping things modular and reusable. Recently, I hit a point where my Gradle build logic grew into a collection of 10 specialized plugins. They were working great as a local includeBuild, but I started thinking — what if I could publish these plugins and use them like any other dependency?
This article walks through my journey of transforming local Gradle plugins into published Maven Central artifacts.Testing in projects can quickly become complex, especially when managing dependencies across different platforms. In this post, I’ll share my journey of refactoring TvManiac’s test infrastructure from manually creating fake presenter factories to using proper dependency injection with kotlin-inject-anvil to create a test component that wires the fixtures for us.
The complete implementation is available in the TvManiac.
Let’s jump right in.
The Problem: Manual Test Doubles Previously, our tests looked like this.Intro In the previous article Internationalization (I18n) in Kotlin Multiplatform, we explored how to modularize the :i18n module using Moko Resources for handling string resources across platforms.
In this follow-up article, we’ll dive deeper into:
Implement dynamic language switching without app restarts Create a testable localization architecture Handle platform-specific locale implementations The Settings Screen demonstrates our new approach to localization, enabling dynamic language switching without app restarts on both Android and iOS.Welcome back! In this article, we’ll explore my approach to implementing Internationalization (I18n) in a Kotlin Multiplatform project. I’ll share how I’ve structured the solution to enable resource sharing between Android and iOS platforms. While this implementation might be more complex than necessary for some use cases, it demonstrates a modular approach to handling internationalization. Let’s dive in and see how it works.
Internationalization (I18n) Internationalization (I18n) is the process of designing and developing applications that can be adapted to different languages and regions.Intro SQLDelight is a powerful tool for managing database schemas in Kotlin Multiplatform projects. In this blog post, I’ll walk through how I setup SQLDelight migrations for TvManiac.
SQLDelight Migrations SQLDelight migrations allow you to evolve your database schema over time while preserving existing data. Migration files in SQLDelight follow a simple naming convention: <version>.sqm. These files are stored in the same directory as your .sq files, typically under your sqldelight source directory.