Since Swift’s introduction in 2014, it has matured a lot. We no longer read the stories of how unstable the compiler is, or how SourceKit is crashing every few minutes. While some people might still argue Swift isn’t production ready, there’s no denying that there are thousands of apps on the App Store that are either entirely written in Swift, or at least contain some Swift code.
There are many reasons some teams are hesitant to start using Swift. Those include things like having to spend time to migrate their codebase each time a new version comes out or dealing with the less than ideal tooling. While we have the same concerns at Instabug, there is one major issue that simply prevents us from using Swift, which is ABI stability.
ABI is short for “Application Binary Interface”. An ABI defines lots of low-level details, like how parameters are passed to functions and how system calls are made. Think of an ABI as the application programming interface (API) for pre-compiled libraries.
Saying that a language has ABI stability means that we would be able to take a pre-compiled binary and link it with different versions of the compiler.
So for example, if we compile the Instabug SDK using Swift 2.3, it would be possible to link it to an app that uses Swift 2.1, 3.0 or any other version. Right now, since Swift doesn’t have ABI stability, a version of the Instabug SDK built with Swift 2.3 would only be usable in an app that uses Swift 2.3.
So is this really a big deal? It’s not for application developers and for open-source libraries, but for an SDK that’s distributed pre-compiled, it’s a deal breaker.
Apple initially planned ABI stability for Swift 3.0, then pushed it to 4.0, and recently they announced that it has been deferred from 4.0. The Swift team has put together an ABI Stability Manifesto that details everything that needs to be done to have a stable ABI along with a dashboard that shows the status of each task that needs to be completed.
The reasoning behind having a stable ABI getting postponed several times is that there have been higher priorities like improving compile time, compiler stability and making important language changes, like completing the generics system, that have to be done before the ABI could be locked down.
One more issue that prevents us from adopting Swift is the fact that a runtime library is included with every app that uses the language either directly or by using a framework that contains it. This is done to make sure that an app will continue to run reliably on the past, present, and future versions of iOS. As a result of including the runtime library, app size increases by about five megabytes.
This wouldn’t be an issue for apps that already use Swift, but for the ones that are purely written in Objective-C, that would be an undesirable side effect of using our SDK.
Until Swift reaches ABI stability, we must have 100% of our framework codebase written in Objective-C. However, we currently use Swift to write some of our UI and unit tests. When we’re finally able to include Swift code in our framework, it will most likely be a slow transition with most new code being written in Swift, while maintaining all the current Objective-C code.