Version: 0.9.0
Our general coding conventions at Spotify are documented on an internal wiki, but specifics for Objective C and Objective C++ code in the iOS client are documented here.
Copyright (c) 2015 Spotify AB.
This work is licensed under a Creative Commons Attribution 4.0 International License.
- Spacing, Lines and Formatting
- Brackets
- Naming
- Comments
- Pragma Marks
- Constants
- Return Early
- Initializers
- Prefix Headers
- Strings
- Dot Notation
- Categories
- Keep your lines within 120 characters width when possible.
- In Xcode, you can set a page guide in Text Editing in Preferences.
- Use 4 spaces for indentation and alignment. Do not use tabs.
- Trailing whitespace is acceptable only on blank lines, but discouraged even there.
- In Xcode, select "Automatically trim whitespace" and "Including whitespace-only lines" in Text Editing preferences to handle this automatically.
- Put spaces after commas, and before and after operators.
- Do not put spaces between parentheses and what they are enclosing.
Example:
foo("bar")
Not:
foo( "bar" )
- Array one-liners are acceptable unless they have too many items or their values are too long.
NSArray *array = @[@"uno", @"dos", @"tres", @"cuatro"];
- In that case, break them in several lines:
NSArray *array = @[
@"This is how we do, yeah, chilling, laid back",
@"Straight stuntin’ yeah we do it like that",
@"This is how we do, do do do do, this is how we do",
];
- Dictionary one-liners are reserved for single pairs only:
NSDictionary *dict = @{@"key" : @"highway"};
- Format it pretty otherwise, leaving a trailing comma after the last item:
NSDictionary *dict = @{
@"key1" : @"highway",
@"key2" : @"heart",
};
- Always use brackets for
if
/for
/while
/do
-while
statements. Even if its a one-liner:
if (itsMagic) {
[self makeItEverlasting];
}
- Write follow up
else
clauses after the previous closing bracket on the same line.
if (hasClue) {
knowExactlyWhatToDo();
} else if (seeItAllSoClear) {
writeItDown();
} else {
sing();
dance();
}
- Follow Apple’s Coding Guidelines for Cocoa on naming.
- Use the
//
style for single line comments or when appending comments in the same line of code. - Use the
/* */
style for multi-line comments.
Example:
/*
* This is a multi-line comment. The opening and closing markers are on their
* own lines, and each other line is preceded by a * that is indented by one
* space.
*
* This is a new paragraph in the same block comment.
*/
stop(); // Hammer-time!
// this is a very brief comment.
- Use doxygen-style comments for all the headers. Make
sure to use the available markup tags like
@param
,@return
, etc. The///
form is preferred for single line comments, and/** */
for multi-line comments. Use the same formatting as in the example block above.
- Use the pre-processor instruction
#pragma mark
to mark related groups of methods.
- Do not define constants using
#define
. - Publicly (or privately) exposed variables should be constant (trying to assign values will result in compilation error).
extern NSString * const SPTCodeStandardErrorDomain;
- Return early on errors and failed pre-conditions to avoid unnecessary nested brackets and / or unnecessary computations.
Example:
- (void)setFireToThe:(id)rain
{
if ([_rain isEqualTo:rain]) {
return;
}
_rain = rain;
}
- Always do assignment of
self
, callsuper
(or the designated initializer) and return early on failure.
Example:
- (instancetype)initWithName:(NSString *)name
{
if (!(self = [super init])) {
return nil;
}
_name = name;
return self;
}
- The use of prefix headers has been deprecated. Do not add new code to an existing prefix header.
- All strings presented to the user should be localized.
- Use bracket notation when calling non-accessor methods:
[self doSomething];
- Use bracket notation when accessing globals through a class method:
[MyClass sharedInstance];
- Set and access properties using dot notation:
self.myString = @"A string";
- Except in the
init
ordealloc
methods, always use the ivar directly there:
_myString = nil;
- Methods in categories on non-Spotify classes must be prefixed
spt_
to avoid name clashes.