I’m a big believer that code should have consistent style. I got my first contract web gig not by how my code performed, but how it looked. Its vibe was that it’s a code done by person that cares.
There is only one true rule: make up your mind and be utterly and thoroughly consistent.
I was lucky to be properly schooled very early on naming and general guidelines how Cocoa code should look. I found two great blog posts by Scott Stevenson (he works at Apple for a number of years now) from back in 2004. Everything he wrote back then still holds true and I urge you to go and read both. Scott explains not only how but also why it should be that way.
Back in 2008, I made a small booklet out of those pages and color-printed it. It was siting on my table for years, right next to the monitor.
Over time, I have developed few rules of my own.
The first thing you need to do is choose good prefix. I was in quite a pickle here as I kept hitting into existing Apple frameworks. Initials from my name are
AV so that was out of questions. My original company name was code·aplus which gives
CA – also out of question.
Thus when I renamed to Radiant Tap, using
RT was straight forward and did not overlap with anything.
One advice here is to avoid using K as second letter - Apple has a tendency to create
_Something_Kit frameworks and you can find yourself in a problem. For the same reason, avoid F (Foundation) as the second letter and C (Core) as the first letter.
Side note: Apple actually recommends that you use three-letter prefix - blah. They also recommend to prefix your methods as well, like
rt_fetchContact. Yuck. That’s unnatural to both read and write. Not gonna happen here.
Mobile apps rarely are a world on their own and they usually involve one or more web services and thus you need to write wrappers for those services.
I avoid using get in the name of methods that get data from the service - I use fetch instead. The reason is that while most APIs use HTTP’s GET method to deliver data, there are cases where you would be using POST as well. In that case having
getLanguages: method implies that GET will be used.
fetchLanguages: implies nothing.
Similarly, instead of
postOrder: I use
saveOrder, whichever is more appropriate for the given context.
Singletons are an important design pattern that Apple uses all over their frameworks. What irks me is that they are not consistent with their naming. You have
[NSFileManager defaultManager] but also have
[AVAudioSession sharedInstance]. Well darn – should it be
default? Why it’s
Instance and not
It’s annoying to use frameworks from the same company and need to guess or look up which name they used.
In my code lately, I settled on
default followed by the name of the Class itself. Thus if it’s RTRunManager class then its singleton is
[RTRunManager defaultManager], if it’s RTChartDataSource then it’s
[RTChartDataSource defaultDataSource] etc.
update (Oct 14): Khoa Pham suggested a nice distinction between default/shared: use
default for recommended configuration but can safely create your own new instance. Use
shared if it’s safe to have only one instance of the particular class.
For the longest time, I was writing code like this:
1 2 3
No hard and fast rule, it just looked nicer to me to place the
* next to the variable and not after the type. Thinking like - it’s my pointer to the variable, not to the Class or from the Class.
However, the nullability attributes in iOS 9 have thrown me out a bit.
* now looks more like a typo then correct syntax.
Still not settled on this though. Apple’s own frameworks use the hanging
enumerateKeysAndObjectsUsingBlock:) so well…; choose as you like and then be consistent with it.