LoginSignup
156
107

SwiftLintの全ルール一覧(Swift 4.2版)

Last updated at Posted at 2019-02-11

SwiftLintの記事はシリーズになっています。
記事を順番に読み進めると、SwiftLintを使いこなせるようになります。

はじめに

すでに SwiftLintのルールをまとめてくださっている方 がいらっしゃいますが、約2年ほど更新されていなかったので、自分でもまとめてみました。

SwiftLintの概要や導入については以下をご参照ください。
Swiftの静的解析ツール「SwiftLint」のセットアップ方法 - Qiita

2019/12/08 追記

今回紹介するSwiftLintのバージョン(0.30.1)から0.38.0までの間に、追加・変更・廃止されたルールを以下の記事にまとめました。
https://qiita.com/uhooi/items/8e9767c2e746f4171ded

SwiftLintの最新バージョンを使う方は併せてご参照ください。

注意

公式ページのルールを簡単に翻訳してまとめたものです。
英語に慣れている方は公式ページを直接見るのがいいです。
https://github.com/realm/SwiftLint/blob/master/Rules.md

また、間違っている箇所や不適切な箇所がありましたら教えていただけると嬉しいです。

環境

  • Swift:4.2.1
  • Xcode:10.1 (10B61)
  • SwiftLint:0.30.1

Default

デフォルトで有効になっているルールの一覧です。

Block Based KVO

Swift 3.2以降の場合、新しいブロックベースのKVO APIとキーパスを使うべきです。
https://realm.github.io/SwiftLint/block_based_kvo.html

// bad
class Foo: NSObject {
    override func observeValue(forKeyPath keyPath: String?, of object: Any?,
        change: [NSKeyValueChangeKey: Any]?,
        context: UnsafeMutableRawPointer?) { }
}

// good
let observer = foo.observe(\.value, options: [.new]) { (foo, change) in
    print(change.newValue)
}

Class Delegate Protocol

デリゲートプロトコルはクラスのみであるべきで、弱参照されることができます。
https://realm.github.io/SwiftLint/class_delegate_protocol.html

// bad
protocol FooDelegate { }

// good
protocol FooDelegate: class { }

Closing Brace Spacing

右括弧で閉じ括弧を閉じる場合、間にスペースを含めるべきではありません。
https://realm.github.io/SwiftLint/closing_brace_spacing.html

// bad
[].map({ } )

// good
[].map({ })

Closure Parameter Position

クロージャのパラメータは開き括弧と同じ行にあるべきです。
https://realm.github.io/SwiftLint/closure_parameter_position.html

// bad
[1, 2].map {
    number in
    number + 1
}

// good
[1, 2].map { number in
    number + 1
}

Colon

: は、型の指定時には識別子の後ろ、ディクショナリではキーの後ろにあるべきです。
https://realm.github.io/SwiftLint/colon

// bad
let abc:Void
let abc :Void
let abc : Void
let abc: [String:Int]
let abc: [String :Int]
let abc: [String : Int]

// good
let abc: Void
let abc: [String: Int]

Comma Spacing

カンマの前にスペースがあるべきではなく、カンマの後ろには1つの半角スペースがあるべきです。
https://realm.github.io/SwiftLint/comma_spacing.html

// bad
func abc(a: String,b: String) { }
func abc(a: String ,b: String) { }
func abc(a: String , b: String) { }

// good
func abc(a: String, b: String) { }

Compiler Protocol Init

ExpressibleByArrayLiteral のようなコンパイルプロトコルで定義されているイニシャライザは直接呼び出すべきではありません。
https://realm.github.io/SwiftLint/compiler_protocol_init.html

// bad
let set = Set(arrayLiteral: 1, 2)
let set = Set.init(arrayLiteral: 1, 2)

// good
let set: Set<Int> = [1, 2]
let set = Set(array)

Control Statement

if , for , guard , switch , while , catch 文は条件や引数を不必要に括弧で括るべきではありません。
https://realm.github.io/SwiftLint/control_statement.html

// bad
if (condition) { }
for (item in collection) { }
guard (condition) else { }
switch (foo) { }
while (condition) { }
do {
} catch (let error) {
}

// good
if condition { }
for item in collection { }
guard condition else { }
switch foo { }
while condition { }
do {
} catch let error {
}

Custom Rules

正規表現を指定してカスタムルールを作成できます。
https://realm.github.io/SwiftLint/custom_rules.html

Cyclomatic Complexity

関数内は複雑にすべきではありません。
https://realm.github.io/SwiftLint/cyclomatic_complexity.html

// bad
func f1() {
    if true {
        if true {
            if false { }
        }
    }
    if false { }
    let i = 0

    switch i {
    case 1: break
    case 2: break
    case 3: break
    case 4: break
    default: break
    }
    for _ in 1...5 {
        guard true else {
            return
        }
    }
}

// good
func f1() {
    if true {
        for _ in 1..5 { } }
    if false { }
}

Deployment Target

可用性のチェックまたは属性は、デプロイメントターゲットが満たす古いバージョンを使うべきではありません。
https://realm.github.io/SwiftLint/deployment_target.html

// bad
@available(iOS 6.0, *)
class A { }

if #available(iOS 6.0, *) { }

// good
@available(iOS 12.0, *)
class A { }

if #available(iOS 12.0, *) { }

Discarded Notification Center Observer

ブロックを使って通知を登録するとき、返される不透明なオブザーバは後で削除できるように格納すべきです。
https://realm.github.io/SwiftLint/discarded_notification_center_observer.html

// bad
nc.addObserver(forName: .NSSystemTimeZoneDidChange, object: nil, queue: nil) { }

// good
let foo = nc.addObserver(forName: .NSSystemTimeZoneDidChange, object: nil, queue: nil) { }

Discouraged Direct Initialization

有害な可能性がある型を直接初期化すべきではありません。
https://realm.github.io/SwiftLint/discouraged_direct_initialization.html

// bad
let foo = UIDevice()
let foo = Bundle()

// good
let foo = UIDevice.current
let foo = Bundle.main
let foo = Bundle(path: "bar")
let foo = Bundle(identifier: "bar")

Duplicate Imports

インポートは1回のみ行うべきです。
https://realm.github.io/SwiftLint/duplicate_imports.html

// bad
import Foundation
import Dispatch
import Foundation

// good
import Foundation
import Dispatch

Dynamic Inline

dynamic@inline(__always) を同時に使ってはいけません。
https://realm.github.io/SwiftLint/dynamic_inline.html

// bad
class C {
    @inline(__always) dynamic func f() { }
}

// good
class C {
    dynamic func f() { }
}
class C {
    @inline(__always) func f() { }
}

Empty Enum Arguments

列挙型が連想型と一致しない場合、引数を省略すべきです。
https://realm.github.io/SwiftLint/empty_enum_arguments.html

// bad
switch foo {
    case .bar(_): break
}
switch foo {
    case .bar(): break
}

// good
switch foo {
    case .bar: break
}

Empty Parameters

Void -> より () -> を使うべきです。
https://realm.github.io/SwiftLint/empty_parameters.html

// bad
let abc: (Void) -> Void = { }

// good
let abc: () -> Void = { }

Empty Parentheses with Trailing Closure

トレイリングクロージャを使う場合、メソッドの呼び出し後に空の括弧を記述すべきではありません。
https://realm.github.io/SwiftLint/empty_parentheses_with_trailing_closure.html

// bad
[1, 2].map() { $0 + 1 }

// good
[1, 2].map { $0 + 1 }

File Line Length

ファイル内はあまりにも多くの行にまたがるべきではないです。
https://realm.github.io/SwiftLint/file_line_length.html

