Headstone for AppCode

AppCode is dead. Long live… what, exactly?

If you’ve seen any of my live coding, you know that AppCode is my preferred IDE for Swift. There are very few tasks (such as changing project settings) for which I prefer Xcode. But for coding, there’s no contest. And with the addition of Inline refactorings, my Swift coding accelerated even more.

But as JetBrains announced their latest release of AppCode, they dropped a bomb: this is also their final release. They will provide bare-bones updates for compatibility and security through the end of 2023. And then, the end.

I’m gutted.

Why Did AppCode Die?

Swift alone nearly killed AppCode. But I think SwiftUI struck the final blow.

Remember pre-Swift days? Objective-C was the tool for working with almost everything in the Apple ecosystem. Remember, Objective-C dates back to the early 1980s. A big shift to Objective-C 2.0 happened in 2007. You can still build old Objective-C projects today, with no changes.

Though AppCode users were a small minority, some of my coworkers used it at least occasionally. That’s because compared to Xcode, its support for automated refactoring was overpowering.

Then came Swift.

This new programming language was type-strict, with a lot more syntax. JetBrains, the makers of AppCode, was suddenly left with an IDE that didn’t work for modern Apple development. So they had to catch up, adding basic Swift support. But Swift is a performance hog. AppCode’s usability suffered, and my coworkers who had been using AppCode… well, they stopped.

And this wasn’t just support for a single language. We also needed cross-language support: Swift calling Objective-C, and Objective-C calling Swift. AppCode features suffered when they crossed this language boundary, because a good IDE answers these basic questions:

  • Where is this thing defined?
  • Where is this thing used?
  • Is this thing unused?

Across the language boundary, the answers were sometimes incomplete — and thus wrong. From a coder’s perspective, trusted Objective-C features became worse. So this was another problem that JetBrains had to solve. Even as they did, Apple kept issuing changes to improve the syntax with special transformation rules, which AppCode had to add (after the fact).

But over several releases, AppCode improved in both performance and reliability. It became possible to use for real projects again. I told my coworkers, “You can come back now, it handles Swift just fine.” But they didn’t come back.

Then Swift became open-source.

New language features (with new syntax) started flying in. AppCode’s support for refactoring Swift was bare-bones to start with, but they were in a race adding language changes, and couldn’t afford to add refactoring features. In a race to keep up, you are always going to be behind. So when a new language feature came, AppCode users often had to wait. Of course, this lost even more users.

Still, JetBrains eventually added more code manipulation. Change Signature was a game-changer for me.

Then along came SwiftUI.

SwiftUI did two things. First, it accelerated changes to Swift, adding features and syntax that SwiftUI needs. But also, Xcode’s built-in Preview (live rendering the UI) made Xcode itself more compelling for SwiftUI.

JetBrains published an article showing how to use InjectionIII to see your SwiftUI layouts without Xcode. But InjectionIII is a third-party library — more friction to keep developers from adopting AppCode.

For JetBrains, the expenses of developing AppCode kept increasing, while their revenue kept decreasing. Game over.

Swift Refactorings We’ll Never See in AppCode

With the end of AppCode development, there are refactorings we have for Objective-C that we’ll never see for Swift. These include: Introduce parameter (moving variable definition into the signature)

  • Extract superclass
  • Extract subclass
  • Pull members up (properties or methods)
  • Push members down
  • Move members to another type (existing or new). This checks which referenced members should also move.
  • Remove unused imports

I wrote above, “Compared to Xcode, its support for automated refactoring was overpowering.” Long before the end of AppCode, this was finally true for Swift. But the Swift refactoring was still a thin sliver of what it could do with Objective-C.

And you know what? The powerful Objective-C refactoring itself was a thin sliver of what you can do in their other IDEs, especially IntelliJ.

I grieve for what could have been.

What’s the Future of Refactoring and Code Generation in Swift?

So now what? I would guess that most developers in the Apple ecosystem have only ever worked in Xcode. There’s no clamor for better tools. Will Apple developers remain ignorant of automated refactoring or point-of-call code generation?

I sure hope not. There are two ways this could go. One way is Apple putting in the hard work to improve refactoring in their tools. This would mean:

  • Improving current refactorings which are barely adequate (if they work at all)
  • Adding new refactorings
  • Providing these in a keyboard-triggered pop-up instead of slow mouse access

But given Apple’s antipathy to good coding practices (and their lack of exposure to ideas outside their ecosystem), the odds are slim. And what few changes they will provide come only once a year.

But they’re not the only players. Remember how Swift went open-source?

We have an opportunity for the open-source community to respond. There’s already an official Swift plug-in for the VSCode IDE. Still in its early days, it’s worth keeping an eye on.

What if the community came together to create:

  • A way to convert Swift source code into an Abstract Syntax Tree (AST)
  • A way to convert an AST back into Swift source code
  • Behavior-preserving transformations of the AST

Maybe it’s time for developers to reclaim tool-making in the Apple ecosystem, and let Apple catch up.

Do you know of tools to refactor Swift source code, or generate new code from a call site? Please share any in the comments below.