6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Swiftの静的解析を行うためにSwiftLintをインストールしてみた

Last updated at Posted at 2017-07-05

Tailorのインストール、実行を試してみたのでSwiftLintも試してみる。

#インストール
公式ページにのっているので省略。
Tailorとほぼ同じでHomebrewが入っていれば簡単。

#SwiftLintのチェックをXcodeビルド時に実行できるようにする
Tailorの時と同様にBuild Phaseにスクリプトを記載するとできる。
Build PhaseでNew Run Script Phase
スクリプト名をSwiftLintにして以下内容を記載。

if which swiftlint >/dev/null; then
    swiftlint
else
    echo "warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint"
fi

こんな感じになります。

スクリーンショット 2017-07-05 15.46.19.png

Tailorとほぼ同じ手順。

#実行
設定できたはずなのでビルドしてみると・・・
無事動いたがワーニングだけでなくエラーも出ている。
※Tailorでは14このwarningだったソース

スクリーンショット 2017-07-05 15.52.04.png

なんとなく優秀そうだぞ。と思って公式ページをみると90コほどルールがあった。
ルールが多ければいいというわけではないが。
SwiftLintもTailor同様にymlファイルでルールの設定が細かくできるようだ。

#ルールの設定
こちらもTailorとほぼ同じ手順でOK。
xcodeprojectファイルと同階層に.swiftlint.ymlを作成することで可能になる。
Tailorを試していたことで作業がかなり捗る。

.swiftlint.ymlを作成せずにビルドするとこんな感じ。デフォルトのチェック状態
デフォルトの設定は以下コマンドで確認できる

$ swiftlint rules

スクリーンショット 2017-07-05 16.52.15.png

デフォルトのコメントもエラーになっている。1行は120文字以内でないとエラーになっている。
このあたりを回避するために.swiftlint.ymlを作成し以下の内容を記載。

# 実行から除外するルール
disabled_rules:
# テストコード、Pod等のライブラリは対象外
excluded:
- Pods/
- Podfile
- Podfile.lock

# 1行あたりの文字数制限
line_length: 300

line_length: 300で1行あたりの文字数制限を緩和して再実行

スクリーンショット 2017-07-05 16.57.27.png
こんな感じでエラーが消えた。

試しに残りの2つのワーニングも消してみる。
(本当にワーニングの必要はないかは別問題で実験)

# 実行から除外するルール
disabled_rules:
- trailing_whitespace
- vertical_whitespace
- trailing_newline

# テストコード、Pod等のライブラリは対象外
excluded:
- Pods/
- Podfile
- Podfile.lock

# 1行あたりの文字数制限
line_length: 300

ビルドしてみると無事ワーニングも消えた。

スクリーンショット 2017-07-05 17.07.08.png

こんな感じでソース内に記述することで一部のワーニング、エラーを除外することもできる

    func applicationWillResignActive(_ application: UIApplication) {
        // swiftlint:disable:next line_length
        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
        // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
        // swiftlint:disable:previous line_length
    }

ポイントは対象を// swiftlint:disable:next ルール// swiftlint:disable:previous ルールで対象を囲むこと。
今回は1行の文字数制限をルールから除外してみた。

    // swiftlint:disable:next line_length
    ****
    // swiftlint:disable:previous line_length

スクリーンショット 2017-07-05 17.31.26.png

無事チェックされなくなったのでエラーが消えた。
ちなみに// swiftlint:disable line_lengthのように囲まずに1行だけ書くと記載箇所以降はルールが適用されなくなる。

#SwiftLintを触った感想
ルールの設定、数値など細かく設定できること、自前のルールも作成できるとのことなのでより細かくルールを決めたい場合はSwiftLintが良さそうだ。
使えそうな匂いがするのでルールについて確認してみる。

#ルールについて
独自にまとめようと思ったが素晴らしくまとまったものがあったのでこちらを参考に。
リンク先のサンプル通り、opt-in_rulesは記載しておいてコメントアウトすると使いやすいかな。

.swiftlint.ymlで設定する項目。

.swiftlint.yml
    # 無効にするルール
    disabled_rules:
    - trailing_whitespace
    # デフォルト無効のルールのうち、有効にするルール
    opt_in_rules:
    - attributes
    # Lint対象に含めるファイルがあるパスを記述。
    included:
    - Source
    # Lint対象から外すファイルのあるパスを記述。includedより優先される。Podsやライブラリなど。
    excluded:
    - Pods/
    - Podfile
    # configurable rules can be customized from this configuration file
    # binary rules can set their severity level
    # 1行あたりの文字数制限
    line_length: 300

opt-in-rulesだけ抜き出してみた。
各ルールの説明は参考サイトの説明や公式ページの内容を機械的に翻訳して埋めてみた。
すでにまとめていただいているものはわかりやすいが、よくわからないものもある。
extension_access_modifierno_extension_access_modifierは相反する推奨になっている?
除外するルールや、有効にするルールは随時見直していく。

.swiftlint.yml
  opt_in_rules:
    - attributes                              # 属性は関数と型の独自の行にあるべき
    - closure_end_indentation                 # クロージャの最後の } は開始したラインと同じインデントを持つ必要がある
    - closure_spacing                         # クロージャ内の式はカッコの間に1つのスペースがあるべき
    - conditional_returns_on_newline          # 条件文は始まった行の次の行でreturnするべき.
    - empty_count                             # 要素が何もないことを確認する際はcount == 0よりもisEmptyを用いてチェックする
    - explicit_init                           # 明示的な.init()メソッドの呼び出しは避けるべき.
    - explicit_top_level_acl                  # 最上位の宣言では、アクセス制御レベルのキーワードを明示的に指定する必要がある
    - explicit_type_interface                 # クラス変数とかインスタンス変数とかには"型"を記述しろ
    - extension_access_modifier               # 拡張アクセス修飾子を使用することを推奨
    - fatal_error_message                     # fatalErrorを使う場合はメッセージを書く
    - file_header                             # ファイルの先頭のコメントの書式
    - first_where                             # .filter { }.firstよりも.first(where:)を用いる.
    - force_unwrappin                         # ! 使うな
    - implicit_return                         # クロージャの暗黙のリターンを推奨
    - implicitly_unwrapped_optional           # 暗黙的なUnwrapは禁止
    - multiline_parameters                    # 関数とメソッドのパラメータは、同じ行または1行に1つずつ指定する必要がある
    - nimble_operator                         # Nimble演算子のオーバーロードは、フリーマッチャー関数よりも優先
    - no_extension_access_modifier            # 拡張アクセス修飾子を使用しないことを推奨する                       
    - number_separator                        # 3桁ごとに _ 
    - object_literal                          # イニシャライザを直接呼び出すよりは#imageLiteralや#colorLiteralを用いる.
    - operator_usage_whitespace               # 演算子を使用する前後にスペース                      
    - overridden_super_call                   # メソッドを override したら super を呼ぶ
    - private_outlet                          # @IBOutlet は private に
    - prohibited_super_call                   # いくつかのメソッドにおいてはsuperを呼び出すべきではない.
    - redundant_nil_coalescin                 # nil結合演算子において,左辺がnilの場合のみ評価される性質上,右辺にnilを書くのは冗長なため,書くべきでない.
    - sorted_imports                          # import をアルファベット順に
    - switch_case_on_newline                  # switch文におけるcaseの各処理は改行した後書くべき
    - vertical_parameter_alignment_on_call    # 関数のパラメータは宣言の複数の行にある場合、垂直方向に整列させる必要がある

#参考

6
4
0

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
6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?