// bad
print("swiftlint")
print("swiftlint")
print("swiftlint")

For Where

for文内にif文が1つのみ存在する場合、 where 句を使うべきです。
https://realm.github.io/SwiftLint/for_where.html

// bad
for user in users {
    if user.id == 1 {
        user.myFunction()
    }
}

// good
for user in users where user.id == 1 {
    user.myFunction()
}

Force Cast

強制キャスト( as! )は使うべきではありません。
https://realm.github.io/SwiftLint/force_cast.html

// bad
NSNumber() as! Int

// good
NSNumber() as? Int

Force Try

強制トライ( try! )は使うべきではありません。
https://realm.github.io/SwiftLint/force_try.html

func a() throws { }

// bad
try! a()

// good
do {
    try a()
} catch {
    // エラー処理
}

Function Body Length

関数内はあまりにも多くの行にまたがるべきではないです。
https://realm.github.io/SwiftLint/function_body_length.html

Function Parameter Count

関数の引数の数は少なくすべきです。
https://realm.github.io/SwiftLint/function_parameter_count.html

// bad
func f(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int) { }

// good
func f(a: Int, b: Int, c: Int, d: Int, e: Int) { }

Generic Type Name

ジェネリック型は英数のみを含み、大文字で始まり、1〜20文字にすべきです。
https://realm.github.io/SwiftLint/generic_type_name.html

// bad
func foo<T, U_Foo>(param: U_Foo) -> T { }
func foo<T, u>(param: u) -> T { }

// good
func foo<T, U>(param: U) -> T { }

Identifier Name

識別子名は英数のみを含み、小文字で始まるか、大文字のみを含むべきです。
上記以外では、変数名は静的かつ不変と定義されている場合は大文字から始まることがあります。
変数名は長過ぎたり短過ぎたりしてはいけません。
https://realm.github.io/SwiftLint/identifier_name.html

// bad
let MyLet = 0
let _myLet = 0
let id = 0

// good
let myLet = 0

Implicit Getter

読取専用のコンピューテッドプロパティとサブスクリプトには get キーワードを使うべきではありません。
https://realm.github.io/SwiftLint/implicit_getter.html

// bad
class Foo {
    var foo: Int {
        get {
            return 20
        }
    }
}

// good
class Foo {
    var foo: Int {
        return 20
    }
}

Inert Defer

defer が親スコープの終わりにある場合、その場所で実行されます。
https://realm.github.io/SwiftLint/inert_defer.html

// bad
func example() {
    print("other code")
    defer { /* deferred code */ }
}

// good
func example() {
    defer { /* deferred code */ }
    print("other code")
}

Is Disjoint

Set.intersection(_:).isEmpty より Set.isDisjoint(with:) を使うべきです。
https://realm.github.io/SwiftLint/is_disjoint.html

// bad
_ = Set(syntaxKinds).intersection(commentAndStringKindsSet).isEmpty

// good
_ = Set(syntaxKinds).isDisjoint(with: commentAndStringKindsSet)

Large Tuple

タプルはあまりにも多くのメンバーを持つべきではありません。
代わりにカスタムタイプを作成すべきです。
https://realm.github.io/SwiftLint/large_tuple.html

// bad
let foo: (Int, Int, Int)

// good
let foo: (Int, Int)

Leading Whitespace

ファイルは先頭にスペースを含んではいけません。
https://realm.github.io/SwiftLint/leading_whitespace.html

// bad
 // foo

// good
// foo

Legacy CGGeometry Functions

構造体のエクステンションのプロパティとメソッドは、従来の関数より優先すべきです。
https://realm.github.io/SwiftLint/legacy_cggeometry_functions.html

// bad
CGRectGetWidth(rect)
CGRectGetHeight(rect)
CGRectGetMinX(rect)
CGRectGetMidX(rect)
CGRectGetMaxX(rect)
CGRectGetMinY(rect)
CGRectGetMidY(rect)
CGRectGetMaxY(rect)
CGRectIsNull(rect)
CGRectIsEmpty(rect)
CGRectIsInfinite(rect)
CGRectStandardize(rect)
CGRectIntegral(rect)
CGRectInset(rect, 10, 5)
CGRectOffset(rect, -2, 8.3)
CGRectUnion(rect1, rect2)
CGRectIntersection(rect1, rect2)
CGRectContainsRect(rect1, rect2)
CGRectContainsPoint(rect, point)
CGRectIntersectsRect(rect1, rect2)

// good
rect.width
rect.height
rect.minX
rect.midX
rect.maxX
rect.minY
rect.midY
rect.maxY
rect.isNull
rect.isEmpty
rect.isInfinite
rect.standardized
rect.integral
rect.insetBy(dx: 5.0, dy: -7.0)
rect.offsetBy(dx: 5.0, dy: -7.0)
rect1.union(rect2)
rect1.intersect(rect2)
rect1.contains(rect2)
rect.contains(point)
rect1.intersects(rect2)

Legacy Constant

構造スコープ定数は従来のグローバル定数より優先すべきです。
https://realm.github.io/SwiftLint/legacy_constant.html

// bad
CGRectInfinite
CGPointZero
CGRectZero
CGSizeZero
NSZeroPoint
NSZeroRect
NSZeroSize
CGRectNull
CGFloat(M_PI)
Float(M_PI)

// good
CGRect.infinite
CGPoint.zero
CGRect.zero
CGSize.zero
NSPoint.zero
NSRect.zero
NSSize.zero
CGRect.null
CGFloat.pi
Float.pi

Legacy Constructor

Swiftのコンストラクタは従来のコンビニエンス関数より優先すべきです。
https://realm.github.io/SwiftLint/legacy_constructor.html

// bad
CGPointMake(10, 10)
CGPointMake(xVal, yVal)
CGPointMake(calculateX(), 10)
CGSizeMake(10, 10)
CGSizeMake(aWidth, aHeight)
CGRectMake(0, 0, 10, 10)
CGRectMake(xVal, yVal, width, height)
CGVectorMake(10, 10)
CGVectorMake(deltaX, deltaY)
NSMakePoint(10, 10)
NSMakePoint(xVal, yVal)
NSMakeSize(10, 10)
NSMakeSize(aWidth, aHeight)
NSMakeRect(0, 0, 10, 10)
NSMakeRect(xVal, yVal, width, height)
NSMakeRange(10, 1)
NSMakeRange(loc, len)
UIEdgeInsetsMake(0, 0, 10, 10)
UIEdgeInsetsMake(top, left, bottom, right)
NSEdgeInsetsMake(0, 0, 10, 10)
NSEdgeInsetsMake(top, left, bottom, right)
CGVectorMake(10, 10)
NSMakeRange(10, 1)
UIOffsetMake(0, 10)
UIOffsetMake(horizontal, vertical)

// good
CGPoint(x: 10, y: 10)
CGPoint(x: xValue, y: yValue)
CGSize(width: 10, height: 10)
CGSize(width: aWidth, height: aHeight)
CGRect(x: 0, y: 0, width: 10, height: 10)
CGRect(x: xVal, y: yVal, width: aWidth, height: aHeight)
CGVector(dx: 10, dy: 10)
CGVector(dx: deltaX, dy: deltaY)
NSPoint(x: 10, y: 10)
NSPoint(x: xValue, y: yValue)
NSSize(width: 10, height: 10)
NSSize(width: aWidth, height: aHeight)
NSRect(x: 0, y: 0, width: 10, height: 10)
NSRect(x: xVal, y: yVal, width: aWidth, height: aHeight)
NSRange(location: 10, length: 1)
NSRange(location: loc, length: len)
UIEdgeInsets(top: 0, left: 0, bottom: 10, right: 10)
UIEdgeInsets(top: aTop, left: aLeft, bottom: aBottom, right: aRight)
NSEdgeInsets(top: 0, left: 0, bottom: 10, right: 10)
NSEdgeInsets(top: aTop, left: aLeft, bottom: aBottom, right: aRight)
UIOffset(horizontal: 0, vertical: 10)
UIOffset(horizontal: horizontal, vertical: vertical)

