_ = `self` // Learning swift style guide.
- Arrow Whitespace
- Angle Bracket Whitespace
- Colon Whitespace
- Comma Whitespace
- Operator Whitespace (only in operator declarations)
- Leading Whitespace
- Parentheses Whitespace
- Trailing Whitespace
- Comment Whitespace
- Function Whitespace
- Indentation style
- Redundant Parentheses
- Force Casts
- Multiple Imports
- Terminating Semicolon
- TODO Syntax
- Redundant Optional Binding
- Trailing Closure
class
, protocol
, struct
, and enum
names should follow PascalCase naming conventions.
Preferred
class OneClass {
// do something interesting for this class
}
class SubClass : SuperClass {
// do something interesting for this class
}
Not Preferred
class invalidClassName {
// do something interesting for this class
}
class inval1dCla$$Name : SuperClass {
// do something interesting for this class
}
Preferred
enum OneEnumeration {
// do something interesting for this enumeration
}
Not Preferred
enum oTHEr_Enumeration {
// do something interesting for this enumeration
}
enum nextEnumeratioN {
// do something interesting for this enumeration
}
enum One-Enumeration {
// do something interesting for this enumeration
}
Preferred
struct OneStructure {
// do something interesting for this structure
}
Not Preferred
struct One-Structure {
// do something interesting for this structure
}
Preferred
protocol OneProtocol {
// do something interesting for this protocol
}
Not Preferred
protocol oneProtocol {
// do something interesting for this protocol
}
methods
, variables
, and enum values
names should follow CamelCase naming conventions
Preferred
func oneMethod() {
// show your hard work in definition
}
Not Preferred
func one-method() {
// show your hard work in definition
}
func SecondMethod() {
// show your hard work in definition
}
func Method() {
// show your hard work in definition
}
Preferred
var lastName = "Utsav"
Not Preferred
var last_name = "wrong"
var lastname = "also wrong"
var LastName = "another wrong"
Preferred
enum Direction {
case north
case south
case east
case west
}
Not Preferred
enum Direction {
case N0rth
case Sou-th
case East
case WEST
}
// Not Preferred in latest swift version
enum Direction {
case North
case South
case East
case West
}
Global Constants
should follow either PascalCase naming conventions or CamelCase naming conventions.
Local constants
should follow either PascalCase naming conventions or CamelCase naming conventions.
Preferred
let MaxHeight = 42
let maxHeight = 42
let defaultValue = 100
Not Preferred
let max_height = 42
let kMaxHeight = 42
let MAXHEIGHT = 42
let DEFAULTVALUE = 1000
Single space prefer @before and @after '->' to ' -> '.
Examples:
Preferred
func loginCheck() -> Int {
return 1 + 2
}
list.map() {
(name) -> Int in
return 1
}
class SomeClass: SomeSuperClass {
// something goes here
}
Not Preferred
func loginCheck()->Int {
return 1 + 2
}
list.map() {
(name) -> Int in
return 1
}
class SomeClass: SomeSuperClass{
}
Preferred
struct User {
let multiplier: Int
subscript(index: Int) -> Int {
return multiplier * index
}
// do something interesting
}
Not Preferred
struct User {
let multiplier: Int
subscript(index: Int)-> Int {
return multiplier * index
}
// do something interesting
}
struct SomeStruct : SomeParentStruct {
}
Preferred
func sumOfTwo()) -> (Int, Int) -> (Int) {
// do something interesting
}
Not Preferred
func sumOfTwo() -> (Int, Int)-> (Int) {
// do something interesting
}
func sumOfTwo() -> (Int, Int) -> (Int){
// do something interesting
}
There should be no whitespace @before or @after an opening chevron <
and before the closing chevron >
.
Examples:
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
}
In some case required space while using opening angle bracket. The opening angle bracket (if used) in an operator declaration must have a single space preceding it.
Example:
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:
class
,var
,struct
,protocol
,extension
,func
, andtuple
declarationsdict
literals and typescase
statements
However Exception is for conditional expressions there should be a single whitespace @before and @after the colon.
Preferred
var x: Int = 2
Not Preferred
var x : Int
var success: Bool
Preferred
var x = [ "index": 1, "index": 2 ]
var y: [ Int: String ]
Not Preferred
var x = [ "index" : 1, "index": 2]
var y: [ Int : String ]
Preferred
switch character {
case "a":
print(a)
default:
alert()
}
Not Preferred
switch character {
case "a" :
print(a)
default :
alert()
}
Preferred
class SubClass: BaseClass {
// do something interesting
}
struct SubStruct: BaseStruct {
// do something interesting
}
protocol SubProtocol: BaseProtocol {
// do something interesting
}
extension BaseClass: BaseProtocol {
// do something interesting
}
Not Preferred
class SubClass : BaseClass {
// do something interesting
}
struct SubStruct: BaseStruct {
// do something interesting
}
protocol SubProtocol:AnotherProtocol {
// do something interesting
}
extension BaseClass : BaseProtocol {
// do something interesting
}
Preferred
var someTuple = (top: 10, bottom: 12)
Not Preferred
var someTuple = (top:10, bottom : 12)
Preferred
func someFunction<T: SomeClass, U: SomeProtocol>(someT: T, someU: U) {
}
Not Preferred
func someFunction<T : SomeClass, U:SomeProtocol>(someT: T, someU: U) {
}
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 (',' to ', ') in the following structures:
- Generics
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
}
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
}
- Type Inheritance Clauses
Preferred
class Bicycle: Vehicle, TwoWheeler {
var hasBasket = false
}
Not Preferred
class Bicycle: Vehicle, TwoWheeler {
var hasBasket = false
}
- Condition Clauses
Preferred
if x < 2,
var y = val {
println(x + y)
}
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).")
}
Not Preferred
if x < 2 , var y = val {
println(x + y)
}
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).")
}
- Availability Arguments
Preferred
if #available(iOS 9, OSX 10.10, *) {
// Use iOS 9 APIs on iOS, and use OS X v10.10 APIs on OS X
}
Not Preferred
if #available(iOS 9, OSX 10.10,*) {
// Use iOS 9 APIs on iOS, and use OS X v10.10 APIs on OS X
}
- Generic Argument Lists
Preferred
struct Dictionary<Key: Hashable, Value>: CollectionType {}
Not Preferred
struct Dictionary<Key: Hashable, Value>: CollectionType {}
- Pattern Initializer Lists
Preferred
let numX = 2, func_y = { x in println(x) }
Not Preferred
let numX = 2 , func_y = { x in println(x) }
- Parameter Lists
Preferred
func initialize(x: Int, y: Int, z: Int) {}
Not Preferred
func initialize(x: Int,y: Int,z: Int) {}
- Enum Case Lists
Preferred
enum Planet {
case Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}
enum Planet : Int {
case Mercury = 0, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}
Not Preferred
enum Planet {
case Mercury,Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}
enum Planet {
case Mercury = 0 ,Venus = 1,Earth = 2, Mars = 4, Jupiter= 5, Saturn = 6, Uranus= 7, Neptune= 9
}
- Tuple Pattern Lists
Preferred
var (x, y): (Int, Int)
Not Preferred
var (x,y): (Int , Int)
- Array Literal Items
Preferred
shoppingList += ["Chocolate Spread", "Cheese", "Butter"]
Not Preferred
shoppingList += ["Chocolate Spread" , "Cheese", "Butter"]
- Dictionary Literal Items
Preferred
var airports: [String: String] = ["YYZ": "Toronto Pearson", "DUB": "Dublin"]
Not Preferred
var airports: [String: String] = ["YYZ": "Toronto Pearson","DUB": "Dublin"]
- Capture List Items
Preferred
lazy var someClosure: Void -> String = {
[unowned self, weak delegate = self.delegate!] in
// closure body goes here
}
Not Preferred
lazy var someClosure: Void -> String = {
[unowned self , weak delegate = self.delegate!] in
// closure body goes here
}
- Paranthesized Expressions
Preferred
var arr = [ (1, 2, 3), (3, 4, 5) ]
Not Preferred
var arr = [ (1,2, 3), (3 , 4, 5) ]
- Switch Case Item Lists
Preferred
switch character {
case "a", "e", "i", "o", "u":
continue
default:
print(character)
}
Not Preferred
switch character {
case "a","e","i","o", "u":
continue
default:
print(character)
}
Single space at both side of 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 }
Check that source files begin with a non-whitespace character or blank line.
Preferred
1 //
2 // FileName.swift
3 // ProjectName
4 //
5 // Copyright information....
6 //
.
.
.
12 import Foundation
1 import Foundation
2 import UIKit
Not Preferred
1 ¬
2 import Foundation
1 import Foundation
There should be no whitespace immediately before/after an opening parenthesis (
and before the closing parenthesis )
.
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!" )
Preferred
let tuple = (5, 2)
Not Preferred
let tuple = ( 5, 2 )
Preferred
if (someCondition) {
...
}
Not Preferred
if ( someCondition ) {
...
}
Preferred
class SomeClass {
init() {
}
}
Not Preferred
class SomeClass {
init ( ) {
}
}
remove whitespace after the last non-whitespace character on each line until the newline.
Preferred
let number = 42¬
Not Preferred
let number = 42 ¬
print("Hello white space") ¬
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 line
/// This is a documentation comment line
/* This is a
multi-line comments */
/* This is a
multi-line comments
*/
/** This is a
documentation multi-line
comments
*/
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 1 blank line before and after itself. in exception if function is start of a file.
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
}
Definitions of
init
, class
, enum
, struct
, function
, protocol
, extension
, closure
, Getters and Setters (set
, get
), Control flow constructs (if
, else if
, else
, switch
, for
, while
, repeat-while
)
Opening curly braces go on the same line as the corresponding statement, separated by a space. and closing brace at the end is on the same indentation level as the header of the function at a line of its own.
Examples:
Preferred
init(name: String) {
self.name = name
}
Not Preferred
init(name: String)
{
self.name = name
}
Preferred
class OneClass {
}
class OneClass: SuperClass {
}
Not Preferred
class OneClass
{
}
class OneClass: SuperClass{
}
Preferred
struct OneStruct {
}
struct OneStruct : SuperStruct {
}
Not Preferred
struct OneStruct
{
}
struct OneStruct : SuperStruct {
}
Preferred
func callMe() {
}
func isOk () -> Bool {
}
Not Preferred
func callMe()
{
}
func isOk () -> Bool
{
}
- if, else if, and else statement
Preferred
if i > 2 {
} else if i < 10 {
} else {
}
Not Preferred
if i > 2
{
}
else if i < 10
{
}
else
{
}
- switch statement
Preferred
switch character {
case "a", "e", "i", "o", "u":
continue
default:
print(character)
}
Not Preferred
switch character
{
case "a", "e", "i", "o", "u":
continue
default:
print(character)
}
- for loop
Preferred
for name in names {
}
Not Preferred
for name in names
{
}
- while loop
Preferred
while true {
}
Not Preferred
while true
{
}
- repeat-while loop
Preferred
repeat {
} while true
Not Preferred
repeat
{
} while true
Preferred
protocol XProtocol {
}
protocol XProtocol : YProtocol {
}
Not Preferred
protocol XProtocol
{
}
protocol XProtocol : YProtocol
{
}
Preferred
enum SomeEnum {
case n, e, w, s
}
enum SomeEnum {
case n
case e
case w
case s
}
enum SomeEnum: Int {
case n, e, w = 5, s
}
Not Preferred
enum SomeEnum
{
case n, e, w, s
}
enum SomeEnum
{
case n
case e
case w
case s
}
enum SomeEnum: Int
{
case n, e, w = 5, s
}
Preferred
func closerFunc () -> () {
// closure
}
Not Preferred
func closerFunc () -> ()
{
// closure
}
- set
Preferred
var age : Double {
set {
oldValue = newValue / 2
}
}
Not Preferred
var age : Double
{
set
{
oldValue = newValue / 2
}
}
- get
Preferred
var age : Double {
get {
oldValue = newValue / 2
}
}
Not Preferred
var age : Double
{
get
{
oldValue = newValue / 2
}
}
Preferred
extension newExtension {
}
Not Preferred
extension newExtension
{
}
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.
- if, else if statement
Preferred
if i < 2 {
} else if 10 > i {
}
Not Preferred
if (i < 2) {
} else if (10 > i) {
}
- switch statement
Preferred
switch character {
case "a", "e", "i", "o", "u":
continue
default:
print(character)
}
Not Preferred
switch (character) {
case "a", "e", "i", "o", "u":
continue
default:
print(character)
}
- for loop
Preferred
for name in names {
}
Not Preferred
for (name in names) {
}
- while loop
Preferred
while true {
}
Not Preferred
while (true) {
}
- repeat-while loop
Preferred
repeat {
} while true
Not Preferred
repeat {
} while (true)
- guard clause
Preferred
guard true else { }
Not Preferred
guard (true) else { }
- do/catch statement
Preferred
do {
} catch SomeException {
}
Not Preferred
do {
} catch (SomeException) {
}
- throw statement
Preferred
throw SomeException
Not Preferred
throw (SomeException)
- array items
Preferred
var list: [String] = ["Hello", "Hi"]
Not Preferred
var list: [String] = [("Hello"), ("Hi")]
- dictionary items
Preferred
var name: [String: String] = ["first": "Utsav", "last": "Patel"]
Not Preferred
var name: [String: String] = [("first"): ("Utsav"), ("last"): ("Patel")]
- initializer patterns
Preferred
var x: Int = 2
var y: String = "Hi"
var x = 2
Not Preferred
var x: Int = (2)
var y: String = ("Hi")
var x = (2)
Preferred
items.map {
item in item.transform()
}
Not Preferred
items.map() {
item in item.transform()
}
Avoid using the forced form of the type cast operator (as!
)
Use 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 if not required.
Preferred
import Foundation
Not Preferred
import Foundation;
Preferred
enum CompassPoint {
case north
case south
case east
case west
}
enum CompassPoint {
case north, south, east, west
}
Not Preferred
enum CompassPoint {
case north;
case south;
case east;
case west;
};
enum CompassPoint {
case north, south, east, west;
};
Preferred
protocol OneProtocol {
var name: String { get }
func isProblem() -> Bool
func callMe(number: PhoneNumber)
}
Not Preferred
protocol SomeProtocol {
var name: String { get };
func isProblem() -> Bool;
func callMe(number: PhoneNumber);
};
Preferred
extension NewType {
}
Not Preferred
extension NewType {
};
Preferred
struct NewStruct {
var x: String // variables
}
Not Preferred
struct NewStruct {
var x: String // variables
};
Preferred
class NewClass {
let b = 2 // constants
}
Not Preferred
class NewClass {
let b = 2 // constants
};
Preferred
// while loop
while true {
}
// for loop
for name in names {
}
// repeat while
repeat {
} while true
Not Preferred
// while loop
while true {
};
// for loop
for name in names {
};
// 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: add todo comments
// TODO(dev-name): add todo comments
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, c != 0 {
print("(a + b) / c = \((a + b) / c)") // (a + b) / c = 5
}
if let a = a, b = b, var c = c, 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, c != 0 {
print("(a + b) / c = \((a + b) / c)") // (a + b) / c = 5
}
if let a = a, let b = b, var c = c, 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 })
SwiftyStyle welcomes contributions to our open source projects on Github.
Feel free to submit issues and enhancement requests.
Please refer to each project's style guidelines and guidelines for submitting patches and additions. In general, we follow the "fork-and-pull" Git workflow.
- Fork the repo on GitHub
- Clone the project to your own machine
- Commit changes to your own branch
- Push your work back up to your fork
- Submit a Pull request so that I can review your changes
NOTE: Be sure to merge the latest from "upstream" before making a pull request!