-
1 - Indentation must be done using tabs, each tab has 4 spaces width (set Xcode > Preferences > Text Editing > Indentation)
-
2 - Always avoid long lines; max line length should be 160 characters (set XCode > Preferences > Text Editing > Page Guide Column)
-
3 - Enable automatic Trim Trailing Whitespace (set XCode > Preferences > Text Editing > Automatically trim trailing whitespace & Including whitespace-only lines)
-
4 - Never place place opening braces on new lines (1TBS convention).
class MyClass { func myMethod() { if x == y { /* ... */ } else if x == z { /* ... */ } else { /* ... */ } } /* ... */ }
-
5 - When writing a type for a property, constant, variable, a key for a dictionary, a function argument, a protocol conformance or a superclass don't add a space before the colon.
// Property Type let aProperty: MyPropertyClass // Dictionary let aDictionary: [String: Int] = [ "key1": 2, "key2": 3 ] // Function func aFunction<T, U: SomeProtocol>(argA: U, argB: T) where T.RelatedType == U { /* ... */ } // Calling a Function myFunction(argument: "MyArgument") // Superclasses class Dog: Wolf { /* ... */ } // protocols extension PirateViewController: UITableViewDataSource { /* ... */ }
-
6 - There should be a space following a comma.
let anArray = ["a", "b", "c"]
-
7 - There should be a space before and after a binary operation (
+
,-
,==
,>
...). No space must be apped after(
and before)
.let myValue = 20 + (30 / 2) * 3 if 1 + 1 == 3 { /* ... */ }
-
8 - Always follow the Xcode's recommended rules about indentation style (basically your code should not change if you force indentation using CTRL-I shortcut). When declaring a function that span multiple lines prefer the style used by Xcode:
// Xcode indentation for a function declaration that spans multiple lines func myFunction(parameterOne: String, parameterTwo: String, parameterThree: String) { // Xcode indents to here for this kind of statement print("\(parameterOne) \(parameterTwo) \(parameterThree)") }
// Xcode indentation for a multi-line `if` statement if myFirstValue > (mySecondValue + myThirdValue) && myFourthValue == .someEnumValue { // Xcode indents to here for this kind of statement print("Hello, World!") }
-
9 - When calling a function with many parameters (or with a long line), put each argument on a separate line with a single extra indentation.
myAwesomeFunctionWithLotsOfArgs( firstArgument: "Hello, I am a string", secondArgument: "Test", thirdArgument: 2)
-
10 - When dealing with
Array
orDictionary
with a large amount of elements consider splitting it in multiple lines and treat the[
and]
as if they were braces in a method,if
statement, etc (same for Closures).someFunctionWithABunchOfArguments( someStringArgument: "hello I am a string", someArrayArgument: [ "dadada daaaa daaaa dadada daaaa daaaa dadada daaaa daaaa", "string one is crazy - what is it thinking?" ], someDictionaryArgument: [ "dictionary key 1": "some value 1, but also some more text here", "dictionary key 2": "some value 2" ], someClosure: { parameter1 in print(parameter1) })
-
11 - For empty arrays and dictionaries, prefer type annotation. (For an array or dictionary assigned to a large, multi-line literal, use type annotation.)
// PREFERRED var names: [String] = [] var lookup: [String: Int] = [:] // NOT PREFERRED var names = [String]() var lookup = [String: Int]()
-
12 - Prefer using local constants to avoid multi-line predicates if possible.
Use:
let firstCondition = x == firstReallyReallyLongPredicateFunction() let secondCondition = y == secondReallyReallyLongPredicateFunction() let thirdCondition = z == thirdReallyReallyLongPredicateFunction() if firstCondition && secondCondition && thirdCondition { // do something }
Instead of:
if x == firstReallyReallyLongPredicateFunction() && y == secondReallyReallyLongPredicateFunction() && z == thirdReallyReallyLongPredicateFunction() { // do something }
-
13 - Avoid parenthesis in control flows, in Swift standard they're not necessary:
// PREFERRED if x == y { /* ... */ } // NOT PREFERRED if (x == y) { /* ... */ }
-
14 - There should one blank line between methods. This aid visual clarity and organization of the code. Inside a method/function whitespace should separate functionality; if you have too much sections separated by space often it means you should refactor into several different methods (separation of concerns).
-
15 - Hide non-shared, implementation details inside the extension using
private
access control. -
16 - Free functions (not attached to a class or type) should be used sparingly. When possible, prefer to use a method instead of a free function. This aids in readability and discoverability. You can also extend primary types if acceptable. Free functions are most appropriate when they aren't associated with any particular type or instance (generics in Swift).
-
17 - Do not use semicolons; Swift does not require a semicolon after each statement in your code. They are only required if you wish to combine multiple statements on a single line. Never write multiple statements on a single line separated with semicolons.
-
18 - Do not use emoji in your code: it's an unnecessary source of friction and it doesn't add to the learning and it interrupts the coding flow.
-
19 - Consider organizing your code by separating method/property/class using
// MARK:
.