





















































MobilePro #185: Code Smarter with Reflection in Swift & Kotlin
Hi ,
Welcome to the 190th edition of MobilePro!
At some point, every developer runs into the same problem: your code needs to adapt, but rewriting everything feels clunky and repetitive. Maybe you’re debugging a stubborn issue, mapping models to JSON for the tenth time, or trying to make your tools smarter without hardcoding every detail. In those moments, you wish your code could just… explain itself.
That’s where reflection comes in. It’s the ability for your code to look in the mirror at runtime—inspecting objects, properties, and types on the fly. While it’s often overlooked, reflection is a powerful way to build more flexible, adaptable, and even elegant solutions.
In this article, we’ll explore how reflection can become a secret weapon for mobile developers working in Swift or Kotlin. You’ll learn how to:
Reflection isn’t just an abstract concept—it’s a practical tool you can apply today to make your development process faster, cleaner, and more future-proof.
All these ideas are inspired by Jon Hoffman’s Mastering Swift 6, a comprehensive guide to building modern, powerful, and efficient applications with Swift. You can grab a copy from Packt or Amazon.
Before we jump in, let's take a quick look at last week's highlights:
Jon Hoffman has over 30 years of experience in the information technology field. Over the years, he has worked in system administration, network administration and security, application development, and architecture. He currently serves as an Enterprise Software Manager for Syntech Systems.
Outside of his professional life, Jon has a wide range of personal interests that keep him both physically and mentally engaged. He enjoys spending quality time with his two children and his fiancée. He also stays active through running, hiking, paddleboarding, yoga, and working out. In addition, Jon has a deep passion for reading and continues to nurture his love for coding.
In software development, reflection gives us the ability to inspect and interact with objects, types, and members at runtime, without knowing their specifics at compile time. While it’s often overlooked, reflection can be a powerful tool when used correctly, offering flexibility and adaptability in situations where static code might otherwise be limiting.
In mobile development, reflection is supported in both iOS and Android environments; however, the APIs differ. This article will focus heavily on Swift’s Mirror API while also showing how similar concepts apply to Android development with both Kotlin and Java.
The simplest way to think about reflection is that it enables code to look at itself. It’s like holding up a mirror (pun intended) to our code at runtime and asking the code:
Reflection can also enable dynamic method invocation, type inspection, and object creation, while not all reflection APIs offer these tools, they can be invaluable in certain development scenarios.
What are some of the benefits of reflection, and how can it assist us? Here is a short list of some benefits of using reflection.
Now let's look at how we could use reflection using the Mirror API with Swift.
Swift's Mirror API is the primary way to perform reflection. A Mirror represents the structure of an instance at runtime, allowing iteration over its properties and metadata.
Here’s an example of inspecting an object:
struct User {
var name: String
var age: Int
}
let user = User(name: "Kai", age: 18)
let mirror = Mirror(reflecting: user)
for child in mirror.children {
if let label = child.label {
print("\(label): \(child.value)")
}
}
This code defines a simple User struct with two stored properties: name (a String) and age (an Int). It then creates an instance of User and uses Swift’s Mirror API to perform reflection, examining the object’s properties at runtime.
The Mirror(reflecting:) method creates a mirror representation of the user instance. The mirror.children sequence contains each stored property as a (label, value) pair. The for loop then iterates through these properties, and for each one, it prints its name (label) and value (value).
This code, essentially, prints the property names and values of user without hardcoding them. If we were to add additional properties to the User strut, it would automatically be printed out or logged without having to change anything. This demonstrates how reflection can be used for dynamic inspection.
Some common use cases of reflection with Swift are:
The Mirror API in Swift allows for read-only properties, which means you can inspect them, but you can’t modify them directly via Mirror. If modifications are needed, you’ll need to combine reflection with dynamic member lookup patterns or protocol-based designs.
Now let’s look at reflection within Android development.
Kotlin provides a reflection API via the kotlin.reflect package. This dynamically allows us to obtain information about classes as well as their names, methods and properties.
Let’s look at an example where we are accessing properties with Kotlin:
import kotlin.reflect.full.memberProperties
data class User(val name: String, val age: Int)
val user = User("Kai", 18)
for (prop in user::class.memberProperties) {
println("${prop.name} = ${prop.getter.call(user)}")
}
We begin by importing kotlin.reflect.full.memberProperties, which provides access to a list of all properties defined in a given class without needing to reference them directly. A User data class is defined with two properties: name and age. An instance is created with name = Kaiand age = 18.
By calling user::class.memberProperties, we obtain a collection of KProperty objects, each representing one property of the User class. We then iterate through these properties with a for loop and print out the following information:
prop.namereturns the property’s name as aString.
prop.getter.call(user) invokes the property’s getter dynamically on the user instance, retrieving its value without knowing the property name at compile time.
When run, the output lists each property and its value and should look similar to this:
age = 18
name = Kai
This reflective approach is useful in scenarios such as serialization, debugging utilities, or building generic frameworks where the code must adapt to varying data class structures automatically.
Reflection is powerful, but it’s not free. Here are some considerations when you are thinking about using reflection:
Use reflection where flexibility outweighs these costs—often in debugging, tooling, and dynamic mapping scenarios rather than core app logic.
For mobile developers, especially those focused on Swift or Android, understanding reflection opens up new possibilities for writing flexible, adaptable, and powerful code. Swift’s Mirror API, and Kotlin’s kotlin.reflect offer ways to peek inside your objects at runtime.
If you want to dive deeper into the latest Swift 6.2 and build powerful, maintainable apps, then Jon Hoffman'sMastering Swift 6is the book for you!