Dev Conversations #15: Pierluigi Cifani

👍 0
Published: October 30, 2025
👍 0

Dev Conversations is a monthly series where Swift Toolkit features members of Swift work groups, content creators, and people who contribute to the Swift community, focused on tooling, developer experience and Server Side Swift.

In these talks, we discuss open source projects, tips for professional growth, and many other valuable insights and perspectives from other developers.

Pierluigi Cifani has been doing iOS development for over a decade, starting back in 2013 with Objective-C. When he first saw a jailbroken iPhone running a terminal, he knew that’s what he wanted to do. He’s been writing iOS apps ever since, and in the last year, he’s been experimenting with Swift on Android — a topic he presented at NSSpain 2025.

Pierluigi started programming in college with Pascal, Java, and C. As soon as he had a chance to work on iOS at his company, he jumped on it. He remembers having headaches trying to understand how UITableView worked under the hood and how to write one. He’s loved iOS development ever since, from Objective-C’s pthreads to Grand Central Dispatch and now Swift.

At his company, they’ve adopted Swift on Android using the Skip toolchain, allowing them to share business logic between iOS and Android while keeping native UIs on both platforms. This approach lets them maintain native iOS apps while making iOS developers more economically viable by enabling code sharing without compromising the iOS experience. Just last week, the Swift Android Workgroup announced the official Swift SDK for Android.

Pierluigi Cifani

In this episode, Pierluigi shares his journey into Swift on Android, discusses the advantages and challenges of this approach, compares it to Kotlin Multiplatform, and explains why he chose Swift over other cross-platform solutions.

You can also find the written interview and the podcast links after the video in case you prefer reading or listening, and the relevant links at the end of this page.

Also available in your favorite podcast player
Apple PodcastsOvercastCastroRSS

Swift Toolkit
Hey Pierluigi, how's it going?

Pierluigi
All good, thanks for having me.

Swift Toolkit
Tell me a little bit about yourself, your first steps into programming, and how you got where you are today.

Pierluigi
I started programming in college. They taught Pascal back then, then some Java and C. But as soon as I saw the iPhone—I remember first seeing a first generation jailbroken iPhone running the terminal—I understood right then that's what I wanted to do.
As soon as I had a chance to work in iOS at the company I was working for—I was doing C and C++—I jumped wagons and started doing iOS. I remember having headaches trying to understand how UITableView worked under the hood and how to write one.
I've loved doing iOS ever since back in Objective-C. You had to match threads with pthreads then, and Grand Central Dispatch was already a huge improvement. I've been writing iOS since 2013. This last year I've been experimenting with Swift on Android, which is what I talked about in Logroño at NSSpain this year.
Swift Toolkit
Right, we'll leave a link to that talk. Let's jump right into cross-platform or hybrid solutions. I'm personally not a fan of these solutions on iOS at least. What are your thoughts on that?

Pierluigi
I don't like them at all. I think they constrain the quality of the product you can ship to your customers. I've been very vocal against them throughout my career—as long as you go there, you're basically stuck with that vendor or technology that won't be updated as fast, and users will feel the difference when they use your product.
I've been lucky enough to always be doing native iOS development and I hope to keep it that way. One reason I'm doing Swift on Android is to be able to keep it that way actually. All cross-platform solutions come with some sort of trade-off, especially on the iOS side where I can immediately feel it as soon as I launch the app. The tooling and everything is just a step backwards.
That's why I've been doing Swift on Android—to make commercial native iOS developers more economically viable.
Swift Toolkit
So if you're not a fan of cross-platform on iOS, why is it different on Android though?

Pierluigi
First thing you need to know is that if your app is using Swift on Android, your iOS app is unaffected by the cross-platform decision. After you ship it to the store, you can download the IPA, open it, and you'll see it's just an iOS app—pure Swift, everything regular. No difference there.
On Android, you can write your core business logic, networking, serialization, keychain handling—all of that in Swift—and just have the UI written in Compose, which will look and feel native on that platform.
Swift Toolkit
But then we can ask the opposite question. Why not KMM on iOS? Why not Kotlin Multiplatform—we could use Kotlin to write the business logic and interface with SwiftUI.

