- andOperator
- anyObjectProtocol
- applicationMain
- assertionFailures
- blankLineAfterImports
- blankLinesAroundMark
- blankLinesAtEndOfScope
- blankLinesAtStartOfScope
- blankLinesBetweenChainedFunctions
- blankLinesBetweenScopes
- braces
- conditionalAssignment
- consecutiveBlankLines
- consecutiveSpaces
- consistentSwitchCaseSpacing
- duplicateImports
- elseOnSameLine
- emptyBraces
- enumNamespaces
- extensionAccessControl
- fileHeader
- genericExtensions
- headerFileName
- hoistAwait
- hoistPatternLet
- hoistTry
- indent
- initCoderUnavailable
- leadingDelimiters
- linebreakAtEndOfFile
- linebreaks
- modifierOrder
- numberFormatting
- opaqueGenericParameters
- preferForLoop
- preferKeyPath
- redundantBackticks
- redundantBreak
- redundantClosure
- redundantExtensionACL
- redundantFileprivate
- redundantGet
- redundantInit
- redundantInternal
- redundantLet
- redundantLetError
- redundantNilInit
- redundantObjc
- redundantOptionalBinding
- redundantParens
- redundantPattern
- redundantRawValues
- redundantReturn
- redundantSelf
- redundantStaticSelf
- redundantType
- redundantTypedThrows
- redundantVoidReturnType
- semicolons
- sortDeclarations
- sortImports
- sortTypealiases
- spaceAroundBraces
- spaceAroundBrackets
- spaceAroundComments
- spaceAroundGenerics
- spaceAroundOperators
- spaceAroundParens
- spaceInsideBraces
- spaceInsideBrackets
- spaceInsideComments
- spaceInsideGenerics
- spaceInsideParens
- strongOutlets
- strongifiedSelf
- todos
- trailingClosures
- trailingCommas
- trailingSpace
- typeSugar
- unusedArguments
- void
- wrap
- wrapArguments
- wrapAttributes
- wrapLoopBodies
- wrapMultilineStatementBraces
- wrapSingleLineComments
- yodaConditions
- acronyms
- blankLineAfterSwitchCase
- blankLinesBetweenImports
- blockComments
- docComments
- isEmpty
- markTypes
- noExplicitOwnership
- organizeDeclarations
- redundantProperty
- sortSwitchCases
- wrapConditionalBodies
- wrapEnumCases
- wrapMultilineConditionalAssignment
- wrapSwitchCases
Capitalize acronyms when the first character is capitalized.
Option | Description |
---|---|
--acronyms |
Acronyms to auto-capitalize. Defaults to "ID,URL,UUID" |
Examples
- let destinationUrl: URL
- let urlRouter: UrlRouter
- let screenId: String
- let entityUuid: UUID
+ let destinationURL: URL
+ let urlRouter: URLRouter
+ let screenID: String
+ let entityUUID: UUID
Prefer comma over &&
in if
, guard
or while
conditions.
Examples
- if true && true {
+ if true, true {
- guard true && true else {
+ guard true, true else {
- if functionReturnsBool() && true {
+ if functionReturnsBool(), true {
- if functionReturnsBool() && variable {
+ if functionReturnsBool(), variable {
Prefer AnyObject
over class
in protocol definitions.
Examples
- protocol Foo: class {}
+ protocol Foo: AnyObject {}
NOTE: The guideline to use AnyObject
instead of class
was only
introduced in Swift 4.1, so the anyObjectProtocol
rule is disabled unless the
swift version is set to 4.1 or above.
Replace obsolete @UIApplicationMain and @NSApplicationMain attributes with @main for Swift 5.3 and above.
Changes all instances of assert(false, ...) to assertionFailure(...) and precondition(false, ...) to preconditionFailure(...).
Examples
- assert(false)
+ assertionFailure()
- assert(false, "message", 2, 1)
+ assertionFailure("message", 2, 1)
- precondition(false, "message", 2, 1)
+ preconditionFailure("message", 2, 1)
Insert blank line after import statements.
Examples
import A
import B
@testable import D
+
class Foo {
// foo
}
Insert a blank line after multiline switch cases (excluding the last case, which is followed by a closing brace).
Examples
func handle(_ action: SpaceshipAction) {
switch action {
case .engageWarpDrive:
navigationComputer.destination = targetedDestination
await warpDrive.spinUp()
warpDrive.activate()
+
case let .scanPlanet(planet):
scanner.target = planet
scanner.scanAtmosphere()
scanner.scanBiosphere()
scanner.scanForArticialLife()
+
case .handleIncomingEnergyBlast:
await energyShields.prepare()
energyShields.engage()
}
}
Insert blank line before and after MARK:
comments.
Option | Description |
---|---|
--lineaftermarks |
Insert blank line after "MARK:": "true" (default) or "false" |
Examples
func foo() {
// foo
}
// MARK: bar
func bar() {
// bar
}
func foo() {
// foo
}
+
// MARK: bar
+
func bar() {
// bar
}
Remove trailing blank line at the end of a scope.
Examples
func foo() {
// foo
-
}
func foo() {
// foo
}
array = [
foo,
bar,
baz,
-
]
array = [
foo,
bar,
baz,
]
Remove leading blank line at the start of a scope.
Option | Description |
---|---|
--typeblanklines |
"remove" (default) or "preserve" blank lines from types |
Examples
func foo() {
-
// foo
}
func foo() {
// foo
}
array = [
-
foo,
bar,
baz,
]
array = [
foo,
bar,
baz,
]
Remove blank lines between chained functions but keep the linebreaks.
Remove blank lines between import statements.
Examples
import A
-
import B
import C
-
-
@testable import D
import E
Insert blank line before class, struct, enum, extension, protocol or function declarations.
Examples
func foo() {
// foo
}
func bar() {
// bar
}
var baz: Bool
var quux: Int
func foo() {
// foo
}
+
func bar() {
// bar
}
+
var baz: Bool
var quux: Int
Convert block comments to consecutive single line comments.
Examples
- /*
- * foo
- * bar
- */
+ // foo
+ // bar
- /**
- * foo
- * bar
- */
+ /// foo
+ /// bar
Wrap braces in accordance with selected style (K&R or Allman).
Option | Description |
---|---|
--allman |
Use allman indentation style: "true" or "false" (default) |
Examples
- if x
- {
// foo
}
- else
- {
// bar
}
+ if x {
// foo
}
+ else {
// bar
}
Assign properties using if / switch expressions.
Option | Description |
---|---|
--condassignment |
Use cond. assignment: "after-property" (default) or "always" |
Examples
- let foo: String
- if condition {
+ let foo = if condition {
- foo = "foo"
+ "foo"
} else {
- foo = "bar"
+ "bar"
}
- let foo: String
- switch condition {
+ let foo = switch condition {
case true:
- foo = "foo"
+ "foo"
case false:
- foo = "bar"
+ "bar"
}
// With --condassignment always (disabled by default)
- switch condition {
+ foo.bar = switch condition {
case true:
- foo.bar = "baaz"
+ "baaz"
case false:
- foo.bar = "quux"
+ "quux"
}
Replace consecutive blank lines with a single blank line.
Examples
func foo() {
let x = "bar"
-
print(x)
}
func foo() {
let x = "bar"
print(x)
}
Replace consecutive spaces with a single space.
Examples
- let foo = 5
+ let foo = 5
Ensures consistent spacing among all of the cases in a switch statement.
Examples
func handle(_ action: SpaceshipAction) {
switch action {
case .engageWarpDrive:
navigationComputer.destination = targetedDestination
await warpDrive.spinUp()
warpDrive.activate()
case .enableArtificialGravity:
artificialGravityEngine.enable(strength: .oneG)
+
case let .scanPlanet(planet):
scanner.target = planet
scanner.scanAtmosphere()
scanner.scanBiosphere()
scanner.scanForArtificialLife()
case .handleIncomingEnergyBlast:
energyShields.engage()
}
}
var name: PlanetType {
switch self {
case .mercury:
"Mercury"
-
case .venus:
"Venus"
case .earth:
"Earth"
case .mars:
"Mars"
-
case .jupiter:
"Jupiter"
case .saturn:
"Saturn"
case .uranus:
"Uranus"
case .neptune:
"Neptune"
}
Use doc comments for API declarations, otherwise use regular comments.
Option | Description |
---|---|
--doccomments |
Doc comments: "before-declarations" (default) or "preserve" |
Examples
- // A placeholder type used to demonstrate syntax rules
+ /// A placeholder type used to demonstrate syntax rules
class Foo {
- // This function doesn't really do anything
+ /// This function doesn't really do anything
func bar() {
- /// TODO: implement Foo.bar() algorithm
+ // TODO: implement Foo.bar() algorithm
}
}
Remove duplicate import statements.
Examples
import Foo
import Bar
- import Foo
import B
#if os(iOS)
import A
- import B
#endif
Place else
, catch
or while
keyword in accordance with current style (same or
next line).
Option | Description |
---|---|
--elseposition |
Placement of else/catch: "same-line" (default) or "next-line" |
--guardelse |
Guard else: "same-line", "next-line" or "auto" (default) |
Examples
if x {
// foo
- }
- else {
// bar
}
if x {
// foo
+ } else {
// bar
}
do {
// try foo
- }
- catch {
// bar
}
do {
// try foo
+ } catch {
// bar
}
repeat {
// foo
- }
- while {
// bar
}
repeat {
// foo
+ } while {
// bar
}
Remove whitespace inside empty braces.
Option | Description |
---|---|
--emptybraces |
Empty braces: "no-space" (default), "spaced" or "linebreak" |
Examples
- func foo() {
-
- }
+ func foo() {}
Convert types used for hosting only static members into enums (an empty enum is the canonical way to create a namespace in Swift as it can't be instantiated).
Option | Description |
---|---|
--enumnamespaces |
Change type to enum: "always" (default) or "structs-only" |
Configure the placement of an extension's access control keyword.
Option | Description |
---|---|
--extensionacl |
Place ACL "on-extension" (default) or "on-declarations" |
Examples
--extensionacl on-extension
(default)
- extension Foo {
- public func bar() {}
- public func baz() {}
}
+ public extension Foo {
+ func bar() {}
+ func baz() {}
}
--extensionacl on-declarations
- public extension Foo {
- func bar() {}
- func baz() {}
- internal func quux() {}
}
+ extension Foo {
+ public func bar() {}
+ public func baz() {}
+ func quux() {}
}
Use specified source file header template for all files.
Option | Description |
---|---|
--header |
Header comments: "strip", "ignore", or the text you wish use |
--dateformat |
"system" (default), "iso", "dmy", "mdy" or custom |
--timezone |
"system" (default) or a valid identifier/abbreviation |
Examples
You can use the following tokens in the text:
Token | Description |
---|---|
{file} |
File name |
{year} |
Current year |
{created} |
File creation date |
{created.year} |
File creation year |
{author} |
Name and email of the user who first committed the file |
{author.name} |
Name of the user who first committed the file |
{author.email} |
Email of the user who first committed the file |
Example:
--header \n {file}\n\n Copyright © {created.year} {author.name}.\n
- // SomeFile.swift
+ //
+ // SomeFile.swift
+ // Copyright © 2023 Tim Apple.
+ //
You can use the following built-in formats for --dateformat
:
Token | Description |
---|---|
system | Use the local system locale |
iso | ISO 8601 (yyyy-MM-dd) |
dmy | Date/Month/Year (dd/MM/yyyy) |
mdy | Month/Day/Year (MM/dd/yyyy) |
Custom formats are defined using Unicode symbols.
--dateformat iso
- // Created {created}
+ // Created 2023-08-10
--dateformat dmy
- // Created {created}
+ // Created 10/08/2023
--dateformat mdy
- // Created {created}
+ // Created 08/10/2023
--dateformat 'yyyy.MM.dd.HH.mm'
- // Created {created}
+ // Created 2023.08.10.11.00
Setting a time zone enforces consistent date formatting across environments
around the world. By default the local system locale is used and for convenience
gmt
and utc
can be used. The time zone can be further customized by
setting it to a abbreviation/time zone identifier supported by the Swift
standard library.
--dateformat 'yyyy-MM-dd HH:mm ZZZZ' --timezone utc
- // Created {created}
+ // Created 2023-08-10 11:00 GMT
--dateformat 'yyyy-MM-dd HH:mm ZZZZ' --timezone Pacific/Fiji
- // Created 2023-08-10 11:00 GMT
+ // Created 2023-08-10 23:00 GMT+12:00
Use angle brackets (extension Array<Foo>
) for generic type extensions
instead of type constraints (extension Array where Element == Foo
).
Option | Description |
---|---|
--generictypes |
Semicolon-delimited list of generic types and type parameters |
Examples
- extension Array where Element == Foo {}
- extension Optional where Wrapped == Foo {}
- extension Dictionary where Key == Foo, Value == Bar {}
- extension Collection where Element == Foo {}
+ extension Array<Foo> {}
+ extension Optional<Foo> {}
+ extension Dictionary<Key, Value> {}
+ extension Collection<Foo> {}
// With `typeSugar` also enabled:
- extension Array where Element == Foo {}
- extension Optional where Wrapped == Foo {}
- extension Dictionary where Key == Foo, Value == Bar {}
+ extension [Foo] {}
+ extension Foo? {}
+ extension [Key: Value] {}
// Also supports user-defined types!
- extension LinkedList where Element == Foo {}
- extension Reducer where
- State == FooState,
- Action == FooAction,
- Environment == FooEnvironment {}
+ extension LinkedList<Foo> {}
+ extension Reducer<FooState, FooAction, FooEnvironment> {}
Ensure file name in header comment matches the actual file name.
Move inline await
keyword(s) to start of expression.
Option | Description |
---|---|
--asynccapturing |
List of functions with async @autoclosure arguments |
Examples
- greet(await forename, await surname)
+ await greet(forename, surname)
- let foo = String(try await getFoo())
+ let foo = await String(try getFoo())
Reposition let
or var
bindings within pattern.
Option | Description |
---|---|
--patternlet |
let/var placement in patterns: "hoist" (default) or "inline" |
Examples
- (let foo, let bar) = baz()
+ let (foo, bar) = baz()
- if case .foo(let bar, let baz) = quux {
// inner foo
}
+ if case let .foo(bar, baz) = quux {
// inner foo
}
Move inline try
keyword(s) to start of expression.
Option | Description |
---|---|
--throwcapturing |
List of functions with throwing @autoclosure arguments |
Examples
- foo(try bar(), try baz())
+ try foo(bar(), baz())
- let foo = String(try await getFoo())
+ let foo = try String(await getFoo())
Indent code in accordance with the scope level.
Option | Description |
---|---|
--indent |
Number of spaces to indent, or "tab" to use tabs |
--tabwidth |
The width of a tab character. Defaults to "unspecified" |
--smarttabs |
Align code independently of tab width. defaults to "enabled" |
--indentcase |
Indent cases inside a switch: "true" or "false" (default) |
--ifdef |
#if indenting: "indent" (default), "no-indent" or "outdent" |
--xcodeindentation |
Match Xcode indenting: "enabled" or "disabled" (default) |
--indentstrings |
Indent multiline strings: "false" (default) or "true" |
Examples
if x {
- // foo
} else {
- // bar
- }
if x {
+ // foo
} else {
+ // bar
+ }
let array = [
foo,
- bar,
- baz
- ]
let array = [
foo,
+ bar,
+ baz
+ ]
switch foo {
- case bar: break
- case baz: break
}
switch foo {
+ case bar: break
+ case baz: break
}
Add @available(*, unavailable)
attribute to required init(coder:)
when
it hasn't been implemented.
Option | Description |
---|---|
--initcodernil |
Replace fatalError with nil in unavailable init?(coder:) |
Examples
+ @available(*, unavailable)
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
Prefer isEmpty
over comparing count
against zero.
Examples
- if foo.count == 0 {
+ if foo.isEmpty {
- if foo.count > 0 {
+ if !foo.isEmpty {
- if foo?.count == 0 {
+ if foo?.isEmpty == true {
NOTE: In rare cases, the isEmpty
rule may insert an isEmpty
call for
a type that doesn't implement that property, breaking the program. For this
reason, the rule is disabled by default, and must be manually enabled via the
--enable isEmpty
option.
Move leading delimiters to the end of the previous line.
Examples
- guard let foo = maybeFoo // first
- , let bar = maybeBar else { ... }
+ guard let foo = maybeFoo, // first
+ let bar = maybeBar else { ... }
Add empty blank line at end of file.
Use specified linebreak character for all linebreaks (CR, LF or CRLF).
Option | Description |
---|---|
--linebreaks |
Linebreak character to use: "cr", "crlf" or "lf" (default) |
Add a MARK comment before top-level types and extensions.
Option | Description |
---|---|
--marktypes |
Mark types "always" (default), "never", "if-not-empty" |
--typemark |
Template for type mark comments. Defaults to "MARK: - %t" |
--markextensions |
Mark extensions "always" (default), "never", "if-not-empty" |
--extensionmark |
Mark for standalone extensions. Defaults to "MARK: - %t + %c" |
--groupedextension |
Mark for extension grouped with extended type. ("MARK: %c") |
Examples
+ // MARK: - FooViewController
+
final class FooViewController: UIViewController { }
+ // MARK: UICollectionViewDelegate
+
extension FooViewController: UICollectionViewDelegate { }
+ // MARK: - String + FooProtocol
+
extension String: FooProtocol { }
Use consistent ordering for member modifiers.
Option | Description |
---|---|
--modifierorder |
Comma-delimited list of modifiers in preferred order |
Examples
- lazy public weak private(set) var foo: UIView?
+ public private(set) lazy weak var foo: UIView?
- final public override func foo()
+ override public final func foo()
- convenience private init()
+ private convenience init()
NOTE: If the --modifierorder
option isn't set, the default order will be:
override
, private
, fileprivate
, internal
, package
, public
, open
, private(set)
, fileprivate(set)
, internal(set)
, package(set)
, public(set)
, open(set)
, final
, dynamic
, optional
, required
, convenience
, indirect
, isolated
, nonisolated
, nonisolated(unsafe)
, lazy
, weak
, unowned
, static
, class
, borrowing
, consuming
, mutating
, nonmutating
, prefix
, infix
, postfix
Don't use explicit ownership modifiers (borrowing / consuming).
Examples
- borrowing func foo(_ bar: consuming Bar) { ... }
+ func foo(_ bar: Bar) { ... }
Use consistent grouping for numeric literals. Groups will be separated by _
delimiters to improve readability. For each numeric type you can specify a group
size (the number of digits in each group) and a threshold (the minimum number of
digits in a number before grouping is applied).
Option | Description |
---|---|
--decimalgrouping |
Decimal grouping,threshold (default: 3,6) or "none", "ignore" |
--binarygrouping |
Binary grouping,threshold (default: 4,8) or "none", "ignore" |
--octalgrouping |
Octal grouping,threshold (default: 4,8) or "none", "ignore" |
--hexgrouping |
Hex grouping,threshold (default: 4,8) or "none", "ignore" |
--fractiongrouping |
Group digits after '.': "enabled" or "disabled" (default) |
--exponentgrouping |
Group exponent digits: "enabled" or "disabled" (default) |
--hexliteralcase |
Casing for hex literals: "uppercase" (default) or "lowercase" |
--exponentcase |
Case of 'e' in numbers: "lowercase" or "uppercase" (default) |
Examples
- let color = 0xFF77A5
+ let color = 0xff77a5
- let big = 123456.123
+ let big = 123_456.123
Use opaque generic parameters (some Protocol
) instead of generic parameters
with constraints (T where T: Protocol
, etc) where equivalent. Also supports
primary associated types for common standard library types, so definitions like
T where T: Collection, T.Element == Foo
are updated to some Collection<Foo>
.
Option | Description |
---|---|
--someany |
Use some Any types: "true" (default) or "false" |
Examples
- func handle<T: Fooable>(_ value: T) {
+ func handle(_ value: some Fooable) {
print(value)
}
- func handle<T>(_ value: T) where T: Fooable, T: Barable {
+ func handle(_ value: some Fooable & Barable) {
print(value)
}
- func handle<T: Collection>(_ value: T) where T.Element == Foo {
+ func handle(_ value: some Collection<Foo>) {
print(value)
}
// With `--someany enabled` (the default)
- func handle<T>(_ value: T) {
+ func handle(_ value: some Any) {
print(value)
}
Organize declarations within class, struct, enum, actor, and extension bodies.
Option | Description |
---|---|
--categorymark |
Template for category mark comments. Defaults to "MARK: %c" |
--markcategories |
Insert MARK comments between categories (true by default) |
--beforemarks |
Declarations placed before first mark (e.g. typealias,struct ) |
--lifecycle |
Names of additional Lifecycle methods (e.g. viewDidLoad ) |
--organizetypes |
Declarations to organize (default: class,actor,struct,enum ) |
--structthreshold |
Minimum line count to organize struct body. Defaults to 0 |
--classthreshold |
Minimum line count to organize class body. Defaults to 0 |
--enumthreshold |
Minimum line count to organize enum body. Defaults to 0 |
--extensionlength |
Minimum line count to organize extension body. Defaults to 0 |
--organizationmode |
Organize declarations by "visibility" (default) or "type" |
Examples
--organizationmode visibility
(default)
public class Foo {
- public func c() -> String {}
-
- public let a: Int = 1
- private let g: Int = 2
- let e: Int = 2
- public let b: Int = 3
-
- public func d() {}
- func f() {}
- init() {}
- deinit() {}
}
public class Foo {
+
+ // MARK: Lifecycle
+
+ init() {}
+ deinit() {}
+
+ // MARK: Public
+
+ public let a: Int = 1
+ public let b: Int = 3
+
+ public func c() -> String {}
+ public func d() {}
+
+ // MARK: Internal
+
+ let e: Int = 2
+
+ func f() {}
+
+ // MARK: Private
+
+ private let g: Int = 2
+
}
--organizationmode type
public class Foo {
- public func c() -> String {}
-
- public let a: Int = 1
- private let g: Int = 2
- let e: Int = 2
- public let b: Int = 3
-
- public func d() {}
- func f() {}
- init() {}
- deinit() {}
}
public class Foo {
+
+ // MARK: Properties
+
+ public let a: Int = 1
+ public let b: Int = 3
+
+ let e: Int = 2
+
+ private let g: Int = 2
+
+ // MARK: Lifecycle
+
+ init() {}
+ deinit() {}
+
+ // MARK: Functions
+
+ public func c() -> String {}
+ public func d() {}
+
}
Convert functional forEach
calls to for loops.
Option | Description |
---|---|
--anonymousforeach |
Convert anonymous forEach: "convert" (default) or "ignore" |
--onelineforeach |
Convert one-line forEach: "convert" or "ignore" (default) |
Examples
let strings = ["foo", "bar", "baaz"]
- strings.forEach { placeholder in
+ for placeholder in strings {
print(placeholder)
}
// Supports anonymous closures
- strings.forEach {
+ for string in strings {
- print($0)
+ print(string)
}
- foo.item().bar[2].baazValues(option: true).forEach {
+ for baazValue in foo.item().bar[2].baazValues(option: true) {
- print($0)
+ print(baazValue)
}
// Doesn't affect long multiline functional chains
placeholderStrings
.filter { $0.style == .fooBar }
.map { $0.uppercased() }
.forEach { print($0) }
Convert trivial map { $0.foo }
closures to keyPath-based syntax.
Examples
- let barArray = fooArray.map { $0.bar }
+ let barArray = fooArray.map(\.bar)
- let barArray = fooArray.compactMap { $0.optionalBar }
+ let barArray = fooArray.compactMap(\.optionalBar)
Remove redundant backticks around identifiers.
Examples
- let `infix` = bar
+ let infix = bar
- func foo(with `default`: Int) {}
+ func foo(with default: Int) {}
Remove redundant break
in switch case.
Examples
switch foo {
case bar:
print("bar")
- break
default:
print("default")
- break
}
Removes redundant closures bodies, containing a single statement, which are called immediately.
Examples
- let foo = { Foo() }()
+ let foo = Foo()
- lazy var bar = {
- Bar(baaz: baaz,
- quux: quux)
- }()
+ lazy var bar = Bar(baaz: baaz,
+ quux: quux)
Remove redundant access control modifiers.
Examples
public extension URL {
- public func queryParameter(_ name: String) -> String { ... }
}
public extension URL {
+ func queryParameter(_ name: String) -> String { ... }
}
Prefer private
over fileprivate
where equivalent.
Examples
- fileprivate let someConstant = "someConstant"
+ private let someConstant = "someConstant"
In Swift 4 and above, fileprivate
can also be replaced with private
for
members that are only accessed from extensions in the same file:
class Foo {
- fileprivate var foo = "foo"
+ private var foo = "foo"
}
extension Foo {
func bar() {
print(self.foo)
}
}
Remove unneeded get
clause inside computed properties.
Examples
var foo: Int {
- get {
- return 5
- }
}
var foo: Int {
+ return 5
}
Remove explicit init
if not required.
Examples
- String.init("text")
+ String("text")
Remove redundant internal access control.
Examples
- internal class Foo {
+ class Foo {
- internal let bar: String
+ let bar: String
- internal func baaz() {}
+ func baaz() {}
- internal init() {
+ init() {
bar = "bar"
}
}
Remove redundant let
/var
from ignored variables.
Examples
- let _ = foo()
+ _ = foo()
Remove redundant let error
from catch
clause.
Examples
- do { ... } catch let error { log(error) }
+ do { ... } catch { log(error) }
Remove/insert redundant nil
default value (Optional vars are nil by default).
Option | Description |
---|---|
--nilinit |
"remove" (default) redundant nil or "insert" missing nil |
Examples
--nilinit remove
- var foo: Int? = nil
+ var foo: Int?
// doesn't apply to `let` properties
let foo: Int? = nil
// doesn't affect non-nil initialization
var foo: Int? = 0
--nilinit insert
- var foo: Int?
+ var foo: Int? = nil
Remove redundant @objc
annotations.
Examples
- @objc @IBOutlet var label: UILabel!
+ @IBOutlet var label: UILabel!
- @IBAction @objc func goBack() {}
+ @IBAction func goBack() {}
- @objc @NSManaged private var foo: String?
+ @NSManaged private var foo: String?
Remove redundant identifiers in optional binding conditions.
Examples
- if let foo = foo {
+ if let foo {
print(foo)
}
- guard let self = self else {
+ guard let self else {
return
}
Remove redundant parentheses.
Examples
- if (foo == true) {}
+ if foo == true {}
- while (i < bar.count) {}
+ while i < bar.count {}
- queue.async() { ... }
+ queue.async { ... }
- let foo: Int = ({ ... })()
+ let foo: Int = { ... }()
Remove redundant pattern matching parameter syntax.
Examples
- if case .foo(_, _) = bar {}
+ if case .foo = bar {}
- let (_, _) = bar
+ let _ = bar
Simplifies redundant property definitions that are immediately returned.
Examples
func foo() -> Foo {
- let foo = Foo()
- return foo
+ return Foo()
}
Remove redundant raw string values for enum cases.
Examples
enum Foo: String {
- case bar = "bar"
case baz = "quux"
}
enum Foo: String {
+ case bar
case baz = "quux"
}
Remove unneeded return
keyword.
Examples
- array.filter { return $0.foo == bar }
+ array.filter { $0.foo == bar }
// Swift 5.1+ (SE-0255)
var foo: String {
- return "foo"
+ "foo"
}
// Swift 5.9+ (SE-0380) and with conditionalAssignment rule enabled
func foo(_ condition: Bool) -> String {
if condition {
- return "foo"
+ "foo"
} else {
- return "bar"
+ "bar"
}
}
Insert/remove explicit self
where applicable.
Option | Description |
---|---|
--self |
Explicit self: "insert", "remove" (default) or "init-only" |
--selfrequired |
Comma-delimited list of functions with @autoclosure arguments |
Examples
func foobar(foo: Int, bar: Int) {
self.foo = foo
self.bar = bar
- self.baz = 42
}
func foobar(foo: Int, bar: Int) {
self.foo = foo
self.bar = bar
+ baz = 42
}
In the rare case of functions with @autoclosure
arguments, self
may be
required at the call site, but SwiftFormat is unable to detect this
automatically. You can use the --selfrequired
command-line option to specify
a list of such methods, and the redundantSelf
rule will then ignore them.
An example of such a method is the expect()
function in the Nimble unit
testing framework (https://github.com/Quick/Nimble), which is common enough that
SwiftFormat excludes it by default.
There is also an option to always use explicit self
but only inside init
,
by using --self init-only
:
init(foo: Int, bar: Int) {
self.foo = foo
self.bar = bar
- baz = 42
}
init(foo: Int, bar: Int) {
self.foo = foo
self.bar = bar
+ self.baz = 42
}
Remove explicit Self
where applicable.
Remove redundant type from variable declarations.
Option | Description |
---|---|
--redundanttype |
"inferred", "explicit", or "infer-locals-only" (default) |
Examples
// inferred
- let view: UIView = UIView()
+ let view = UIView()
// explicit
- let view: UIView = UIView()
+ let view: UIView = .init()
// infer-locals-only
class Foo {
- let view: UIView = UIView()
+ let view: UIView = .init()
func method() {
- let view: UIView = UIView()
+ let view = UIView()
}
}
// Swift 5.9+, inferred (SE-0380)
- let foo: Foo = if condition {
+ let foo = if condition {
Foo("foo")
} else {
Foo("bar")
}
// Swift 5.9+, explicit (SE-0380)
let foo: Foo = if condition {
- Foo("foo")
+ .init("foo")
} else {
- Foo("bar")
+ .init("foo")
}
Converts throws(any Error)
to throws
, and converts throws(Never)
to non-throwing.
Examples
- func foo() throws(Never) -> Int {
+ func foo() -> Int {
return 0
}
- func foo() throws(any Error) -> Int {
+ func foo() throws -> Int {
throw MyError.foo
}
Remove explicit Void
return type.
Option | Description |
---|---|
--closurevoid |
Closure void returns: "remove" (default) or "preserve" |
Examples
- func foo() -> Void {
// returns nothing
}
+ func foo() {
// returns nothing
}
Remove semicolons.
Option | Description |
---|---|
--semicolons |
Allow semicolons: "never" or "inline" (default) |
Examples
- let foo = 5;
+ let foo = 5
- let foo = 5; let bar = 6
+ let foo = 5
+ let bar = 6
// semicolon is not removed if it would affect the behavior of the code
return;
goto(fail)
Sorts the body of declarations with // swiftformat:sort and declarations between // swiftformat:sort:begin and // swiftformat:sort:end comments.
Examples
// swiftformat:sort
enum FeatureFlags {
- case upsellB
- case fooFeature
- case barFeature
- case upsellA(
- fooConfiguration: Foo,
- barConfiguration: Bar)
+ case barFeature
+ case fooFeature
+ case upsellA(
+ fooConfiguration: Foo,
+ barConfiguration: Bar)
+ case upsellB
}
enum FeatureFlags {
// swiftformat:sort:begin
- case upsellB
- case fooFeature
- case barFeature
- case upsellA(
- fooConfiguration: Foo,
- barConfiguration: Bar)
+ case barFeature
+ case fooFeature
+ case upsellA(
+ fooConfiguration: Foo,
+ barConfiguration: Bar)
+ case upsellB
// swiftformat:sort:end
var anUnsortedProperty: Foo {
Foo()
}
}
Sort import statements alphabetically.
Option | Description |
---|---|
--importgrouping |
"testable-first/last", "alpha" (default) or "length" |
Examples
- import Foo
- import Bar
+ import Bar
+ import Foo
- import B
- import A
- #if os(iOS)
- import Foo-iOS
- import Bar-iOS
- #endif
+ import A
+ import B
+ #if os(iOS)
+ import Bar-iOS
+ import Foo-iOS
+ #endif
Sort switch cases alphabetically.
Sort protocol composition typealiases alphabetically.
Examples
- typealias Placeholders = Foo & Bar & Baaz & Quux
+ typealias Placeholders = Baaz & Bar & Foo & Quux
typealias Dependencies
- = FooProviding
+ = BaazProviding
& BarProviding
- & BaazProviding
+ & FooProviding
& QuuxProviding
Sort import statements alphabetically.
Note: sortedImports rule is deprecated. Use sortImports instead.
Sort switch cases alphabetically.
Note: sortedSwitchCases rule is deprecated. Use sortSwitchCases instead.
Add or remove space around curly braces.
Examples
- foo.filter{ return true }.map{ $0 }
+ foo.filter { return true }.map { $0 }
- foo( {} )
+ foo({})
Add or remove space around square brackets.
Examples
- foo as[String]
+ foo as [String]
- foo = bar [5]
+ foo = bar[5]
Add space before and/or after comments.
Examples
- let a = 5// assignment
+ let a = 5 // assignment
- func foo() {/* ... */}
+ func foo() { /* ... */ }
Remove space around angle brackets.
Examples
- Foo <Bar> ()
+ Foo<Bar>()
Add or remove space around operators or delimiters.
Option | Description |
---|---|
--operatorfunc |
Spacing for operator funcs: "spaced" (default) or "no-space" |
--nospaceoperators |
Comma-delimited list of operators without surrounding space |
--ranges |
Spacing for ranges: "spaced" (default) or "no-space" |
--typedelimiter |
"space-after" (default), "spaced" or "no-space" |
Examples
- foo . bar()
+ foo.bar()
- a+b+c
+ a + b + c
- func ==(lhs: Int, rhs: Int) -> Bool
+ func == (lhs: Int, rhs: Int) -> Bool
Add or remove space around parentheses.
Examples
- init (foo)
+ init(foo)
- switch(x){
+ switch (x) {
Add space inside curly braces.
Examples
- foo.filter {return true}
+ foo.filter { return true }
Remove space inside square brackets.
Examples
- [ 1, 2, 3 ]
+ [1, 2, 3]
Add leading and/or trailing space inside comments.
Examples
- let a = 5 //assignment
+ let a = 5 // assignment
- func foo() { /*...*/ }
+ func foo() { /* ... */ }
Remove space inside angle brackets.
Examples
- Foo< Bar, Baz >
+ Foo<Bar, Baz>
Remove space inside parentheses.
Examples
- ( a, b)
+ (a, b)
Use consistent ordering for member modifiers.
Note: specifiers rule is deprecated. Use modifierOrder instead.
Remove weak
modifier from @IBOutlet
properties.
Examples
As per Apple's recommendation (https://developer.apple.com/videos/play/wwdc2015/407/ @ 32:30).
- @IBOutlet weak var label: UILabel!
+ @IBOutlet var label: UILabel!
Remove backticks around self
in Optional unwrap expressions.
Examples
- guard let `self` = self else { return }
+ guard let self = self else { return }
NOTE: assignment to un-escaped self
is only supported in Swift 4.2 and
above, so the strongifiedSelf
rule is disabled unless the Swift version is
set to 4.2 or above.
Use correct formatting for TODO:
, MARK:
or FIXME:
comments.
Examples
- /* TODO fix this properly */
+ /* TODO: fix this properly */
- // MARK - UIScrollViewDelegate
+ // MARK: - UIScrollViewDelegate
Use trailing closure syntax where applicable.
Option | Description |
---|---|
--trailingclosures |
Comma-delimited list of functions that use trailing closures |
--nevertrailing |
List of functions that should never use trailing closures |
Examples
- DispatchQueue.main.async(execute: { ... })
+ DispatchQueue.main.async {
- let foo = bar.map({ ... }).joined()
+ let foo = bar.map { ... }.joined()
Add or remove trailing comma from the last item in a collection literal.
Option | Description |
---|---|
--commas |
Commas in collection literals: "always" (default) or "inline" |
Examples
let array = [
foo,
bar,
- baz
]
let array = [
foo,
bar,
+ baz,
]
Remove trailing space at end of a line.
Option | Description |
---|---|
--trimwhitespace |
Trim trailing space: "always" (default) or "nonblank-lines" |
Prefer shorthand syntax for Arrays, Dictionaries and Optionals.
Option | Description |
---|---|
--shortoptionals |
Use ? for optionals "always" or "except-properties" (default) |
Examples
- var foo: Array<String>
+ var foo: [String]
- var foo: Dictionary<String, Int>
+ var foo: [String: Int]
- var foo: Optional<(Int) -> Void>
+ var foo: ((Int) -> Void)?
Mark unused function arguments with _
.
Option | Description |
---|---|
--stripunusedargs |
"closure-only", "unnamed-only" or "always" (default) |
Examples
- func foo(bar: Int, baz: String) {
print("Hello \(baz)")
}
+ func foo(bar _: Int, baz: String) {
print("Hello \(baz)")
}
- func foo(_ bar: Int) {
...
}
+ func foo(_: Int) {
...
}
- request { response, data in
self.data += data
}
+ request { _, data in
self.data += data
}
Use Void
for type declarations and ()
for values.
Option | Description |
---|---|
--voidtype |
How void types are represented: "void" (default) or "tuple" |
Examples
- let foo: () -> ()
+ let foo: () -> Void
- let bar: Void -> Void
+ let bar: () -> Void
- let baz: (Void) -> Void
+ let baz: () -> Void
- func quux() -> (Void)
+ func quux() -> Void
- callback = { _ in Void() }
+ callback = { _ in () }
Wrap lines that exceed the specified maximum width.
Option | Description |
---|---|
--maxwidth |
Maximum length of a line before wrapping. defaults to "none" |
--nowrapoperators |
Comma-delimited list of operators that shouldn't be wrapped |
--assetliterals |
Color/image literal width. "actual-width" or "visual-width" |
--wrapternary |
Wrap ternary operators: "default", "before-operators" |
Align wrapped function arguments or collection elements.
Option | Description |
---|---|
--wraparguments |
Wrap all arguments: "before-first", "after-first", "preserve" |
--wrapparameters |
Wrap func params: "before-first", "after-first", "preserve" |
--wrapcollections |
Wrap array/dict: "before-first", "after-first", "preserve" |
--closingparen |
Closing paren position: "balanced" (default) or "same-line" |
--callsiteparen |
Closing paren at call sites: "balanced" or "same-line" |
--wrapreturntype |
Wrap return type: "if-multiline", "preserve" (default) |
--wrapconditions |
Wrap conditions: "before-first", "after-first", "preserve" |
--wraptypealiases |
Wrap typealiases: "before-first", "after-first", "preserve" |
--wrapeffects |
Wrap effects: "if-multiline", "never", "preserve" |
Examples
NOTE: For backwards compatibility with previous versions, if no value is
provided for --wrapparameters
, the value for --wraparguments
will be used.
--wraparguments before-first
- foo(bar: Int,
- baz: String)
+ foo(
+ bar: Int,
+ baz: String
+ )
- class Foo<Bar,
- Baz>
+ class Foo<
+ Bar,
+ Baz
+ >
--wrapparameters after-first
- func foo(
- bar: Int,
- baz: String
- ) {
...
}
+ func foo(bar: Int,
+ baz: String)
+ {
...
}
--wrapcollections before-first
:
- let foo = [bar,
baz,
- quuz]
+ let foo = [
+ bar,
baz,
+ quuz
+ ]
Wrap @attributes onto a separate line, or keep them on the same line.
Option | Description |
---|---|
--funcattributes |
Function @attributes: "preserve", "prev-line", or "same-line" |
--typeattributes |
Type @attributes: "preserve", "prev-line", or "same-line" |
--storedvarattrs |
Stored var @attribs: "preserve", "prev-line", or "same-line" |
--computedvarattrs |
Computed var @attribs: "preserve", "prev-line", "same-line" |
--complexattrs |
Complex @attributes: "preserve", "prev-line", or "same-line" |
--noncomplexattrs |
List of @attributes to exclude from complexattrs rule |
Examples
--funcattributes prev-line
- @objc func foo() {}
+ @objc
+ func foo() { }
--funcattributes same-line
- @objc
- func foo() { }
+ @objc func foo() {}
--typeattributes prev-line
- @objc class Foo {}
+ @objc
+ class Foo { }
--typeattributes same-line
- @objc
- enum Foo { }
+ @objc enum Foo {}
Wrap the bodies of inline conditional statements onto a new line.
Examples
- guard let foo = bar else { return baz }
+ guard let foo = bar else {
+ return baz
+ }
- if foo { return bar }
+ if foo {
+ return bar
+ }
Rewrite comma-delimited enum cases to one case per line.
Option | Description |
---|---|
--wrapenumcases |
Wrap enum cases: "always" (default) or "with-values" |
Examples
enum Foo {
- case bar, baz
}
enum Foo {
+ case bar
+ case baz
}
Wrap the bodies of inline loop statements onto a new line.
Examples
- for foo in array { print(foo) }
+ for foo in array {
+ print(foo)
+ }
- while let foo = bar.next() { print(foo) }
+ while let foo = bar.next() {
+ print(foo)
+ }
Wrap multiline conditional assignment expressions after the assignment operator.
Examples
- let planetLocation = if let star = planet.star {
- "The \(star.name) system"
- } else {
- "Rogue planet"
- }
+ let planetLocation =
+ if let star = planet.star {
+ "The \(star.name) system"
+ } else {
+ "Rogue planet"
+ }
Wrap the opening brace of multiline statements.
Examples
if foo,
- bar {
// ...
}
if foo,
+ bar
+ {
// ...
}
guard foo,
- bar else {
// ...
}
guard foo,
+ bar else
+ {
// ...
}
func foo(
bar: Int,
- baz: Int) {
// ...
}
func foo(
bar: Int,
+ baz: Int)
+ {
// ...
}
class Foo: NSObject,
- BarProtocol {
// ...
}
class Foo: NSObject,
+ BarProtocol
+ {
// ...
}
Wrap single line //
comments that exceed the specified --maxwidth
.
Wrap comma-delimited switch cases onto multiple lines.
Examples
switch foo {
- case .bar, .baz:
break
}
switch foo {
+ case .foo,
+ .bar:
break
}
Prefer constant values to be on the right-hand-side of expressions.
Option | Description |
---|---|
--yodaswap |
Swap yoda values: "always" (default) or "literals-only" |