Converting Objective-C to Swift
When I first started writing in Swift, version 2.0 of the language had just been released. I didn’t start out as an ObjC developer, but every example I came across was written in ObjC and I reluctantly forced myself to learn it. Despite reading a lot of ObjC code and writing some, I still prefer to have all my code in a Swift project be written in Swift.
In order to add window management to the Multitouch app, I recently decided to port the popular Spectacle app from ObjC to Swift. The port ended up being more of a rewrite of the app, and I open sourced it and released it as Rectangle. Here’s what I learned along the way.
If doing it yourself seems crazy, pay a service
Depending on the codebase, how much time you have, and your ObjC dev chops, manning up and doing a full manual port of your ObjC code will more than likely give you the best results. Chances are that if you’re reading this, you already know that’s not a path you want to go down. Because of time constraints, I knew this wasn’t something I wanted to do. Even if a service only got me half the way there, I figured I would save significant time.
At the time of this writing there’s really only one service I found that looked to be worth using: Swiftify. I tried out the trial of iSwift, but it doesn’t appear to be maintained. I couldn’t get iSwift to convert an entire project at once to Swift, and it didn’t port to the latest version of Swift (not a dealbreaker for me, but still). Swiftify checked all of those boxes, and the website says it can get you 90% of the way there. We’ll see if that rings true.
As you’d probably expect from a service like this, it can be a little tricky to figure out how much it costs to just convert a project without finagling around a little bit on their site. To convert a project, your simple options are a pay as you go or a subscription. The pay as you go is based on the size of the files that are uploaded to be converted. Spectacle source files were about 55KB zipped (370KB unzipped), and converting via pay as you go was around $18 if I remember right. Compare that with the monthly subscription of $30 for up to 10MB of files. For me, I figured that if I messed up and needed some extra files converted, I’d rather just have paid $30 than potentially more. Additionally, I’d be able to convert a few odds and ends projects and maybe get my money’s worth. You can cancel the subscription at any time, and still use the service until 1 month is over or you’ve reached the 10MB limit. 10MB of source code is actually a rather generous amount if you’re in it for converting small projects. I recommend trying out the pay as you go method first, as they give you an automated price tag before you have to pay anything. I paid $3 for a small one-class conversion outside of the subscription.
Of course, there’s other options, including paying the Swiftify team to convert your code for you. The $30 subscription for 1 month was as much as I wanted to spend, which is actually a pretty cheap gamble when you’re looking at potentially saving several hours of your life.
The Swiftify team has provided us with a plethora of avenues to take for executing the conversion, and I think at the end of the day all of them just upload code to their servers and spit the results out. I hate installing software when it’s not necessary, especially plugins, so cut the corners and just upload a zip of your source to via the website. If you’re extremely lucky, you won’t see any errors logged on site for the conversion.
So you download the converted Swift sources and you’re pretty much good to go, right? Well, not quite. This is where things actually get interesting. I’m not really sure where they got that 90% figure from on the website, but what I got back for Spectacle seemed pretty far away from it. I had plenty of errors logged on the website during the Swiftify conversion, and this resulted in a hefty amount of work just to get the darn thing to compile. Your mileage may vary.
You’re still manually porting code, just from broken to working Swift
As for the generated Swift code, I started with over 280 errors and warnings to chomp through. Getting the code to compile was very similar to any code porting project. You tend to find a few recurring patterns that you just continuously fix over and over again. It’s a bit numbing, but finally getting to that point with no errors feels pretty good, even though the project doesn’t still doesn’t actually work by the end of it. Also, the number of errors does increase as you go, as the compiler can reach more and more parts of the code.
At their simplest, compile errors in the converted code would be things like missing argument labels in function calls. The most common compile errors dealt with optionals, and sometimes these would require some careful tracing to figure out what variables should and shouldn’t be optional. The problems weren’t that difficult to solve, there was just a lot of them for a relatively small codebase.
Despite the initial difficulty of getting the Swift code to compile, I quickly grasped the beauty of Swiftify — it was already just so much easier to sift through the Swift code than the original ObjC code. On the ugly side, however, I never felt like I could fully trust it. There was one instance where the converted code was gibberish. It appeared to get tripped up on excess of parentheses and operators. Bottom line is that this distrust forced me to code review all the generated code side by side with the ObjC code, and that kinda sucked. But… it was actually the right thing do anyways. It gave me a stronger understanding of the code.
Swiftify: Yay or nay?
After all of that I initially didn’t feel like I could 100% recommend it to a friend due to the amount of work still left for me to do after the conversion. But… take a step back and think about the situation. I am just one developer, and I don’t have years of ObjC experience. Adding up all the time I spent on the port, it was less than 10 hours. I was able to cut some corners because I didn’t want to use all of the code in Spectacle, and I already had similar Swift code from other apps that I could use to fill in some gaps. Still though, the time saved has to be pretty big. Having a starting point of a broken Swift project is still quite a bit faster for me than starting with an ObjC project.
With that in mind, I absolutely would recommend Swiftify to a friend. I think the automated Swiftify service was a good solution where my end result was a Swift port where I still got the understanding of the codebase without burning too much time or money. I could have done with a little less errors to fix though ;)
(I have no affiliation with Swiftify. This was my experience and my opinions.)