Aleksandar • Vacić

iOS bits and pieces

Masterclass: naming things

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.

Style guide

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.

Namespace well

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.

API wrappers

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 sendOrder: or saveOrder, whichever is more appropriate for the given context.

Singletons

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 shared or default? Why it’s Instance and not Session?

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.

Pointer star

For the longest time, I was writing code like this:

1
2
3
NSTimer *timer = 
(void)timerFired:(NSTimer *)timer
NSString *const RTSomething

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.

1
2
NSTimer * _Nonnull timer = 
(void)timerFired:(NSTimer * _Nonnull)timer

That hanging * now looks more like a typo then correct syntax. Still not settled on this though. Apple’s own frameworks use the hanging * (see enumerateKeysAndObjectsUsingBlock:) so well…; choose as you like and then be consistent with it.