Skip to content
Aditya Trivedi edited this page Apr 10, 2017 · 106 revisions

Naming

Whitespace

Length

Others

Total: 31


class, enum, struct, and protocol names should follow UpperCamelCase naming convention : several words are joined together, and the first letter of every word is capitalized.

Class names

Preferred

class SomeClass {
	// class definition goes here
}

class SomeClass : SomeSuperClass {
	// class definition goes here
}

Not Preferred

class invalidClassName {
	// class definition goes here
}

class inval1dCla$$Name : SomeSuperClass {
	// class definition goes here
}

Enumeration types

Preferred

enum SomeEnumeration {
	// enumeration definition goes here
}

Not Preferred

enum S0me_Enumer4t!on {
	// enumeration definition goes here
}

Struct names

Preferred

struct SomeStructure {
	// structure definition goes here
}

Not Preferred

struct Some-Structure {
	// structure definition goes here
}

Protocol names

Preferred

protocol SomeProtocol {
	// protocol definition goes here
}

Not Preferred

protocol someprotocol {
	// protocol definition goes here
}

method, var, and enum value names should follow lowerCamelCase naming convention: first letter of the entire word is lowercase, but subsequent first letters are uppercase.

Method and selector names

Preferred

func someMethod() {
	// method definition goes here
}

Not Preferred

func some-method() {
	// method definition goes here
}

Variable names

Preferred

var someVariable = someValue

Not Preferred

var Some_Var1able = someValue

Enumeration values

Preferred

enum CompassPoint {
	case north
	case south
	case east
	case west
}

Not Preferred

enum CompassPoint {
	case N0rth
	case Sou-th
	case East
	case WEST
}

Global constants should follow either UpperCamelCase or lowerCamelCase naming conventions. Local constants should follow lowerCamelCase naming conventions.

Preferred

let MaxHeight = 42
let maxHeight = 42

Not Preferred

let max_height = 42

Flag "k-prefixed" constants.

Preferred

let maxHeight = 42
let MaxHeight = 42

Not Preferred

let kMaxHeight = 42

Prefer a single space before and after '->'.

Function and Closure declarations

Preferred

func onePlusTwo() -> Int {
  return 1 + 2
}

names.map() {
  (name) -> Int in
  return 1
}

Not Preferred

func onePlusTwo()->Int {
  return 1 + 2
}

names.map() {
  (name)  ->  Int in
  return 1
}

class SomeClass: SomeSuperClass{
}

Subscript declarations

Preferred

struct TimesTable {
    let multiplier: Int

    subscript(index: Int) -> Int {
        return multiplier * index
    }
}

Not Preferred

struct TimesTable {
    let multiplier: Int

    subscript(index: Int)-> Int {
        return multiplier * index
    }
}

struct SomeStruct : SomeParentStruct   {
}

Function Types

Preferred

func something() -> (Int, Int) -> (Int) {
  // do something
}

Not Preferred

func something() -> (Int, Int)-> (Int) {
  // do something
}

func something() -> (Int, Int)  -> (Int){
  // do something
}

There should be no whitespace immediately before/after an opening chevron < and before the closing chevron >.

Generics

Preferred

func simpleMax<T: Comparable>(x: T, _ y: T) -> T {
    if x < y {
        return y
    }
    return x
}

Not Preferred

func simpleMax < T: Comparable >(x: T, _ y: T) -> T {
    if x < y {
        return y
    }
    return x
}

Requirement list

Preferred

func allItemsMatch<
    C1: Container, C2: Container
    where C1.ItemType == C2.ItemType, C1.ItemType: Equatable>
    (someContainer: C1, _ anotherContainer: C2) -> Bool {}

Not Preferred

func allItemsMatch <
    C1: Container, C2: Container
    where C1.ItemType == C2.ItemType, C1.ItemType: Equatable >
    (someContainer: C1, _ anotherContainer: C2) -> Bool {}

Operator Declarations

An exception to this rule is made for operator declarations. The opening angle bracket (if used) in an operator declaration must have a single space preceding it.

Preferred

