Airbnb Swift Style Guide
Goals
Following this style guide should:
- Make it easier to read and begin understanding unfamiliar code.
- Make code easier to maintain.
- Reduce simple programmer errors.
- Reduce cognitive load while coding.
- Keep discussions on diffs focused on the code’s logic rather than its style.
Note that brevity is not a primary goal. Code should be made more concise only if other good code qualities (such as readability, simplicity, and clarity) remain equal or are improved.
Guiding Tenets
- This guide is in addition to the official Swift API Design Guidelines. These rules should not contradict that document.
- These rules should not fight Xcode’s ^ + I indentation behavior.
- We strive to make every rule lintable:
- If a rule changes the format of the code, it needs to be able to be reformatted automatically (either using SwiftLint autocorrect or SwiftFormat).
- For rules that don’t directly change the format of the code, we should have a lint rule that throws a warning.
- Exceptions to these rules should be rare and heavily justified.
Table of Contents
- Xcode Formatting
- Naming
- Style
- Patterns
- File Organization
- Objective-C Interoperability
- Contributors
- Amendments
Xcode Formatting
You can enable the following settings in Xcode by running this script, e.g. as part of a “Run Script” build phase.
-
(link) Each line should have a maximum column width of 100 characters.
Why?
Due to larger screen sizes, we have opted to choose a page guide greater than 80
-
(link) Use 2 spaces to indent lines.
-
(link) Trim trailing whitespace in all lines.
⬆
back to top
Naming
-
(link) Use PascalCase for type and protocol names, and lowerCamelCase for everything else.
protocol SpaceThing { // ... } class SpaceFleet: SpaceThing { enum Formation { // ... } class Spaceship { // ... } var ships: [Spaceship] = [] static let worldName: String = "Earth" func addShip(_ ship: Spaceship) { // ... } } let myFleet = SpaceFleet()
Exception: You may prefix a private property with an underscore if it is backing an identically-named property or method with a higher access level
Why?
There are specific scenarios where a backing a property or method could be easier to read than using a more descriptive name.
- Type erasure
<div class="highlight highlight-source-swift position-relative" data-snippet-clipboard-copy-content="public final class AnyRequester: Requester {
public init(_ requester: T) where T.ModelType == ModelType {
_executeRequest = requester.executeRequest
}@discardableResult
public func executeRequest(
_ request: URLRequest,
onSuccess: @escaping (ModelType, Bool) -> Void,
onFailure: @escaping (Error) -> Void)
-> URLSessionCancellable
{
return _executeRequest(request, session, parser, onSuccess, onFailure)
}private let _executeRequest: (
URLRequest,
@escaping (ModelType, Bool) -> Void,
@escaping (NSError) -> Void)
-> URLSessionCancellable}
“>public final class AnyRequester<ModelType>: Requester { public init<T: Requester>(_ requester: T) where T.ModelType == ModelType { _executeRequest = requester.executeRequest } @discardableResult public func executeRequest( _ request: URLRequest, onSuccess: @escaping (ModelType, Bool) -> Void, onFailure: @escaping (Error) -> Void) -> URLSessionCancellable { return _executeRequest(request, session, parser, onSuccess, onFailure) } private let _executeRequest: ( URLRequest, @escaping (ModelType, Bool) -> Void, @escaping (NSError) -> Void) -> URLSessionCancellable }