Pierluigi
That's a great question. The answer is personal: because on KMM you have to use Kotlin and not Swift. Kotlin is a fine language, but it's designed to run on top of the JVM, so it has all those constraints baked into the language and there's basically no way around those.
I personally find Kotlin code way less expressive than Swift code can be. If you ask an Android developer what the Kotlin transition was like from Java, they'll basically say "what transition?" There was no transition. Everything was just super fast, super easy.
On the iOS side, the transition from Objective-C to Swift was painful because the language is not built on top of Objective-C. It's not Objective-C 3.0. It's a completely different paradigm, completely different thing. It had a completely different runtime, and that's why it has powerful generics, enums with associated values, value type semantics, and all that good performance that we get.
That's basically the reason why I'm so excited about this advancement in the Swift ecosystem. It's very important for us to keep writing code in Swift because I enjoy it very much. I have open source projects that I started in 2016 and they're running on Android as we speak. That's very nice to see happening.
Swift Toolkit
Let's get into the technical details. Last time I saw KMM, someone on my team showed me it basically translates Kotlin code into Swift code. How does KMM work nowadays?

Pierluigi
KMM—I'm not an expert here—but what it does is that Kotlin is a JVM-based language. It compiles down to that, but it can also compile down to native code, like a binary that can run anywhere that Linux or Unix runs.
When you export your Kotlin Multiplatform framework for it to be consumed on iOS, you need to be very careful because some dependencies aren't available on iOS—which is the same thing that happens with Swift on Android. But as soon as you get that to compile, there's an extra step that generates Swift interface files instead of Objective-C headers.
What KMM does is create a black box, an XCFramework that you can import into your Xcode project and use to call your shared business logic. We tried it in my company maybe in 2021 or 2022, but it ended up being just a proof of concept, Swift had concurrency and Kotlin coroutines were not ready yet if I recall correctly.
Swift Toolkit
Speaking of proof of concept, how was your proof of concept for Swift on Android? What were the first steps, the initial setup? Where did you even begin?

Pierluigi
I had the Skip toolchain—which is a company that vends Swift on Android toolchain—on my radar for a while. They started with transpilation, which basically means translating each line of Swift code to the equivalent Kotlin version. But it felt too complicated or too brittle because you had to translate Swift into Kotlin, so you couldn't use generics, enums, protocols with constraints or associated types.
As soon as they developed a new version that enabled you to use regular Swift and compile that into machine code for Android, I started digging into that and basically started porting the open source Swift packages that power all of our clients' apps.
The process was slow. Just run the tests on the emulator. If they pass, kind of hope for the best. After the two open source projects that power our iOS apps were compiling and running on Android, we started porting one of our client's apps. One of them was heavily modularized, so we were able to just pinpoint the core package of it.
We started with the simplest one. Once that was done and it was compiling and the tests were passing on Android, we couldn't wait to try it out. The first proof of concept was for Naturitas, which is an e-commerce application where we managed to port both the iOS and Android codebase.
Swift Toolkit
Like a feed, some sort of feed?

Pierluigi
The proof of concept was simple. The app has a home screen with banners, products on sale, recommended products, and a list of categories—basically what you expect to see when you launch an e-commerce app. All of those elements are referenced using a deep link. Marketing people use URLs like https://naturitas.es/something as the deep link, which we then convert into a native enum with associated types.
We had two implementations: one in Kotlin for Android and one in Swift for iOS. That has historically been very challenging to keep up to date and keep working as expected on both platforms. Sometimes they make a change, we change it on the iOS codebase, but the Android guy is on vacation or maybe I was on paternity leave and the Android person wasn't.
It was a challenge to keep that simple business logic in sync. It's more complicated than it seems because sometimes for some URLs, you have to call an endpoint to figure out where to go. URL comes in, async URL comes out because we have to resolve the deep link at runtime using a network request. So it looks simple, but it's complex enough to test the networking stack and test Kotlin communication on both directions.
After we did the whole process of packaging up the first open source projects for Android and then the first module for Android, we started hooking it up to the UI. This process was longer than I expected, but then after we had that function that takes a URL and spits out asynchronously a deep link, we were able to hook it up relatively fast on the Android side.
We shipped it to the Play Store and we were very happy because we could delete about a thousand lines of Kotlin code. That's a thousand lines of code that a small company like ours doesn't have to maintain, which has benefits in the long run. We've been iterating ever since—rewriting the authentication layer, the store preference layer which customizes the behavior of the app depending on what country you're in. It's a process that's still ongoing, release by release, where every couple of weeks we ship a version that substitutes one system for the other.
Swift Toolkit
Step by step, I see. But where do you get the toolchain from? How do you even compile a framework whose platform is Android?