func ++< <T where T: Comparable>(op1: T, op2: T) -> Bool {
}

Not Preferred

func ++<<T where T: Comparable>(op1: T, op2: T) -> Bool {
}

There should be no whitespace preceding the colon, exactly one whitespace after the colon for:

However, for conditional expressions there should be a single whitespace before and after the colon.

Variable declarations

Preferred

var x: Int = 2

Not Preferred

var x : Int
var y:   String

Dictionary literals and types

Preferred

var x = [ 'key1': 1, 'key2': 2 ]
var y: [ Int: String ]

Not Preferred

var x = [ 'key1' : 1, 'key2':  3]
var y: [ Int :    String ]

Case statements

Preferred

switch character {
case "a": doSomething(a);
default: alert();
}

Not Preferred

switch character {
case "a" : doSomething(a);
default:     alert();
}

Class, Struct, Protocol, and Extension declarations

Preferred

class ClassName: BaseClass {
}

struct StructName: BaseStruct {
}

protocol ProtocolName: AnotherProtocol {
}

extension TypeName: ProtocolName {
}

Not Preferred

class ClassName : BaseClass {
}

struct StructName:  BaseStruct {
}

protocol ProtocolName:AnotherProtocol {
}

extension TypeName : ProtocolName {
}

Tuple declarations

Preferred

var y = (key: 1, value: 2)

Not Preferred

var y = (key:1, value : 2)

Function declarations

Preferred

func someFunction<T: SomeClass, U: SomeProtocol>(someT: T, someU: U) {
}

Not Preferred

func someFunction<T : SomeClass, U:SomeProtocol>(someT: T, someU: U) {
}

Conditional expressions

Preferred

var x = condition ? a : b

Not Preferred

var x = condition ? a: b
var x = condition ? a   : b

Prefer no spaces before and exactly one space after a comma (',') in the following structures:

  • Generics
  • Type Inheritance Clauses
  • Condition Clauses
  • Availability Arguments
  • Generic Argument Lists
  • Pattern Initializer Lists
  • Parameter Lists
  • Enum Case Lists
  • Tuple Pattern Lists
  • Tuple Type Lists
  • Expression Lists
  • Array Literal Items
  • Dictionary Literal Items
  • Capture List Items
  • Paranthesized Expressions
  • Identifier Lists
  • Switch Case Item Lists

Preferred

func someFunction<T: SomeClass, U: SomeProtocol>(someT: T, someU: U) {
    // function body goes here
}

func someFunction<T: SomeClass, U: SomeProtocol,
	V: AnotherClass>(someT: T, someU: U) {
    // function body goes here
}

class Bicycle: Vehicle, TwoWheeler {
    var hasBasket = false
}

if x < 2, var y = val {
    println(x + y)
}

if let roomCount = john.residence?.numberOfRooms, roomCountTwo = john.residence?.numberOfRooms {
    println("John's residence has \(roomCount) room(s).")
}

if #available(iOS 9, OSX 10.10, *) {
    // Use iOS 9 APIs on iOS, and use OS X v10.10 APIs on OS X
}

struct Dictionary<Key: Hashable, Value>: CollectionType {}

let numX = 2, func_y = { x in println(x) }

func initialize(x: Int, y: Int, z: Int) {}

enum Planet {
    case Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}

enum ASCIIControlCharacter: Character {
    case Tab = "\t", LineFeed = "\n"
    case CarriageReturn = "\r"
}

var (x, y): (Int, Int)

for (i = 0, j = n - 1; i < n && j >= 0; i++, j--) {
  println(mat[i][j])
}

shoppingList += ["Chocolate Spread", "Cheese", "Butter"]

var airports: [String: String] = ["YYZ": "Toronto Pearson", "DUB": "Dublin"]

lazy var someClosure: Void -> String = {
    [unowned self, weak delegate = self.delegate!] in
    // closure body goes here
}

var arr = [ (1, 2, 3), (3, 4, 5) ]

reversed = names.sort( { s1, s2 in s1 > s2 } )

