Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/spotify/ios-style

Guidelines for iOS development in use at Spotify
https://github.com/spotify/ios-style

code-style coding-style objective-c spotify style-guide

Last synced: about 1 month ago
JSON representation

Guidelines for iOS development in use at Spotify

Awesome Lists containing this project

README

        

Spotify Objective-C Coding Style
================================

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.

License
-------
Copyright (c) 2015-2016 Spotify AB.

This work is licensed under a [Creative Commons Attribution 4.0 International License]( http://creativecommons.org/licenses/by/4.0/).

Table of Contents
-----------------

1. [Spacing, Lines and Formatting](#spacing-lines-and-formatting)
2. [Brackets](#brackets)
3. [Naming](#naming)
4. [Comments](#comments)
5. [Pragma Marks](#pragma-marks)
6. [Constants](#constants)
7. [Return Early](#return-early)
8. [Initializers](#initializers)
9. [Headers](#headers)
10. [Nullability](#nullability)
11. [Strings](#strings)
12. [Dot Notation](#dot-notation)
13. [Categories](#categories)

Spacing, Lines and Formatting
-----------------------------

### Line length
* Keep your lines within **120** characters width when possible.
* In Xcode, you can set a page guide in Text Editing in Preferences.

### Whitespace
* 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:**
```objc
foo("bar")
```

**Not:**

```objc
foo( "bar" )
```

### Containers
* Array one-liners are acceptable unless they have too many items or their values are too long.

```objc
NSArray *array = @[@"uno", @"dos", @"tres", @"cuatro"];
```

* In that case, break them in several lines:

```objc
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:

```objc
NSDictionary *dict = @{@"key" : @"highway"};
```

* Format it pretty otherwise, leaving a trailing comma after the last item:
```objc
NSDictionary *dict = @{
@"key1" : @"highway",
@"key2" : @"heart",
};
```

Brackets
--------
* Always use brackets for `if` / `for` / `while` / `do`-`while` statements. Even if its a one-liner:

```objc
if (itsMagic) {
[self makeItEverlasting];
}
```

* Write follow up `else` clauses after the previous closing bracket on the same line.

```objc
if (hasClue) {
knowExactlyWhatToDo();
} else if (seeItAllSoClear) {
writeItDown();
} else {
sing();
dance();
}
```

Naming
------
* Follow Apple’s [Coding Guidelines for Cocoa](https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CodingGuidelines/CodingGuidelines.html)
on naming.

Comments
--------
* 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:**
```objc
/*
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.
```

* Document all methods and properties in the headers using Xcode’s documentation style (which is `///` 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 Marks
------------
* Use the pre-processor instruction `#pragma mark` to mark related groups of methods.

Constants
---------
* Do not define constants using `#define`.
* Publicly (or privately) exposed variables should be constant (trying to assign values will result in compilation
error).

```objc
extern NSString * const SPTCodeStandardErrorDomain;
```

Return Early
------------
* Return early on errors and failed pre-conditions to avoid unnecessary nested brackets and / or unnecessary
computations.

**Example:**

```objc
- (void)setFireToTheRain:(id)rain
{
if ([_rain isEqualTo:rain]) {
return;
}

_rain = rain;
}
```

Initializers
------------
* Follow [Apple's typical init format](https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html#//apple_ref/doc/uid/TP40011210-CH5-SW11) to initialize objects.

**Example:**

```objc
- (instancetype)init
{
self = [super init];

if (self) {
// initialize instance variables here
}

return self;
}
```

Headers
-------
* The use of prefix headers has been deprecated. Do not add new code to an existing prefix header.
* When importing a module use the hash-import variant instead of at-import.
* Yes: `#import `
* No: `@import Foundation;`

Nullability
-----------
* Use `NS_ASSUME_NONNULL_BEGIN` and `NS_ASSUME_NONNULL_END` in header files, and explicitly add `nullable` when needed. Example:
```objc
#import

@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 playlist;

- (nullable instancetype)initWithPlaylist:(id)playlist
customTitle:(nullable NSString *)customTitle;

@end

NS_ASSUME_NONNULL_END
```

Strings
-------
* All strings presented to the user should be localized.

Dot Notation
------------
* Use bracket notation when calling non-accessor methods:

```objc
[self doSomething];
```

* Use bracket notation when accessing globals through a class method:

```objc
[MyClass sharedInstance];
```

* Set and access properties using dot notation:

```objc
self.myString = @"A string";
```

* Except in the `init` or `dealloc` methods, always use the ivar directly there:

```objc
_myString = nil;
```

Categories
----------
* Methods in categories on non-Spotify classes must be prefixed `spt_` to avoid name clashes.