Guidelines for iOS development in use at Spotify
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-2016 Spotify AB.
This work is licensed under a Creative Commons Attribution 4.0 International License.
Example:
foo("bar")
Not:
foo( "bar" )
NSArray *array = @[@"uno", @"dos", @"tres", @"cuatro"];
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",
];
NSDictionary *dict = @{@"key" : @"highway"};
NSDictionary *dict = @{
@"key1" : @"highway",
@"key2" : @"heart",
};
if
/ for
/ while
/ do
-while
statements. Even if its a one-liner:if (itsMagic) {
[self makeItEverlasting];
}
else
clauses after the previous closing bracket on the same line.if (hasClue) {
knowExactlyWhatToDo();
} else if (seeItAllSoClear) {
writeItDown();
} else {
sing();
dance();
}
//
style for single line comments or when appending comments in the same line of code./* */
style for multi-line comments.Example:
/*
This is a multi-line comment. The opening and closing markers are on their
own lines.
This is a new paragraph in the same block comment.
*/
stop(); // Hammer-time!
// this is a very brief comment.
///
at the time of writing).
You can select a property or method and use Option
+Cmd
+/
to generate the documentation template for it. Make sure to use the available
markup tags like @param
, @return
, etc. (these will be auto-generated for you by Xcode).#pragma mark
to mark related groups of methods.#define
.extern NSString * const SPTCodeStandardErrorDomain;
Example:
- (void)setFireToTheRain:(id)rain
{
if ([_rain isEqualTo:rain]) {
return;
}
_rain = rain;
}
Example:
- (instancetype)init
{
self = [super init];
if (self) {
// initialize instance variables here
}
return self;
}
#import <Foundation/Foundation.h>
@import Foundation;
NS_ASSUME_NONNULL_BEGIN
and NS_ASSUME_NONNULL_END
in header files, and explicitly add nullable
when needed. Example:#import <Foundation/Foundation.h>
@protocol SPTPlaylist;
NS_ASSUME_NONNULL_BEGIN
typedef void(^SPTSomeBlock)(NSData * _Nullable data, NSError * _Nullable error);
@interface SPTYourClass : NSObject
@property (nonatomic, copy, readonly, nullable) NSString *customTitle;
@property (nonatomic, strong, readonly) id<SPTPlaylist> playlist;
- (nullable instancetype)initWithPlaylist:(id<SPTPlaylist>)playlist
customTitle:(nullable NSString *)customTitle;
@end
NS_ASSUME_NONNULL_END
[self doSomething];
[MyClass sharedInstance];
self.myString = @"A string";
init
or dealloc
methods, always use the ivar directly there:_myString = nil;
spt_
to avoid name clashes.