switch character {
case "a", "e", "i", "o", "u", " ": continue
default: puzzleOutput.append(character)
}

Not Preferred

func someFunction<T: SomeClass,U: SomeProtocol>(someT: T, someU: U) {
    // function body goes here
}

func someFunction<T: SomeClass , U: SomeProtocol>(someT: T, someU: U) {
    // function body goes here
}

class Bicycle: Vehicle,  TwoWheeler {
    var hasBasket = false
}

if x < 2 , var y = val {
    println(x + y)
}

if let roomCount = john.residence?.numberOfRooms,roomCountTwo = john.residence?.numberOfRooms {
    println("John's residence has \(roomCount) room(s).")
}

if #available(iOS 9, OSX 10.10,*) {
    // Use iOS 9 APIs on iOS, and use OS X v10.10 APIs on OS X
}

struct Dictionary<Key: Hashable,   Value>: CollectionType {}

let numX = 2 , func_y = { x in println(x) }

func initialize(x: Int,y: Int,z: Int) {}

enum Planet {
    case Mercury,Venus, Earth, Mars,  Jupiter, Saturn, Uranus, Neptune
}

enum ASCIIControlCharacter: Character {
    case Tab = "\t" , LineFeed = "\n"
    case CarriageReturn = "\r"
}

var (x,y): (Int , Int)

for (i = 0,j = n - 1; i < n && j >= 0; i++,j--) {
  println(mat[i][j])
}

shoppingList += ["Chocolate Spread" , "Cheese",  "Butter"]

var airports: [String: String] = ["YYZ": "Toronto Pearson","DUB": "Dublin"]

lazy var someClosure: Void -> String = {
    [unowned self , weak delegate = self.delegate!] in
    // closure body goes here
}

var arr = [ (1,2, 3), (3 , 4, 5) ]

reversed = names.sort( { s1,s2 in s1 > s2 } )

switch character {
case "a" , "e",  "i","o", "u", " ": continue
default: puzzleOutput.append(character)
}

Prefer single space around operator in operator declarations.

Preferred

infix operator -+* { precedence 70 associativity right }

Not Preferred

infix operator-+* { precedence 70 associativity right }

infix operator -+*  { precedence 70 associativity right }

infix operator -+*{ precedence 70 associativity right }

infix operator  -+* { precedence 70 associativity right }

Verify that source files begin with a non-whitespace character.

Preferred

1 import Foundation

Not Preferred

1 ¬
2 import Foundation
1 ••import Foundation

Verify that source files terminate with exactly one \n character. This ensures that the last line of the file is valid according to the POSIX standard. Also see No Newline at End of File for more information.

Swift source files should terminate with exactly 1 \n character, not 0 nor more than 1.

Preferred

let myConstant = 42¬
<EOF>

Not Preferred

let myConstant = 42<EOF>
let myConstant = 42¬
¬
¬
<EOF>

There should be no whitespace immediately before/after an opening parenthesis ( and before the closing parenthesis ).

Functions

Preferred

func sum(a: Int, b: Int) -> Int {
  return a + b;
}

print("Hello, World!")

Not Preferred

func sum ( a: Int, b: Int ) -> Int {
  return a + b;
}

print( "Hello, World!" )

Tuples

Preferred

let tuple = (5, 2)

Not Preferred

let tuple = ( 5, 2 )

Conditionals

Preferred

if (someCondition) {
  ...
}

Not Preferred

if ( someCondition ) {
  ...
}

Initializers

Preferred

class SomeClass {
  init() {
  }
}

Not Preferred

class SomeClass {
  init ( ) {
  }
}

Flag whitespace after the last non-whitespace character on each line until the newline.

Preferred

let number = 42¬

Not Preferred

let number = 42••¬