Pierluigi
Android has been unofficially kind of supported on Swift for a while. In Package.swift, you can add Android constraints, and in Swift code you can put `#if os(Android)`. That has been there for a while now.
But Skip, which is a company in America, built a toolchain that takes the Swift SDK—the open source Swift SDK, the open source Swift Foundation—and packages it up in a command line tool that you can use to compile and export Swift packages and modules for Android.
That's what I've been using. All my experience using Swift on Android has been basically powered by Skip. They have a great website, a great community around it, and it's a very good product.
Swift Toolkit
We'll leave docs links. And the advantages—you get everything that you have in Swift. What are the limitations? For example, can you use concurrency? Can you use @Observable? Can you use generics, everything?

Pierluigi
If you're writing Swift code in a Swift file without any imports, everything you can write there can be compiled for Android. That means you get concurrency, generics, associated types, enums with associated types, protocols with generic constraints—pretty much everything.
Everything in the standard library. You could also import Foundation and that will import the open source version of Foundation. That comes with networking, localization, and a bunch of goodness from Foundation, which has been the beating heart of Apple's platforms for a while.
When they open sourced it, that's basically the only reason why we're able to do this. Because a lot of our code depends on Foundation—it's very hard to write meaningful code without Foundation. The fact that they open sourced it means that people like the guys from Skip are able to take it, make the necessary changes, and package it up for use on Android.
Foundation on Android has the same sort of limitations it has on Linux. You get slightly different localization, you get a slightly different networking stack—you don't have the same networking stack as you have on iOS. Stuff like background uploads, which is one of the nice URLSession features, isn't available on Android. Not everything is available, but a surprising amount of it is. It's very easy to write meaningful code with what you get from the open source version of Foundation.
Swift Toolkit
Can you write, for example, a view model with @Observable macros? And how do you even access that from the Android side?

Pierluigi
What I've been talking about so far is basic code. But as soon as you go into how do I power Android UIs, you do have to start importing the Observation framework to be able to use the @Observable macro.
This is when Skip comes in. They offer a Swift Package Manager plugin to wrap all your observable objects and make sure they participate in the state management for Compose views on Android. So they have all the important metadata that's necessary for the Android runtime to react to the changes that happen on the Swift layer.
This is a very powerful feature for the Skip toolchain. This is not part of the Swift on Android SDK—this is part of the toolchain that Skip offers as part of their product. Once you do that, you're able to power Compose UIs with observable objects, observable view models that you write for your iOS apps, which means you get to share even more of the code.
The view model and business logic is a big chunk of the code, but if you can also share up to the view model layer, then we're really talking business here. So it's very cool.
Swift Toolkit
Right, so after all the good stuff, they also have their own nuances. What are the biggest challenges and downsides? In the talk you mentioned binary size, you also mentioned some sort of bridging—you have a protocol in Swift and then you can have the implementation in Kotlin and inject back to Swift. What are the main issues here?

Pierluigi
I mentioned in the KMM section that basically KMM gives you a black box that you can integrate into Xcode. This is the opposite version of that—you create a black box that you hand over to the Android team and hope for the best.
They don't get to step into your Swift code while they're debugging on Android Studio, which is a big productivity issue. So you better ship them good code. You have to have good test coverage. You better have good logging so they can at least follow the trace on the Android side.
Binary size, as you mentioned, is a big issue. Even one line of Swift code increases the size of the final Android binary by 50 megabytes. So it's a big chunk, but I don't think that this is a big deal as we might expect. At the end of the day, apps nowadays—every time I update on the app store, I see bank apps that take half a gig, stuff like that.
It is an issue that I hope will be addressed, but it will take some time. If you remember back when Swift launched, even the same thing happened. Even if you add one line of Swift, you added like 15 megabytes to each single app that you download. That was eventually fixed when Swift was ABI stable and was shipped with the OS.
So hopefully something like that can happen in the future if Google and Apple play ball. The main issue with the binary size comes from internationalization because Swift currently bundles its own internationalization stack instead of plugging into the host environment internationalization. That can also be addressed by the two sides—Apple and Google—and the community taking care of it and doing the plumbing to the OS. But again, this is an issue, but I don't think it's a big deal or a deal breaker, especially nowadays that everybody has 256 gigabyte phones.
Swift Toolkit
Especially on Android, which they have slower adoption.

