Tools of the Trade: AppCode, a breath of fresh air from the Xcode monoculture.

If you are a Mac or iOS developer for better or for worse there is no way around Xcode.

Xcode is free and full-featured, so why would you ever want to use anything else? This is the main reason why there are practically no other Mac OS X or iOS developer tools on the market today. There just isn’t any room for third parties for it to make economic sense to develop expensive developer tools.

The only other serious IDE for Mac OS X and iOS development is JetBrain’s AppCode and I’d recommend that every serious Apple developer should own a copy. While Xcode has evolved into a powerful and mostly stable tool, Apple has a lot of blindspots and Xcode is in many areas (at least) 15 years behind the top of crop. AppCode isn’t.

JetBrains is the powerhouse of Java development tools and they represent everything that Apple does not. Where Apple is closed, secretive and has a very paternalistic approach to its developer community, JetBrains is open, transparent, friendly and as cross-platform as it is possible to be.

The advantages for an Apple developer such as myself is that you get a peak at the world beyond Apple’s strictly enforced white room monoculture. Using AppCode is as much about growing as a developer as it is about efficiently developing software.

JetBrains offers IDEs that support nearly every language that is available and the more outrageously new and niche a language is, the more likely that JetBrains has a tool for it. This means that once you get used to the basic IDE concepts, you can take that expertise and use it for developing in other languages, on other platforms (Android, Windows, Web) and with other technology stacks.

I use WebStorm for my own website development, RubyMine for web app stuff and IntelliJ IDEA for learning functional programming in Scala. If I ever wanted to learn CoffeeScript, Dart or Haskell I know I’d be covered there too. On top of this JetBrains’ plug-in technology makes adding support for the latest and greatest open source technologies a breeze and JetBrains are very good at keeping an eye open for exiting new technologies. There’s a good chance that the first you hear about a new technology is by looking at JetBrains’ product release notes.

The AppCode IDE itself is very much in the mold of other Java development environments. The IDE can do everything and more, but it is also very busy and a long way from the pared-down minimalistic Apple aesthetic. It’s a nerdy power tool more than a philosophical statement.

JetBrains is rightly famous for their language parsing and refactoring acumen, so their IDEs are chock full of “intelligent” features. Not the kind of “intelligent” that makes everything harder, but the actual intelligent kind.

Navigating in AppCode is much more powerful than in Xcode. The gutter contains a myriad of options that will take you from method implementation to declarations and vice versa. You can also click and hold from class definitions to jump to super- and sub-classes, get in-line help and auto-fixing for commons problems. The as-you-type code analyzer finds potential problems and standard fixes, the code reformatting options are powerful and easily accessible. The intelligence extends to seamlessly into finding all places a piece of code is actually used rather than having to rely on text searches.

Best of all, however, AppCode can make changes to associated files without leaving the current file. The annoying roundtrip between implementation and header files that keeps interrupting your train of thought in Xcode can be wholly avoided. You write the implementation for a method and AppCode just offers you the ability to declare said method in the header with a single click without ever taking your eyes of the code you are busy writing.

Working in AppCode you constantly find yourself wondering why Apple can’t just do this. If it seems obvious, it’s in AppCode. Unfortunately this is rarely true for Xcode.

Refactoring is part and parcel of the AppCode experience and backed so far into the IDE that it becomes a nearly invisible part of your development. If you are used to refactoring in Xcode, you are likely to be non-plussed by AppCode’s refactoring support. Where Xcode makes a huge deal out of every refactoring: taking a snapshot, making you validate a thousand changes and more likely than not failing bang in the middle of the refactoring, AppCode just makes the changes with no fuss whatsoever. The first time I used the renaming refactoring in AppCode, I was wondering what I was doing wrong. I typed the new name into the red highlighted area and nothing happened! How do you terminate the editing? In fact, AppCode had already done the project-wide refactoring. Why make a fuss about it? Why could it fail? Why beach-ball for a few seconds? Why indeed?

AppCode enables you to work in a completely different manner to Xcode. Say you are into Test-Driven Development. Write the test cases first. When you instantiate your target class in the test class, AppCode will tell you that the class does not yet exist. A single click solves the problem by creating the class for you. As you write your tests, you can one-click to add method declarations and empty implementations. When you’ve finished with your test cases, there’ll be .m and .h files with complete stub implementations all without you ever leaving the test case implementation file.