Prefer at least one whitespace character after a comment opening symbol (//, ///, /*, or /**) and at least one whitespace character before a comment closing symbol (*/).

Preferred

// This is a comment

/// This is a documentation comment

/* This is a
multi-line comment */

/* This is a
multi-line comment
*/

/** This is a 
documentation multi-line
comment
*/

Not Preferred

//This is a comment

///This is a documentation comment

/*This is a
multi-line comment*/

/**This is a multi-line
documentation comment */

Every function and method declaration should have one blank line before and after itself. An exception to this rule are functions that are declared at the start of a file (only need one blank line after their declaration) or at the end of a file (only need one blank line before their declaration). Comments immediately before a function declaration (no blank lines between them and the function) are considered to be part of the declaration.

Preferred

func function1() {
  var text = 1
  var text = 2
}

function1()

// a comment
func function2() {
  // something goes here
}

struct SomeStruct {

  func function3() {
    // something goes here
  }

  func function4() {
    // something else goes here
  };

}

func function5() {
  // something goes here
}

Not Preferred

func function1() {
  var text = 1
  var text = 2
}
function1()
// a comment
func function2() {
  // something goes here
}

struct SomeStruct {
  func function3() {
    // something goes here
  }

  func function4() {
    // something else goes here
  };
}
func function5() {
  // something goes here
}

Enforce a line limit on the lengths of class bodies.

tailor [--max-class-length <x>]

For example, limiting classes to 2 lines would trigger a violation for the following 3 line class:

1 class ThreeLineClass {
2     // This class spans from lines 1-4.
3
4 }

Enforce a line limit on the lengths of closure bodies.

tailor [--max-closure-length <x>]

For example, limiting closures to 2 lines would trigger a violation for the following 3 line closure:

1 reversed = names.sort({ (s1: String, s2: String) -> Bool in
2     // This closure spans from lines 1-4.
3     return s1 > s2
4 })

Enforce a line limit on the length of each file.

tailor [--max-file-length <x>]

For example, limiting files to 2 lines would trigger a violation for the following 3 line file:

1 let myHello = "Hello,"
2 let myWorld = " world!"
3 println(myHello + myWorld)

Enforce a line limit on the lengths of function bodies.

tailor [--max-function-length <x>]

For example, limiting functions to 2 lines would trigger a violation for the following 3 line function:

1 func helloWorld() {
2     // This function spans from lines 1-4.
3     println("Hello, world!")
4 }

Enforce a line limit on the lengths of struct bodies.

tailor [--max-struct-length <x>]

For example, limiting structs to 2 lines would trigger a violation for the following 3 line struct:

1 struct ThreeLineStruct {
2     // This struct spans from lines 1-4.
3
4 }

Enforce a character limit on the length of each line.

tailor [-l <x>|--max-line-length <x>]

For example, limiting lines to 10 characters would trigger a violation for the following 14 character line:

let hello = 42

Enforce a character limit on the maximum length of each construct name for classes, enums, enumcases, structs, protocols, elements, functions, labels, setters, typealiases, types, variables, and constants.

tailor [--max-name-length <x>]

For example, limiting names to 10 characters would trigger a violation for the following 12 character constant name:

let my12CharName = 42

Enforce a character limit on the minimum length of each construct name for classes, enums, enumcases, structs, protocols, elements, functions, labels, setters, typealiases, types, variables, and constants.

tailor [--min-name-length <x>]

For example, limiting names to at least 3 characters would trigger a violation for the following single character constant name:

let a = 42

Control flow constructs (if, else if, switch, for, while, repeat-while, and guard statements), Exception handling constructs (throw, and do/catch statements), and Initializers (array, dictionary, initializer patterns) should not be enclosed in parentheses.

Additionally, method calls with no parameters and a trailing closure should not have empty parentheses following the method name.

Control flow constructs

  • if, else if statement

Preferred

if SomeCondition {

} else if SomeOtherCondition {
}

Not Preferred

if (SomeCondition) {

} else if (SomeOtherCondition) {
}
  • switch statement

Preferred

switch SomeData {
	default:
		break
}

Not Preferred

switch (SomeData) {
	default:
		break
}
  • for loop

Preferred

for var i = 0; i < 10; i+=1 {

}

Not Preferred

for (var i = 0; i < 10; i+=1) {

}
  • while loop

Preferred

while SomeCondition {

}

Not Preferred

while (SomeCondition) {

}
  • repeat-while loop

Preferred

repeat {

} while SomeCondition

Not Preferred

repeat {

} while (SomeCondition)
  • guard clause

Preferred

guard true else {   }

Not Preferred

guard (true) else {   }

Exception handling constructs

  • do/catch statement

Preferred

do  {

} catch SomeException {

}

Not Preferred

do  {

} catch (SomeException) {

}
  • throw statement

Preferred

throw SomeException

Not Preferred

throw (SomeException)

Initializers

  • array items

Preferred

var shoppingList: [String] = ["Eggs", "Milk"]

Not Preferred

var shoppingList: [String] = [("Eggs"), ("Milk")]
  • dictionary items

Preferred

var airports: [String: String] = ["YYZ": "Toronto Pearson", "DUB": "Dublin"]

Not Preferred

var airports: [String: String] = [("YYZ"): ("Toronto Pearson"), ("DUB"): ("Dublin")]
  • initializer patterns

Preferred

var x: Int = 2
var y: String = "Sleekbyte"
var x = 2

Not Preferred

var x: Int = (2)
var y: String = ("Sleekbyte")
var x = (2)

Method calls

Preferred

items.map {
  item in item.transform()
}

Not Preferred

items.map() {
  item in item.transform()
}

Definitions of

should follow the One True Brace Style (1TBS): each construct has its opening brace one the same line along with the same indentation level as its header, the statements within the braces are indented, and the closing brace at the end is on the same indentation level as the header of the function at a line of its own. Braces are not omitted for a control statement with only a single statement in its scope. Every opening brace must also have one space preceding it.

Classes

Preferred

class SomeClass {
}

class SomeClass: SomeSuperClass {
}

Not Preferred

class SomeClass
{
}

class SomeClass: SomeSuperClass{
}

Structs

Preferred

struct SomeStruct {
}

struct SomeStruct : SomeParentStruct {
}

Not Preferred

struct SomeStruct
{
}

struct SomeStruct : SomeParentStruct  {
}

Functions

Preferred

func someMethod() {
}

func someOtherFunction () -> () {
}

Not Preferred

func someMethod()
{
}

func someOtherFunction () -> ()
{
}

Control flow constructs

  • if, else if, and else statement

Preferred

if SomeCondition {

} else if someOtherCondition {
} else {
}

Not Preferred

if SomeCondition
{

}
else if someOtherCondition
{
}
else
{
}
  • switch statement

Preferred

switch SomeData {
	default:
		break
}

Not Preferred

switch SomeData
{
	default:
		break
}
  • for loop

Preferred

for var i = 0; i < 10; i+=1 {

}

Not Preferred

for var i = 0; i < 10; i+=1
{

}
  • while loop

Preferred

while SomeCondition {

}

Not Preferred

while SomeCondition
{

}
  • repeat-while loop

Preferred

repeat {

} while SomeCondition

Not Preferred

repeat
{

} while SomeCondition

Initializers

Preferred

init(someParameter:Double, someOtherParameter:Double) {
   self.someMember = someParameter
   self.someOtherMember = someOtherParameter
}

Not Preferred

init(someParameter:Double, someOtherParameter:Double)
{
   self.someMember = someParameter
   self.someOtherMember = someOtherParameter
}

Protocols

Preferred

protocol SomeProtocol {

}

protocol SomeOtherProtocol : X {

}

Not Preferred

protocol SomeProtocol
{

}

protocol SomeOtherProtocol : X
{
}

Enums

Preferred

enum SomeEnum {
    case A, B, C, D
}

enum SomeEnum {
    case A
    case B
    case C
    case D
}

enum SomeEnum: Int {
    case A, B, C = 5, D
}

Not Preferred

enum SomeEnum
{
    case A, B, C, D
}

enum SomeEnum
{
    case A
    case B
    case C
    case D
}

enum SomeEnum: Int
{
    case A, B, C = 5, D
}

Closures

Preferred

func someFunction () -> () {
// closure
}

Not Preferred

func someFunction () -> ()
{
// closure
}

Setters and Getters

  • set

Preferred

set {
    oldValue = newValue / 2
}

Not Preferred

set
{
    oldValue = newValue / 2
}
  • get

Preferred

get {
    return value * 2
}

Not Preferred

get
{
    return value * 2
}

Extensions

Preferred

extension someExtension {
}

Not Preferred

extension someExtension
{
}

Avoid using the forced form of the type cast operator (as!) because Swift is not able to determine at compile time if the type conversion will succeed. In the event of an unsuccessful conversion, a runtime error will be triggered. The conditional form of the type cast operator (as?) is safer and should be used when possible.

Preferred

if let movie = item as? Movie {
    print("Movie: '\(movie.name)', dir. \(movie.director)")
}

Not Preferred

let movie = item as! Movie
print("Movie: '\(movie.name)', dir. \(movie.director)")

Multiple import statements should not be defined on a single line.

Preferred

import Foundation
import Cocoa

Not Preferred

import Foundation; import Cocoa

Swift does not require a semicolon after each statement in your code unless you wish to combine multiple statements on a single line. Do not write multiple statements on a single line separated with semicolons.

Imports

Preferred

import Foundation

Not Preferred

import Foundation;

Enums and enum cases

Preferred

enum CompassPoint {
	case North
	case South
	case East
	case West
}

Not Preferred

enum CompassPoint {
	case North;
	case South;
	case East;
	case West;
};

Protocols

Preferred

protocol SomeProtocol {
	var SomeMethod: String { get }
	func SomeMethod()
	func SomeMethod(f: Int)
	func SomeMethod(bar: String, baz: Double)
}

Not Preferred

protocol SomeProtocol {
	var SomeMethod: String { get };
	func SomeMethod();
	func SomeMethod(f: Int);
	func SomeMethod(bar: String, baz: Double);
};

Extensions

Preferred

extension SomeType {

}

Not Preferred

extension SomeType {

};

Structs

Preferred

struct DemoStruct {
        var x: String // variables
}

Not Preferred

struct DemoStruct {
        var x: String // variables
};

Classes

Preferred

class SomeClass {
	let b = 2 // constants
}

Not Preferred

class SomeClass {
	let b = 2 // constants
};

Loops

Preferred

// while loop
while true {

}

// for loop
for ; ; {
}

// repeat while
repeat {

} while true

Not Preferred

// while loop
while true {

};

// for loop
for ; ; {
};

// repeat while
repeat {

} while true;

TODO comments should be defined separately using non-nested single line comments. They should adhere to the <TODO: description> or <TODO(developer-name): description> syntax. Empty TODO comments will be flagged.

Preferred

// TODO: <insert mandatory todo comment>
// TODO(dev-name): <insert mandatory todo comment>

Not Preferred

// TODO:

/// TODO: Documentation comments should not have TODOs

//// TODO: Nested comments should not have TODOs

// //TODO: Nested comments should not have TODOs

// TODO: Nested comments should not have TODOs // some comment

//// TODO: Nested comments should not have TODOs

Optional binding lists should not have consecutive var/let bindings. All constants must be preceded by at most one let binding. All variables must be preceded by only one var binding.

Preferred

if var a = a, b = b, c = c where c != 0 {
    print("(a + b) / c = \((a + b) / c)")     // (a + b) / c = 5
}

if let a = a, b = b, var c = c where c != 0 {
    print("(a + b) / c = \((a + b) / c)")     // (a + b) / c = 5
}

Not Preferred

if var a = a, var b = b, var c = c where c != 0 {
    print("(a + b) / c = \((a + b) / c)")     // (a + b) / c = 5
}

if let a = a, let b = b, var c = c where c != 0 {
    print("(a + b) / c = \((a + b) / c)")     // (a + b) / c = 5
}

Closures that are the last argument of a function should be passed into the function using trailing closure syntax.

Preferred

reversed = names.sort { s1, s2 in return s1 > s2 }

Not Preferred

reversed = names.sort({ s1, s2 in return s1 > s2 })
Clone this wiki locally