Legacy Hashing

hashValue をオーバーライドするのではなく、 hash(info:) 関数を使うべきです。
https://realm.github.io/SwiftLint/legacy_hashing.html

// bad
struct Foo: Hashable {
    let bar: Int = 10

    public var hashValue: Int {
        return bar
    }
}

// good
struct Foo: Hashable {
    let bar: Int = 10

    func hash(into hasher: inout Hasher) {
        hasher.combine(bar)
    }
}

Legacy NSGeometry Functions

従来の関数より構造体のエクステンションのプロパティとメソッドを使うべきです。
https://realm.github.io/SwiftLint/legacy_nsgeometry_functions.html

// bad
NSWidth(rect)
NSHeight(rect)
NSMinX(rect)
NSMidX(rect)
NSMaxX(rect)
NSMinY(rect)
NSMidY(rect)
NSMaxY(rect)
NSEqualRects(rect1, rect2)
NSEqualSizes(size1, size2)
NSEqualPoints(point1, point2)
NSEdgeInsetsEqual(insets2, insets2)
NSIsEmptyRect(rect)
NSIntegralRect(rect)
NSInsetRect(rect, 10, 5)
NSOffsetRect(rect, -2, 8.3)
NSUnionRect(rect1, rect2)
NSIntersectionRect(rect1, rect2)
NSContainsRect(rect1, rect2)
NSPointInRect(rect, point)
NSIntersectsRect(rect1, rect2)

// good
rect.width
rect.height
rect.minX
rect.midX
rect.maxX
rect.minY
rect.midY
rect.maxY
rect.isEmpty
rect.integral
rect.insetBy(dx: 5.0, dy: -7.0)
rect.offsetBy(dx: 5.0, dy: -7.0)
rect1.union(rect2)
rect1.intersect(rect2)
rect1.contains(rect2)
rect.contains(point)
rect1.intersects(rect2)

Line Length

1行にはあまりにも多くの文字を含めるべきではありません。
https://realm.github.io/SwiftLint/line_length.html

Mark

MARK コメントは有効な形式であるべきです。
https://realm.github.io/SwiftLint/mark

// bad
//MARK: bad
// MARK:bad
// MARK: -bad
// MARK:- bad
// MARK bad

// good
// MARK: good
// MARK: - good
// MARK: -

Multiple Closures with Trailing Closure

複数のクロージャを引数とする場合、トレイリングクロージャを使うべきではありません。
https://realm.github.io/SwiftLint/multiple_closures_with_trailing_closure.html

// bad
foo.something(param1: { $0 }) { $0 + 1 }

// good
foo.something(param1: { $0 }, param2: { $0 + 1 })

Nesting

型は最大1レベル、ステートメントは最大5レベルの深さでネストすべきです。
https://realm.github.io/SwiftLint/nesting

// bad
class A { class B { class C { } } }

// good
class A { class B { } }

No Fallthrough Only

case に少なくとも1つのステートメントが含まれている場合のみ、fallthrouth を使うべきです。
https://realm.github.io/SwiftLint/no_fallthrough_only.html

// bad
switch myvar {
case 1:
    fallthrough
case 2:
    var a = 2
}

// good
switch myvar {
case 1:
    var a = 1
    fallthrough
case 2:
    var a = 2
}
switch myvar {
case 1, 2:
    var a = 2
}

Notification Center Detachment

オブジェクトは deinit でのみ自分自身のオブザーバを削除すべきです。
https://realm.github.io/SwiftLint/notification_center_detachment.html

// bad
class Foo {
    func bar() {
        NotificationCenter.default.removeObserver(self)
    }
}

// good
class Foo {
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
}

Opening Brace Spacing