Another big differences with Xcode is that where Apple knows everything best and either offers no customization or forces you to comply with their guidelines, JetBrains puts you in charge. Almost every aspect of the IDE is fully customizable: you can define your own coding style, which will cause AppCode to use your specific style to create stubs. You can even decide to reformat your code automatically before checking it into source control. You can (obviously) choose your own source code management system, add CocoaPods support, edit and preview HTML, CSS, Compass, TypeScript, JavaScript, files or add your own selection of plug-ins. In short, JetBrains is for grown-ups that like taking their own decisions.

Similarly, if you’ve ever felt the frustration of never being able to talk to anybody at Apple about Xcode, you will find the JetBrains support team a breath of fresh air. Something not working? Something not supported? Something you’d like to see added? Just drop them a line and an actual person will reply to you; better yet that person will be an approachable, open-minded fellow developer intent on helping you out. With JetBrains you’re the customer and you know best.

Seriously, just give it a shot. If only for a breath of fresh air.

Some thoughts about Optionals in Swift

Like many Mac and iOS developers, I haven’t yet made the jump from Objective-C to Swift, nor will I make it in the near term.

Just like most other developers, I am slowly putting a little bit of Swift code into new projects to get a feel for the language and I’m experimenting with its new features to be ready when it becomes a more practical proposition.

At the moment, I’m trying to come to grips with “optionals“, a construct that I have never seen in any language I’ve used before.

Essentially, “optionals” are shoeboxes that may or may not contain a value. You can find out whether they contain a value and if so, you can get the value out by “unwrapping it” and if it contains a mutable type, you can change it.

This replaces the C-style pointers that may either point to the data belonging to an object (in the largest sense of the word) or have a “nil” or “NULL” value that signifies “no object”.

Optionals are a clear improvement on null pointers or nil types in at least two significant ways:

  1. Optionals eliminate a whole class of common bugs by forcing developers to think about “what happens if this method does not return a valid object/ value”
  2. Optionals help make Swift code faster by making it easier and safer to optimize code; optimizers do not have to worry about edge cases where the value may be empty.

The price for those two advantages seems very steep, however.

First, not dealing with potentially invalid objects being returned prevents the code from being compiled in the first place. You cannot not deal with the problem.

Secondly, optionals require developers to learn a host of new concepts. This may be a good thing in the long term, but it will slow adoption as you can’t just dive into the language without understanding optionals and you have little hope of ever having come across them before (unless you are beta testing Rust that is).

Using optionals is also really, really cumbersome. Unwrapping each and every optional makes even trivial programs balloon to many times their normal size. This is why Apple has thoughtfully added a lot of syntactic sugar to make the medicine go down that much more easily.

This syntactic sugar (chaining, etc.) makes your code smaller and cleaner and you can almost forget that it is there at all when you read it. Unfortunately that isn’t the case when you write the code and it does also add a whole layer of complexity making Swift harder to learn and understand.

Optionals also do not map onto anything in Objective-C and as there are no native libraries yet, “implicitly unwrapped optionals” abound and feel very much like a backwards-compatibility hack and a solution to a problem you wouldn’t have without optionals.

So there is a price to be paid for beauty, performance and safety.

That needn’t be a show stopper. You get nothing for free in life and the result may be worth the effort.

Unfortunately, when I’m actually using Swift, I find that I don’t seem to be getting much value out of optionals.

Firstly, there’s the fact that now instead of trying to express what I want to do, I find myself wondering about whether I need to unwrap my optionals? and what might be the best syntax for expressing the unwrapping? where should it be done? now or later? Why does this code not compile?

Admittedly with a little bit of practice, this will probably largely go away. There will always be a  cognitive overhead associated with it, but it will that overhead is likely to get smaller with time. I certainly won’t miss having to check the location member of the return value of rangeOfString: for NSNotFound.

The real killer for me is, however, that I now find all those places in my code where I need to think about what to do when the optional is empty .. and I find that there’s not much to be done.

What can you do when you are loading an image from your app bundle and it is not there? There only seem to be two options:

  1. raise an exception, crash or display an alert that the user can’t do anything about
  2. do nothing

Crashing is great, because now there’s a crash report being generated and I know that something has gone wrong in the production version and I can work out what the cause is and correct it. Crashing early is best practice. It certainly beats crashing later.

Doing nothing might be okay in many situations, because it might not be so bad. It is in fact what Objective-C does most of the time in this situation. It just ignores the problem, the application keeps running (but not necessarily working) or it simply crashes somewhere down the line.

Herein lies the problem with optionals. They force you to deal with potential problems that you can’t do anything intelligent about. Worse, because of the absence of an exception mechanism you need to deal with exceptions in situ, polluting your beautiful code with non-sensical error handling code.

So, what I’m wondering is: “Is there any value in explicitly dealing with problems that you can’t do anything about?”