0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Xcodeに内蔵されたswift-formatの使い方

0
Posted at

はじめに

Xcode16よりAppleの公式Formatterであるswiftlang/swift-formatが内蔵されています。
その為追加インストールなしで、ビルド時にswiftファイルの自動整形を行うことができます。
備忘録も兼ね、導入方法についてまとめたいと思います。

手順

手順の概要は以下の通りです。

  1. プロジェクト設定画面を開く
  2. Run Scriptを追加する
  3. スクリプトの編集を行う
  4. User Script Sandboxingを編集
  5. .swift-formatの追加

1. プロジェクト設定画面を開く

Xcodeの左のナビゲーターからプロジェクトを選択し(下図①)、
TARGETSのプロジェクト名を選択します。(下図②)

your xcode

2. Run Scriptを追加する

タブからBuild Phasesを選択し(下図①)、+ボタンを選択し(下図②)、
New Run Script Phaseを選択します。(下図③)

your xcode

3. スクリプトの編集を行う

Run Scriptに下記スクリプトを記載します。
この時、Based on dependency analysisのチェックを外しておきます。(下図赤枠部)

# フォーマットしたいフォルダを指定
set -e

PROJECT_DIR="${SRCROOT}"

# Xcode内蔵のswift-formatを使用してフォーマットを実行
if xcrun --find swift-format >/dev/null 2>&1; then
    xcrun swift-format format \
        --in-place \
        --recursive \
        "$PROJECT_DIR"

    xcrun swift-format lint \
        --recursive \
        "$PROJECT_DIR"
else
    echo "warning: swift-format が見つかりません。"
fi
your xcode

スクリプトの内容

このスクリプトでは、まず以下で swift-format が利用できるか確認しています。

if xcrun --find swift-format >/dev/null 2>&1; then

swift-format が見つかった場合は、以下を実行します。

xcrun swift-format format \
    --in-place \
    --recursive \
    "$PROJECT_DIR"

format は、Swiftファイルを実際にフォーマットするコマンドです。

--in-place を指定することで、フォーマット結果をファイルへ直接反映します。

また、--recursive を指定しているため、指定したディレクトリ以下を再帰的に処理します。

その後、以下を実行します。

xcrun swift-format lint \
    --recursive \
    "$PROJECT_DIR"

lint は、指定したフォーマットルールに従っているかをチェックするためのコマンドです。

つまり、

format
↓
コードを自動整形

lint
↓
フォーマットルールに違反していないか確認

という流れになります。

4. User Script Sandboxingを編集

PROJECCT > TARGETS > "project file"からBuild SettingsとAllを選択し、
Build OptionsのUser Script SandboxingをNoに変更します。

your xcode

5. .swift-formatの追加

.swift-formatはJSON形式で記述されるフォーマットの設定ファイルであり、
プロジェクトのルート配置する必要があります。

ProjectRoot/
├── .swift-format    ←ここに置く
├── AppName.xcodeproj
├── AppName/
│   └── ContentView.swift
│── AppNameTests/
|── AppNameUITests/

プロジェクトのルートに.swift-formatファイルを作成し、
フォーマットの設定を記述します。
フォーマットの設定に関しては、下記コマンドで確認できるダンプを参考に設定すると良い思います。

# swift-formatをインストール済みの場合
swift-format dump-configuration

# swift-formatをインストールしていない場合
xcrun swift-format dump-configuration

筆者は下記のように設定しました。

{
  "fileScopedDeclarationPrivacy": {
    "accessLevel": "private"
  },
  "indentConditionalCompilationBlocks": true,
  "indentSwitchCaseLabels": false,
  "indentation": {
    "spaces": 4
  },
  "lineBreakAroundMultilineExpressionChainComponents": true,
  "lineBreakBeforeControlFlowKeywords": false,
  "lineBreakBeforeEachArgument": true,
  "lineBreakBeforeEachGenericRequirement": false,
  "lineLength": 100,
  "maximumBlankLines": 1,
  "multiElementCollectionTrailingCommas": true,
  "noAssignmentInExpressions": {
    "allowedFunctions": [
      "XCTAssertNoThrow"
    ]
  },
  "prioritizeKeepingFunctionOutputTogether": true,
  "respectsExistingLineBreaks": true,

  "rules": {
    "AllPublicDeclarationsHaveDocumentation": false,
    "AlwaysUseLiteralForEmptyCollectionInit": true,
    "AlwaysUseLowerCamelCase": true,
    "AmbiguousTrailingClosureOverload": true,
    "BeginDocumentationCommentWithOneLineSummary": false,
    "DoNotUseSemicolons": true,
    "DontRepeatTypeInStaticProperties": true,
    "FileScopedDeclarationPrivacy": true,
    "FullyIndirectEnum": true,
    "GroupNumericLiterals": true,
    "IdentifiersMustBeASCII": true,
    "NeverForceUnwrap": true,
    "NeverUseForceTry": true,
    "NeverUseImplicitlyUnwrappedOptionals": true,
    "NoAccessLevelOnExtensionDeclaration": true,
    "NoAssignmentInExpressions": true,
    "NoBlockComments": true,
    "NoCasesWithOnlyFallthrough": true,
    "NoEmptyTrailingClosureParentheses": true,
    "NoLabelsInCasePatterns": true,
    "NoLeadingUnderscores": true,
    "NoParensAroundConditions": true,
    "NoPlaygroundLiterals": true,
    "NoVoidReturnOnFunctionSignature": true,
    "OmitExplicitReturns": false,
    "OneCasePerLine": true,
    "OneVariableDeclarationPerLine": true,
    "OnlyOneTrailingClosureArgument": true,
    "OrderedImports": false,
    "ReplaceForEachWithForLoop": false,
    "ReturnVoidInsteadOfEmptyTuple": true,
    "TypeNamesShouldBeCapitalized": true,
    "UseEarlyExits": true,
    "UseExplicitNilCheckInConditions": true,
    "UseLetInEveryBoundCaseVariable": true,
    "UseShorthandTypeNames": true,
    "UseSingleLinePropertyGetter": true,
    "UseSynthesizedInitializer": true
  }
}

swift-formatのリンタとフォーマットのルールは、RuleDocumentaion.mdに記載されていますので、こちらを参照するといいと思います。

参考文献

0
1
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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?