Swift on Android, Part Two: What Now?

I wrote about the technical details of porting the Swift runtime to Android in my last post. This post discusses the implications for mobile developers.

Should you write iOS/Android cross-platform code in Swift?

Writing cross-platform Swift source code that can run on both iOS and Android is technically possible, but practically very inconvenient.

The only successful deployment that I know of is described by Geordie Jay in his marvelous series of blog posts. His team successfully overcame esoteric linker errors…

As we soon found out, the Android linker ignores LD_LIBRARY_PATH when loading libraries from within Java via System.loadLibrary().

…and developed a method to interface with the JNI from Swift:

We needed a bit more control though: to truly interface with our web app […] we still had to use the JNI to pass around some strings and arrays to and from Java.

Some teams are skilled and dedicated enough to deal with these kinds of roadblocks. Some teams, on the other hand, don't have the resources to do so. If your team relies on polished, widely used developer tools to ship software, I'd recommend mobile cross-platform solutions such as C++ or React Native instead.

Below, I'll highlight some of Swift's limitations on Android, and the work being done to resolve those issues. If it suits you, your career goals, or your team's strategy when it comes to recruiting or open-source "branding," I'd recommend contributing to these areas.

Peripheral libraries

The Swift standard library is nice, but Swift programmers are productive in large part thanks to peripheral libraries, such as Apple's libdispatch and Foundation. Apple released swift-corelibs-libdispatch and swift-corelibs-foundation as Linux Swift versions of these core libraries, but they only partially work on Android.

Gonzalo Larralde has sent a pull request that makes libdispatch available on Android, and it looks like it will be merged soon. John Holdsworth ported Foundation to Android.

Foundation support on Android doesn't "just work", however. Your code will need to include several hooks to ensure it plays nicely with Java. Read the comments on John's Foundation pull request for details, and check out his example project.

Downloadable toolchains

Unlike macOS and Linux, no one is hosting downloadable Swift compiler toolchains for Android. To use Swift on Android, you'll need to download the Swift source code, and build the compiler yourself using the instructions here.

The Swift runtime for Android cannot currently be built on macOS. You must use a Linux environment. I've sent a pull request to enable building on macOS.

In addition, there is no continuous integration server for Swift on Android. I usually find out it's broken and fix the build within a day or two. Apple's Swift CI team is working on extending their Jenkins setup to support Android and other platforms. In the meantime, I've thought about building a @swift-android-ci GitHub bot that connects to my own personal Jenkins instance, but haven't invested any time or money into it yet.

Bridging with Java

It takes a lot of boilerplate to call Swift from Java, or vice versa. Tools like React Native (JavaScript) and Djinni (C++) solve this on other platforms, but no such solution exists for Swift. Perhaps it's possible to build something like Swift's ClangImporter, but for Java – I haven't spent a lot of time looking into this.