Pierluigi
One of the bigger issues is that you have to bump the minimum API version on the Android side to get Swift on Android running. It's 24 if I'm not mistaken, which made us bump it from I think 18 to 24. This is what got the only weird look we got from our clients when we told them about this. It did raise more eyebrows than the 50 MB thing.
Android is a very different environment than what we're used to on iOS, especially with platform specification. I wouldn't count protocols as a downside, but rather as the superpower that you can share the business logic while having the actual implementation differ on each platform.
You could have some sort of protocol—imagine you wrap StoreKit in a protocol that you implement with StoreKit on iOS and with the equivalent on Android. That will leave you to have the same consistent user experience on both platforms while retaining the same code and writing platform-level code.
We have done this successfully, not with StoreKit, but with CoreBluetooth. We have an app that talks with Bluetooth to a peripheral, and we wrapped CoreBluetooth behind a protocol. That's the only part of the app that we have to write twice—one for Kotlin and one for Swift.
Swift Toolkit
What about code completion from the Kotlin side?

Pierluigi
You get code completion to the extent that Android Studio gives you code completion, which works quite differently from Xcode. You don't get stuff like tokenized inputs on functions, which drives me crazy, honestly. But you don't get that in any Kotlin code.
From the Android Studio side, you will see based on AAR, which is the equivalent of the XCFramework for the Java world. That works as it does for any other closed source AAR that you import using Maven or Gradle.
Another downside that I forgot to mention earlier is that even though you can use the whole richness of Swift to write your code, that doesn't mean that Kotlin can access all of it. Stuff like a class that has an async initializer—that does not exist in Kotlin. So even if you can keep your initializer, you have to instruct Skip to not generate Kotlin bindings for that method, and then you have to create a secondary method that can be translated into Kotlin for it to be accessed.
If you have an API that's very generic-based that relies heavily on generics or something fancy like that, it cannot be expressed in Kotlin. So what you have to do is actually wrap it and call that generic API for the Android codebase. The Android codebase will get the same runtime performance, but will get a slightly different API. Again, not a big deal, not great, not terrible.
Swift Toolkit
All right, so we spoke about the pros and cons. Every developer should pick their technologies based on what's more painful for them and what's more valuable. To wrap up, what are the things that excite you the most for the future of Swift in general and Swift on Android more specifically?

Pierluigi
What excites me the most is seeing it all come together and seeing finally the feeling you get when you have years-old Swift code that you wrote running on Android basically unchanged. That's a very nice feeling.
What I would expect for the community going forward is better integration with the tooling that Android developers have to use day to day. Better integration means not having to rely on a black box that you have to ship from your Mac to your team so they can use it on Android Studio.
Ideally some sort of integration with Android Studio or maybe even Visual Studio Code so you can debug Swift code. I would love to see some native first-party support for this from IntelliJ or from Google. That would be very good.
In terms of Swift as an ecosystem, I think that for this to succeed, Swift on Android has to succeed—otherwise the importance of Swift as a language can begin to fade. Some people are even using technologies like Kotlin Multiplatform or even Compose Multiplatform or even Flutter, making projects that are written 100% in Swift very hard to justify from an economics point of view.
I talked about this with many people at NSSpain. If you're lucky enough that your company can survive without its Android users, good. But if your company needs Android users to be economically viable, then some sort of multi-platform technology will be forced upon you because people try to save costs. And that's one way they think they can save cost, even though in the long run it may be a lot more expensive.
Swift Toolkit
I agree. I hope that this effort continues and reaches even more users and developers and doesn't fade away.
Thanks a lot for joining today. Thanks for your insights.
Pierluigi
Thanks for having me!

Swift, Xcode, the Swift Package Manager, iOS, macOS, watchOS and Mac are trademarks of Apple Inc., registered in the U.S. and other countries.

© Swift Toolkit, 2024-2025