{ は定義と同じ行で前に1つの半角スペースを置くべきです。
https://realm.github.io/SwiftLint/opening_brace_spacing.html

// bad
func abc(){
}
func abc()
{
}

// good
func abc() {
}

Operator Function Whitespace

演算子の定義時、1つの半角スペースで囲まれるべきです。
https://realm.github.io/SwiftLint/operator_function_whitespace.html

// bad
func <|(lhs: Int, rhs: Int) -> Int { }
func <|  (lhs: Int, rhs: Int) -> Int { }

// good
func <| (lhs: Int, rhs: Int) -> Int { }

Private over fileprivate

fileprivate より private を使うべきです。
https://realm.github.io/SwiftLint/private_over_fileprivate.html

// TODO: 例を見ても法則がわからない。。

Private Unit Test

private の単体テストは暗黙のうちにスキップされます。
https://realm.github.io/SwiftLint/private_unit_test.html

// bad
private class FooTests: XCTestCase {
   func test1() { }
}

class FooTests: XCTestCase {
    // bad
    private func test1() { }

    // good
    func test1() { }
 }

Protocol Property Accessors Order

プロトコルでプロパティを定義するときは、アクセサの順番を「ゲッター→セッター」とすべきです。
https://realm.github.io/SwiftLint/prohibited_calls_to_super.html

protocol Foo {
    // bad
    var bar: String { set get }

    // good
    var bar: String { set }
    var bar: String { get }
    var bar: String { get set }
}

Redundant Discardable Let

関数の戻り値を使わずに実行する場合、 let _ = foo() より _ = foo() を使うべきです。
https://realm.github.io/SwiftLint/redundant_discardable_let.html

// bad
let _ = foo()
if let _ = foo() { }
guard let _ = foo() else { return }

// good
_ = foo()

Redundant @objc Attribute

冗長な @objc 属性は避けるべきです。
https://realm.github.io/SwiftLint/redundant_objc_attribute.html

// bad
@objc @IBAction private func foo(_ sender: Any) { }

// good
@IBAction private func foo(_ sender: Any) { }

Redundant Optional Initialization

オプショナル型の変数を nil で初期化するのは冗長です。
https://realm.github.io/SwiftLint/redundant_optional_initialization.html

// bad
var myVar: Int? = nil

// good
var myVar: Int?
let myVar: Int? = nil
var myVar: Int? = 0

Redundant Set Access Control Rule

プロパティのセッターのアクセスレベルは、変数のアクセスレベルと同様であれば明示的に指定すべきではありません。
https://realm.github.io/SwiftLint/redundant_set_access_control_rule.html

// bad
private(set) private var foo: Int

// good
private(set) public var foo: Int

Redundant String Enum Value

文字列の列挙型の値は、ケースと同名なら省略できます。
https://realm.github.io/SwiftLint/redundant_string_enum_value.html

// bad
enum Numbers: String {
  case one = "one"
  case two = "two"
}

// good
enum Numbers: String {
  case one
  case two
}
enum Numbers: String {
  case one = "ONE"
  case two = "TWO"
}

Redundant Void Return

関数の定義で Void を返すのは冗長です。
https://realm.github.io/SwiftLint/redundant_void_return.html

// bad
func foo() -> Void { }
func foo() -> () { }

// good
func foo() { }
let foo: Int -> Void

Returning Whitespace

戻り値の矢印と型は1つの半角スペースまたは別の行で区切るべきです。
https://realm.github.io/SwiftLint/returning_whitespace.html

// bad
func abc()-> Int { }
func abc() ->Int { }
func abc()->Int { }

// good
func abc() -> Int { }
func abc()
    -> Int { }
func abc() ->
    Int { }

Shorthand Operator

省略形の演算子を使うべきです。
https://realm.github.io/SwiftLint/shorthand_operator.html

// bad
foo = foo + 1
foo = foo - 1
foo = foo * 1
foo = foo / 1

// good
foo += 1
foo -= 1
foo *= 1
foo /= 1

Statement Position

elsecatch は、前の定義の1つの半角スペースの後ろで同じ行にあるべきです。
https://realm.github.io/SwiftLint/statement_position.html

// bad
}else {

}
catch {

// good
} else {

} catch {

Superfluous Disable Command

無効化されたルールが無効化された領域で違反を起こさなかった場合、SwiftLintの disable コマンドは不要です。
https://realm.github.io/SwiftLint/superfluous_disable_command.html

Switch and Case Statement Alignment

case 文はそれを囲む switch 文と同じインデントにすべきです。
https://realm.github.io/SwiftLint/switch_and_case_statement_alignment.html

// bad
switch someBool {
    case true:
        print("red")
    case false:
        print("blue")
}

// good
switch someBool {
case true:
    print("red")
case false:
    print("blue")
}

Syntactic Sugar

糖衣構文を使うべきです。
https://realm.github.io/SwiftLint/syntactic_sugar.html

// bad
let x: Array<String>
let x: Dictionary<Int, String>
let x: Optional<Int>
let x: ImplicitlyUnwrappedOptional<Int>

// good
let x: [String]
let x: [Int: String]
let x: Int?
let x: Int!

Todo

TODOFIXME は解決すべきです。
https://realm.github.io/SwiftLint/todo

// bad
// TODO:
// FIXME:

Trailing Comma

配列やディクショナリの末尾のカンマは避けるべきです。
https://realm.github.io/SwiftLint/trailing_comma.html

// bad
let array = [1, 2, 3,]
let dictionary = ["foo": 1, "bar": 2,]

// good
let array = [1, 2, 3]
let dictionary = ["foo": 1, "bar": 2]

Trailing Newline

ファイルは末尾に1つの改行を持つべきです。
https://realm.github.io/SwiftLint/trailing_newline.html

Trailing Semicolon

行の末尾にセミコロンを付けるべきではありません。
https://realm.github.io/SwiftLint/trailing_semicolon.html

// bad
let a = 0;

// good
let a = 0

Trailing Whitespace

行の末尾に半角スペースを付けるべきではありません。
https://realm.github.io/SwiftLint/trailing_whitespace.html

// bad
let a = 1

// good
let a = 1

Type Body Length

型内はあまりにも多くの行にまたがるべきではないです。
https://realm.github.io/SwiftLint/type_body_length.html

Type Name

型名は英数のみを含み、大文字で始まり、3〜40文字にすべきです。
https://realm.github.io/SwiftLint/type_name.html

// bad
class My_Type { }
class myType { }
class aa { }

// good
class MyType { }

Unneeded Break in Switch

不要な break は避けるべきです。
https://realm.github.io/SwiftLint/unneeded_break_in_switch.html

switch a {
// bad
case .foo:
    something()
    break

// good
case .bar:
    something()
case .baz:
    break
case .qux:
    for i in [0, 1, 2] { break }
}

Unused Closure Parameter

クロージャで使われていないパラメータは _ に置き換えるべきです。
https://realm.github.io/SwiftLint/unused_closure_parameter.html

// bad
[1, 2].map { number in
    3
}

// good
[1, 2].map { _ in
    3
}
[1, 2].map { number in
    number + 1
}
[1, 2].map { $0 + 1 }

Unused Control Flow Label

未使用の制御フローラベルは削除すべきです。
https://realm.github.io/SwiftLint/unused_control_flow_label.html

// bad
loop: while true { break }

// good
loop: while true { break loop }
loop: while true { continue loop }

Unused Enumerated

インデックスまたはアイテムが使われていない場合、 .enumerated() を削除できます。
https://realm.github.io/SwiftLint/unused_enumerated.html

// TODO: わからない。。

Unused Optional Binding

let _ = より != nil を使うべきです。
https://realm.github.io/SwiftLint/unused_optional_binding.html

// bad
if let _ = a { }

// good
if a != nil { }

Unused Setter Value

セッターの値は使われるべきです。
https://realm.github.io/SwiftLint/unused_setter_value.html

var aValue: String {
    get {
        return Persister.shared.aValue
    }
    set {
        // bad
        Persister.shared.aValue = aValue
        // good
        Persister.shared.aValue = newValue
    }
    // bad
    set { }
}

Valid IBInspectable

@IBInspectable はサポートされている型の変数のみに使い、その型を明示的にすべきです。
https://realm.github.io/SwiftLint/valid_ibinspectable.html

class Foo {
    // bad
    @IBInspectable private let count: Int
    @IBInspectable private var count = 0
    @IBInspectable private var count: Int?
    @IBInspectable private var count: Int!

    // good
    @IBInspectable private var count: Int
    @IBInspectable private var count: Int = 0
}

Vertical Parameter Alignment

関数の定義時、パラメータが複数行にまたがっている場合は垂直方向に揃えるべきです。
https://realm.github.io/SwiftLint/vertical_parameter_alignment.html

// bad
func validateFunction(_ file: File, kind: SwiftDeclarationKind,
                    dictionary: [String: SourceKitRepresentable]) { }
func validateFunction(_ file: File, kind: SwiftDeclarationKind,
                       dictionary: [String: SourceKitRepresentable]) { }

// good
func validateFunction(_ file: File, kind: SwiftDeclarationKind,
                      dictionary: [String: SourceKitRepresentable]) { }

Vertical Whitespace

空白行は1行に制限します。
https://realm.github.io/SwiftLint/vertical_whitespace.html

Void Return

-> () より -> Void を使うべきです。
https://realm.github.io/SwiftLint/void_return.html

// bad
let abc: () -> () = { }

// good
let abc: () -> Void = { }

Weak Computed Property

コンピューテッドプロパティに weak を追加しても効果はありません。
https://realm.github.io/SwiftLint/weak_computed_property.html

class Foo {
    private weak var _delegate: SomeProtocol?

    // bad
    weak var delegate: SomeProtocol? {
    // good
    var delegate: SomeProtocol? {
    get { return _delegate }
    set { _delegate = newValue }
    }
}

Weak Delegate

デリゲートは循環参照を避けるために弱参照とすべきです。
https://realm.github.io/SwiftLint/weak_delegate.html

class Foo {
    // bad
    var delegate: SomeProtocol?

    // good
    weak var delegate: SomeProtocol?
}

XCTFail Message

XCTFail の呼び出しにはアサーションの説明を含めるべきです。
https://realm.github.io/SwiftLint/xctfail_message.html

func testFoo() {
    // bad
    XCTFail()

    // good
    XCTFail("bar")
}

Opt-in

デフォルトで無効になっているルールの一覧です。

AnyObject Protocol

クラス専用のプロトコルでは、 class より AnyObject を使うべきです。
https://realm.github.io/SwiftLint/anyobject_protocol.html

// bad
protocol SomeClassOnlyProtocol: class { }

// good
protocol SomeClassOnlyProtocol: AnyObject { }

Array Init

シーケンスを配列に変換する場合、 seq.map { $0 } より Array(seq) を使うべきです。
https://realm.github.io/SwiftLint/array_init.html

// bad
seq.map { $0 }

// good
Array(seq)

Attributes

属性は関数や型では別の行にあるべきですが、変数やインポートでは同じ行にあるべきです。
https://realm.github.io/SwiftLint/attributes

// bad
@available(iOS 9.0, *) func animate(view: UIStackView)

@available(iOS 9.0, *) class UIStackView

@objc
var x: String

@testable
import SourceKittenFramework

// good
@available(iOS 9.0, *)
func animate(view: UIStackView)

@available(iOS 9.0, *)
class UIStackView

@objc var x: String

@testable import SourceKittenFramework

Closure Body Length

クロージャ内はあまりにも多くの行にまたがるべきではないです。
https://realm.github.io/SwiftLint/closure_body_length.html

// bad
foo.bar { toto in
let a = 0
let a = 0
let a = 0
let a = 0
let a = 0
let a = 0
let a = 0
let a = 0
let a = 0
let a = 0
let a = 0
let a = 0
let a = 0
let a = 0
let a = 0
let a = 0
let a = 0
let a = 0
let a = 0
let a = 0
let a = 0
}

// good
foo.bar { $0 }
foo.bar { toto in
}

Closure End Indentation

クロージャの終了は開始と同様のインデントを持つべきです。
https://realm.github.io/SwiftLint/closure_end_indentation.html

// bad
SignalProducer(values: [1, 2, 3])
    .startWithNext { number in
        print(number)
}

// good
SignalProducer(values: [1, 2, 3])
    .startWithNext { number in
        print(number)
    }
[1, 2].map { $0 + 1 }

Closure Spacing

クロージャ内は各括弧の内側に1つの半角スペースがあるべきです。
https://realm.github.io/SwiftLint/closure_spacing.html

// bad
[].filter {$0.contains(location)}

// good
[].filter { $0.contains(location) }

Collection Element Alignment

コレクション内の全要素は垂直方向に揃うべきです。
https://realm.github.io/SwiftLint/collection_element_alignment.html

// bad
let abc = [
    "alpha": "a",
      "beta": "b",
    "gamma": "g",
    "delta": "d",
   "epsilon": "e"
]

// good
let abc = [
    "alpha": "a",
    "beta": "b",
    "gamma": "g",
    "delta": "d",
    "epsilon": "e"
]

let abc = [1, 2, 3, 4]

let abc = [
    1, 2, 3, 4
]

Conditional Returns on Newline

条件文では次の行でリターンすべきです。
https://realm.github.io/SwiftLint/conditional_returns_on_newline.html

// bad
guard true else { return }

// good
guard true else {
    return true
}

Contains over first not nil

first(where:) != nil より contains を使うべきです。
https://realm.github.io/SwiftLint/contains_over_first_not_nil.html

// bad
myList.first { $0 % 2 == 0 } != nil
myList.first(where: { $0 % 2 == 0 }) != nil

// good
myList.contains { $0 % 2 == 0 }
myList.contains(where: { $0 % 2 == 0 })

Convenience Type

静的メンバーのみをホストするために使われる型は、インスタンス化を回避するために、case のない列挙型として実装すべきです。
https://realm.github.io/SwiftLint/convenience_type.html

// bad
struct Math {
    public static let pi = 3.14
}
class Math {
    public static let pi = 3.14
}

// good
enum Math {
    public static let pi = 3.14
}

// 継承を伴う場合はOK
class MathViewController: UIViewController {
    public static let pi = 3.14
}

// Obj-Cに見えるクラスはOK
@objc class Math: NSObject {
    public static let pi = 3.14
}

// 静的でない型もある場合はOK
struct Math {
    public static let pi = 3.14
    public let randomNumber = 2
}

Discouraged Object Literal

オブジェクトリテラルよりイニシャライザを使うべきです。
https://realm.github.io/SwiftLint/discouraged_object_literal.html

// bad
let image = #imageLiteral(resourceName: "image.jpg")
let color = #colorLiteral(red: value, green: value, blue: value, alpha: 1)

// good
let image = UIImage(named: "image")
let color = UIColor(red: value, green: value, blue: value, alpha: 1)

Discouraged Optional Boolean

オプショナル型よりそうでない Bool 型を使うべきです。
https://realm.github.io/SwiftLint/discouraged_optional_boolean.html

// bad
var foo: Bool?

// good
var foo: Bool

Discouraged Optional Collection

オプショナルのコレクションより空のコレクションを使うべきです。
https://realm.github.io/SwiftLint/discouraged_optional_collection.html

// bad
var foo: [Int]?
var foo: [String: Int]?
let foo: [Int]? = nil
let foo: [String: Int]? = nil

// good
var foo: [Int]
var foo: [String: Int]
let foo: [Int] = []
let foo: [String: Int] = [:]

Empty Count

count0 と比較するより isEmpty を使うべきです。
https://realm.github.io/SwiftLint/empty_count.html

// bad
[Int]().count == 0
[Int]().count > 0
[Int]().count != 0

// good
[Int]().isEmpty

Empty String

空の文字列と比較するより isEmpty を使うべきです。
https://realm.github.io/SwiftLint/empty_string.html

// bad
myString == ""
myString != ""

// good
myString.isEmpty
!myString.isEmpty

Empty XCTest Method

空のXCTestメソッドを実装すべきではありません。
https://realm.github.io/SwiftLint/empty_xctest_method.html

// bad
class TotoTests: XCTestCase {

    override func setUp() {
    }

    override func tearDown() {
    }

    func testFoo() {
    }

}

// good
class TotoTests: XCTestCase {

    var foobar: Foobar?

    override func setUp() {
        super.setUp()
        foobar = Foobar()
    }

    override func tearDown() {
        foobar = nil
        super.tearDown()
    }

    func testFoo() {
        XCTAssertTrue(foobar?.foo)
    }

    func helperFunction() {
    }
}

Explicit ACL

全ての定義はアクセス制御レベルのキーワードを明示的に指定すべきです。
https://realm.github.io/SwiftLint/explicit_acl.html

// bad
enum A { }

// good
internal enum A { }

Explicit Enum Raw Value

列挙型はローバリューを明示的に割り当てるべきです。
https://realm.github.io/SwiftLint/explicit_enum_raw_value.html

// bad
enum Numbers: Int {
    case one
    case two
}

// good
enum Numbers: Int {
    case one = 1
    case two = 2
}

Explicit Init

.init() を明示的に呼び出すべきではありません。
https://realm.github.io/SwiftLint/explicit_init.html

// bad
[1].flatMap { String.init($0) }
[String.self].map { Type in Type.init(1) }

// good
[1].flatMap(String.init)
[String.self].map { $0.init(1) }
[String.self].map { type in type.init(1) }

Explicit Self

インスタンス変数と関数は self. で明示的にアクセスされるべきです。
https://realm.github.io/SwiftLint/explicit_self.html

struct A {
    let p1: Int
    func f1() { }
    func f2() {
        // bad
        f1()
        _ = p1

        // good
        self.f1()
        _ = self.p1
    }
}

Explicit Top Level ACL

最上位の定義はアクセス制御レベルを明示的に指定すべきです。
https://realm.github.io/SwiftLint/explicit_top_level_acl.html

// bad
enum A {
    enum B { }
}

// good
internal enum A {
    enum B { }
}

Explicit Type Interface

プロパティは型インターフェースを持つべきです。
https://realm.github.io/SwiftLint/explicit_type_interface.html

class Foo {
    // bad
    var myVar = 0

    // good
    var myVar: Int? = 0
}

Extension Access Modifier

エクステンションにはアクセス修飾子を使うべきです。
https://realm.github.io/SwiftLint/explicit_type_interface.html

// bad
extension Foo {
    public var bar: Int { return 1 }
    public var baz: Int { return 1 }
}

// good
public extension Foo {
    var bar: Int { return 1 }
    var baz: Int { return 1 }
}

Fallthrough

fallthrough は使うべきではありません。
https://realm.github.io/SwiftLint/fallthrough

// bad
switch foo {
case .bar:
    fallthrough
case .bar2:
    something()
}

// good
switch foo {
case .bar, .bar2:
    something()
}

Fatal Error Message

fatalError はメッセージを付けて呼び出すべきです。
https://realm.github.io/SwiftLint/fatal_error_message.html

// bad
func foo() {
    fatalError()
}

// good
func foo() {
    fatalError("Foo")
}

File Header

// TODO: 例を見ても法則がわからない。。

File Name

ファイル名はファイル内で定義されている型またはエクステンションと一致すべきです。
https://realm.github.io/SwiftLint/file_name.html

First Where

コレクションでは .filter {} .first より .first(where:) を使うべきです。
https://realm.github.io/SwiftLint/first_where.html

// bad
myList.filter { $0 % 2 == 0 } .first

// good
myList.first(where: { $0 % 2 == 0 })
myList.first { $0 % 2 == 0 }

Force Unwrapping

強制アンラップ( ! )は使うべきではありません。
https://realm.github.io/SwiftLint/force_unwrapping.html

// bad
let url = NSURL(string: query)!

// good
if let url = NSURL(string: query) { }

Function Default Parameter at End

関数でデフォルト値を持つ引数は後ろにまとめるべきです。
https://realm.github.io/SwiftLint/function_default_parameter_at_end.html

// bad
func foo(y: Int = 0, x: String, z: CGFloat = 0) { }

// good
func foo(x: String, y: Int = 0, z: CGFloat = 0) { }

Identical Operands

同一のオペランドを比較するのはおそらく間違いです。
https://realm.github.io/SwiftLint/identical_operands.html

// bad
foo == foo

// good
foo == bar

Implicit Return

クロージャでは暗黙のリターンを優先すべきです。
https://realm.github.io/SwiftLint/implicit_return.html

// bad
foo.map {
    return $0 + 1
}

// good
foo.map { $0 + 1 }

Implicitly Unwrapped Optional

暗黙的にアンラップされるオプショナル型はできる限り使うべきではありません。
https://realm.github.io/SwiftLint/implicitly_unwrapped_optional.html

// bad
private var label: UILabel!
let int: Int! = 42

// good
@IBOutlet private var label: UILabel!
let int: Int? = 42

Joined Default Parameter

デフォルトの区切り文字は明示的に使うべきではありません。
https://realm.github.io/SwiftLint/joined_default_parameter.html

// bad
let foo = bar.joined(separator: "")

// good
let foo = bar.joined()
let foo = bar.joined(separator: ",")

Last Where

コレクションでは .filter {} .last より .last(where:) を使うべきです。
https://realm.github.io/SwiftLint/last_where.html

// bad
myList.filter { $0 % 2 == 0 } .last

// good
myList.last(where: { $0 % 2 == 0 })

Legacy Random

従来の関数より type.ramdom(in:) を使うべきです。
https://realm.github.io/SwiftLint/legacy_random.html

// bad
arc4random(10)
arc4random_uniform(83)
drand48(52)

// good
Int.random(in: 0..<10)
Double.random(in: 8.6...111.34)
Float.random(in: 0..<1)

Variable Declaration Whitespace

letvar は他のステートメントと空白行で区切るべきです。
https://realm.github.io/SwiftLint/variable_declaration_whitespace.html

// bad
let a = 0
var x = 1
x = 2

// good
let a = 0
var x = 1

x = 2

Literal Expression End Indentation

配列とディクショナリのリテラルの末尾は、開始行と同様のインデントを持つべきです。
https://realm.github.io/SwiftLint/literal_expression_end_indentation.html

// bad
let x = [
    1,
    2
    ]

// good
[1, 2, 3]
let x = [
    1,
    2
]
let x = [1,
    2
]
let x = [
    1,
    2]

Lower ACL than parent

定義が親よりも低いまたは同じアクセス制御レベルを持つようにすべきです。
https://realm.github.io/SwiftLint/lower_acl_than_parent.html

// bad
struct Foo {
    public func bar() { }
}

// good
public struct Foo {
    public func bar() { }
}

Missing Docs

定義はドキュメント化すべきです。
https://realm.github.io/SwiftLint/missing_docs.html

// good
/// docs
public class A {
    /// docs
    public func b() { }
}
/// docs
public class B: A {
    // オーバーライドメソッドはOK
    override public func b() { }
}

Modifier Order

修飾子の順番は一貫しているべきです。
https://realm.github.io/SwiftLint/modifier_order.html

public class Foo {
    // bad
    convenience required public init() { }
    static public let bar = 42

    // good
    public convenience required init() { }
    public static let bar = 42
}

Multiline Arguments

引数は同じ行に入れるか1行に1つずつ入れるべきです。
https://realm.github.io/SwiftLint/multiline_arguments.html

// bad
func foo(
    param1: "Param1", param2: "Param2",
    param3: "Param3"
)

// good
func foo(param1: "Param1", param2: "Param2", param3: "Param3")
func foo(
    param1: "Param1",
    param2: "Param2",
    param3: "Param3"
)

Multiline Arguments Brackets

複数行の引数は、それらを括る大括弧を新しい行に持つべきです。
https://realm.github.io/SwiftLint/multiline_arguments_brackets.html

// bad
foo(param1: "Param1",
    param2: "Param2"
)
foo(
    param1: "Param1",
    param2: "Param2")

// good
foo(param1: "Param1", param2: "Param2")
foo(
    param1: "Param1",
    param2: "Param2"
)

Multiline Function Chains

関数を連鎖的に呼び出す場合、同じ行に入れるか1行に1つずつ入れるべきです。
https://realm.github.io/SwiftLint/multiline_function_chains.html

// bad
let evenSquaresSum = [20, 17, 35, 4]
    .filter { $0 % 2 == 0 } .map { $0 * $0 }
    .reduce(0, +)

// good
let evenSquaresSum = [20, 17, 35, 4].filter { $0 % 2 == 0 } .map { $0 * $0 } .reduce(0, +)
let evenSquaresSum = [20, 17, 35, 4]
    .filter { $0 % 2 == 0 }
    .map { $0 * $0 }
    .reduce(0, +)

Multiline Literal Brackets

複数行のリテラルは、新しい行にそれを括る大括弧を入れるべきです。
https://realm.github.io/SwiftLint/multiline_literal_brackets.html

// bad
let trio = ["harry",
            "ronald",
            "hermione"
]
let trio = [
    "harry",
    "ronald",
    "hermione"]

// good
let trio = ["harry", "ronald", "hermione"]
let trio = [
    "harry",
    "ronald",
    "hermione"
]

Multiline Parameters

関数とメソッドの引数は、同様の行にあるか1行に1つずつあるべきです。
https://realm.github.io/SwiftLint/multiline_parameters.html

// bad
func foo(param1: Int, param2: Bool,
         param3: [String]) { }

// good
func foo(param1: Int, param2: Bool, param3: [String]) { }
func foo(param1: Int,
         param2: Bool,
         param3: [String]) { }

Multiline Parameters Brackets

複数行の引数は、新しい行にそれを括る大括弧を入れるべきです。
https://realm.github.io/SwiftLint/multiline_parameters_brackets.html

// bad
func foo(param1: "Param1",
         param2: "Param2",
         param3: "Param3"
)
func foo(
    param1: "Param1",
    param2: "Param2",
    param3: "Param3")

// good
func foo(param1: "Param1", param2: "Param2", param3: "Param3")
func foo(
    param1: "Param1",
    param2: "Param2",
    param3: "Param3"
)

Nimble Operator

フリーのmatcher関数よりNimble演算子のオーバーロードを使うべきです。
https://realm.github.io/SwiftLint/nimble_operator.html

//bad
expect(seagull.squawk).to(equal("Hi"))
expect(seagull.squawk).toNot(equal("Hi"))
expect(10).to(beGreaterThan(2))

// good
expect(seagull.squawk) == "Hi!"
expect(seagull.squawk) != "Hi!"
expect(10) > 2

No Extension Access Modifier

エクステンションにアクセス修飾子を付けるべきではありません。
https://realm.github.io/SwiftLint/no_extension_access_modifier.html

// bad
private extension String { }
fileprivate extension String { }
internal extension String { }
public extension String { }
open extension String { }

// good
extension String { }

No Grouping Extension

エクステンションは同じソースファイル内のコードをグループ化するために使うべきではありません。
https://realm.github.io/SwiftLint/no_grouping_extension.html

// bad
enum Fruit { }
extension Fruit { }

// good
// プロトコルのデフォルト実装はOK
protocol Food { }
extension Food { }

NSLocalizedString Key

genstringsが機能するためには、静的文字列を NSLocalizedString のキーとして使うべきです。
https://realm.github.io/SwiftLint/nslocalizedstring_key.html

// bad
NSLocalizedString(method(), comment: nil)

// good
NSLocalizedString("key", comment: nil)

Number Separator

_ は十進数で千の区切り文字として使うべきです。

// bad
let foo = 1000
let foo = 1000_000.000_000_1
let foo = 1_000_000.000000_1
let foo = 1_0_00_000.000_000_1

// good
let foo = 1_000
let foo = 1_000_000.000_000_1

Object Literal

画像や色はイニシャライザよりリテラルを使って生成すべきです。
https://realm.github.io/SwiftLint/object_literal.html

// bad
let image = UIImage(named: "image")
let color = UIColor(red: 0.9607843161, green: 0.7058823705, blue: 0.200000003, alpha: 1.0)

// good
let image = #imageLiteral(resourceName: "image.jpg")
let color = #colorLiteral(red: 0.9607843161, green: 0.7058823705, blue: 0.200000003, alpha: 1.0)

Operator Usage Whitespace

演算子を使うときは1つの半角スペースで囲まれるべきです。
https://realm.github.io/SwiftLint/operator_usage_whitespace.html

// bad
let foo = 1+2
let foo=1+2

// good
let foo = 1 + 2

Overridden methods call super

一部のオーバーライドメソッドは常に親クラスのメソッドを呼び出すべきです。
https://realm.github.io/SwiftLint/overridden_methods_call_super.html

// bad
class VC: UIViewController {
    override func viewWillAppear(_ animated: Bool) {
    }
}

// good
class VC: UIViewController {
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
    }
    override func loadView() {
    }
}

Override in Extension

エクステンションでは定義をオーバーライドすべきではありません。
https://realm.github.io/SwiftLint/override_in_extension.html

extension Person {
    // good
    var age: Int { return 42 }
    func celebrateBirthday() { }

    // bad
    override var age: Int { return 42 }
    override func celebrateBirthday() { }
}

Pattern Matching Keywords

キーワードをタプルの外に出し、複数のパターンマッチングバインディングを組み合わせるべきです。
https://realm.github.io/SwiftLint/pattern_matching_keywords.html

switch foo {
  // bad
  case (let x, let y):

  // good
  case let (x, y):
}

Prefixed Top-Level Constant

最上位の定数はプリフィックスに k を付けるべきです。
https://realm.github.io/SwiftLint/prefixed_top_level_constant.html

// bad
let bar = 20.0

// good
let kBar = 20.0
struct Foo {
    let bar = 20.0
}

Private Actions

@IBActionprivate にすべきです。
https://realm.github.io/SwiftLint/private_actions.html

// bad
class Foo {
    @IBAction func barButtonTapped(_ sender: UIButton) { }
}

// good
class Foo {
    @IBAction private func barButtonTapped(_ sender: UIButton) { }
}

Private Outlets

@IBOutletprivate にすべきです。
∵上位レイヤーへ UIKit が漏洩するのを防ぐため
https://realm.github.io/SwiftLint/private_outlets.html

// bad
class Foo {
    @IBOutlet var label: UILabel?
}

// good
class Foo {
    @IBOutlet private var label: UILabel?
}

Prohibited Interface Builder

IBを使ってビューを生成するのは避けるべきです。
https://realm.github.io/SwiftLint/prohibited_interface_builder.html

class ViewController: UIViewController {
    // bad
    @IBOutlet var label: UILabel!
    @IBAction func buttonTapped(_ sender: UIButton) { }

    // good
    var label: UILabel!
    @objc func buttonTapped(_ sender: UIButton) { }
}

Prohibited calls to super

一部のメソッドは親クラスのメソッドを呼び出してはいけません。
https://realm.github.io/SwiftLint/prohibited_calls_to_super.html

// bad
class VC: UIViewController {
    override func loadView() {
        super.loadView()
    }
}

Quick Discouraged Call

describecontext 内で処理を呼び出すべきではありません。
https://realm.github.io/SwiftLint/quick_discouraged_call.html

class TotoTests: QuickSpec {
    override func spec() {
        describe("foo") {
            // bad
            let foo = Foo()
            context("foo") {
                // bad
                foo.bar()
                it("does something") {
                    // good
                    let foo = Foo()
                    foo.bar()
                }
            }
        }
    }
}

Quick Discouraged Focused Test

一部のみ有効となるテストは実行すべきではありません。
https://realm.github.io/SwiftLint/quick_discouraged_focused_test.html

class TotoTests: QuickSpec {
    override func spec() {
        // bad
        fdescribe("foo") { }
        fcontext("foo") { }
        fit("foo") { }
        fitBehavesLike("foo")

        // good
        describe("foo") { }
        context("foo") { }
        it("foo") { }
        itBehavesLike("foo")
    }
}

Quick Discouraged Pending Test

一部のみ無効となるテストは実行すべきではありません。
https://realm.github.io/SwiftLint/quick_discouraged_pending_test.html

class TotoTests: QuickSpec {
    override func spec() {
        // bad
        xdescribe("foo") { }
        xcontext("foo") { }
        xit("foo") { }
        pending("foo")
        xitBehavesLike("foo")

        // good
        describe("foo") { }
        context("foo") { }
        it("foo") { }
        itBehavesLike("foo")
    }
}

Redundant Nil Coalescing

?? 演算子は左辺が nil の場合のみ評価されるため、右辺に nil を記述するのは冗長です。
https://realm.github.io/SwiftLint/redundant_nil_coalescing.html

// bad
var myVar: Int? = nil
myVar ?? nil

// good
var myVar: Int?
myVar ?? 0

Redundant Type Annotation

変数は冗長な型アノテーションを持つべきではありません。
https://realm.github.io/SwiftLint/redundant_type_annotation.html

// bad
var url: URL = URL()

// good
var url = URL()
var url: CustomStringConvertible = URL()

Required Deinit

クラスは明示的な deinit メソッドを持つべきです。
https://realm.github.io/SwiftLint/required_deinit.html

// bad
class Apple { }

// good
class Apple {
    deinit { }
}

Required Enum Case

特定のプロトコルに準拠した列挙型は特定のケースを実装する必要があります。
https://realm.github.io/SwiftLint/required_enum_case.html

// bad
enum MyNetworkResponse: String, NetworkResponsable {
  case success
  case error
}

// good
enum MyNetworkResponse: String, NetworkResponsable {
  case success
  case error
  case notConnected
}
enum MyNetworkResponse: String, NetworkResponsable {
  case success
  case error
  case notConnected(error: Error)
}

Single Test Class

テストファイルは単一の QuickSpec または XCTestCase クラスを含むべきです。
https://realm.github.io/SwiftLint/single_test_class.html

// bad
class FooTests: QuickSpec { }
class BarTests: QuickSpec { }

class FooTests: XCTestCase { }
class BarTests: XCTestCase { }

class FooTests: XCTestCase { }
class BarTests: QuickSpec { }

// good
class FooTests: XCTestCase { }

class FooTests: QuickSpec { }

Min or Max over Sorted First or Last

sorted().firstsorted().last より min()max() を使うべきです。
https://realm.github.io/SwiftLint/min-or-max-over-sorted-first-or-last

// bad
myList.sorted().first
myList.sorted().last
let min = myList.sorted(by: >).first

// good
myList.min()
myList.max()
let min = myList.min(by: >)

Sorted Imports

インポート文はソートされるべきです。
https://realm.github.io/SwiftLint/sorted_imports.html

// bad
import AAA
import CCC
import BBB
import DDD

// good
import AAA
import BBB
import CCC
import DDD

Static Operator

演算子は自由関数でなく静的関数として定義すべきです。
https://realm.github.io/SwiftLint/static_operator.html

// bad
func == (lhs: A, rhs: A) -> Bool {
    return false
}
func == <T>(lhs: A<T>, rhs: A<T>) -> Bool {
    return false
}

// good
class A: Equatable {
    static func == (lhs: A, rhs: A) -> Bool {
        return false
    }
}
class A<T>: Equatable {
    static func == <T>(lhs: A<T>, rhs: A<T>) -> Bool {
        return false
    }
}

Strict fileprivate

fileprivate は避けるべきです。
https://realm.github.io/SwiftLint/strict_fileprivate.html

// bad
fileprivate extension String { }

extension String {
    fileprivate func Something() { }
}

// good
private extension String { }

extension String {
    func Something() { }
}

Strong IBOutlet

@IBOutlet は弱参照で定義すべきではありません。
https://realm.github.io/SwiftLint/strong_iboutlet.html

// bad
class ViewController: UIViewController {
    @IBOutlet weak var label: UILabel?
    @IBOutlet unowned var label: UILabel!
}

// good
class ViewController: UIViewController {
    @IBOutlet var label: UILabel?
    weak var label: UILabel!
}

Switch Case on Newline

switch 文の中の case 文は常に改行すべきです。
https://realm.github.io/SwiftLint/switch_case_on_newline.html

// bad
switch foo {
case 1: return true
}

// good
switch foo {
case 1:
    return true
}

Toggle Bool

someBool = !someBool より someBool.toggle() を使うべきです。
https://realm.github.io/SwiftLint/toggle_bool.html

// bad
isHidden = !isHidden

// good
isHidden.toggle()

Trailing Closure

できる限りトレイリングクロージャを使うべきです。
https://realm.github.io/SwiftLint/trailing_closure.html

// bad
foo.map({ $0 + 1 })
foo.reduce(0, combine: { $0 + 1 })

// good
foo.map { $0 + 1 }
foo.reduce(0) { $0 + 1 }

Unavailable Function

未実装の関数は使用不可としてマークされるべきです。
https://realm.github.io/SwiftLint/unavailable_function.html

// bad
class ViewController: UIViewController {
    public required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

// good
class ViewController: UIViewController {
    @available(*, unavailable)
    public required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

Unneeded Parentheses in Closure Argument

クロージャ引数の定義時に括弧は不要です。
https://realm.github.io/SwiftLint/unneeded_parentheses_in_closure_argument.html

// bad
let foo = { (bar) in }
let foo = { (bar, _)  in }

// good
let foo = { (bar: Int) in }
let foo = { bar in }
let foo = { bar, _ in }

Untyped Error in Catch

catch 文は型キャストなしでエラー変数を定義すべきではありません。
https://realm.github.io/SwiftLint/untyped_error_in_catch.html

// bad
do {
    try foo()
} catch let error {
}

// good
do {
    try foo()
} catch let error as MyError {
} catch { }

Unused Import

インポートされた全てのモジュールがファイルをコンパイルするために必要とされるべきです。
https://realm.github.io/SwiftLint/unused_import.html

// bad
import Foundation
class A { }

// good
import Foundation
@objc
class A { }

Unused Private Declaration

private の定義はそのファイル内で参照されるべきです。
https://realm.github.io/SwiftLint/unused_private_declaration.html

// bad
private let a = 0

// good
private let a = 0
_ = a

Vertical Parameter Alignment On Call

関数の呼び出し時、パラメータが複数行にまたがっている場合は垂直方向に揃えるべきです。
https://realm.github.io/SwiftLint/vertical_parameter_alignment_on_call.html

// bad
validateFunction(_ file: File, kind: SwiftDeclarationKind,
               dictionary: [String: SourceKitRepresentable]) { }
validateFunction(_ file: File, kind: SwiftDeclarationKind,
                  dictionary: [String: SourceKitRepresentable]) { }

// good
validateFunction(_ file: File, kind: SwiftDeclarationKind,
                 dictionary: [String: SourceKitRepresentable]) { }

Vertical Whitespace Between Cases

SwitchのCase間は空白行を1行含んでください。
https://realm.github.io/SwiftLint/vertical_whitespace_between_cases.html

// bad
switch x {
case .valid:
    print("x is valid")
case .invalid:
    print("x is invalid")
}

// good
switch x {
case .valid:
    print("x is valid")

case .invalid:
    print("x is invalid")
}

Vertical Whitespace before Closing Braces

中括弧を閉じる前に空白行を入れないでください。
https://realm.github.io/SwiftLint/vertical_whitespace_before_closing_braces.html

// bad
{
    {
    }

}

// good
{
    {
    }
}

Vertical Whitespace after Opening Braces

中括弧を開いた後に空白行を入れないでください。
https://realm.github.io/SwiftLint/vertical_whitespace_after_opening_braces.html

// bad
{

    {
    }
}

// good
{
    {
    }
}

XCTest Specific Matcher

XCTAssertEqualXCTAssertNotEqual より特定のXCTestマッチャーを使うべきです。
https://realm.github.io/SwiftLint/xctest_specific_matcher.html

// bad
XCTAssertEqual(foo, true)
XCTAssertEqual(foo, false)
XCTAssertEqual(foo, nil)
XCTAssertNotEqual(foo, true)
XCTAssertNotEqual(foo, false)
XCTAssertNotEqual(foo, nil)

// good
XCTAssertFalse(foo)
XCTAssertTrue(foo)
XCTAssertNil(foo)
XCTAssertNotNil(foo)
XCTAssertEqual(foo, 2)

Yoda condition rule

変数は比較演算子の左側、定数は右側に配置すべきです。
https://realm.github.io/SwiftLint/yoda_condition_rule.html

// bad
if 42 == foo { }

// good
if foo == 42 { }

おわりに

SwiftLintのルールを一通り眺めるだけでもSwiftyに書けるようになった気がします。
ただ、これらを他のメンバーにも守ってもらうには、やはりSwiftLintの導入が便利です。

156
107
6

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
156
107