1) Create a BuildTools folder and Package.swift
- Create a folder called
BuildTools
in the same folder as your xcodeproj file - In this folder, create a file called
Package.swift
, with the following contents:
// swift-tools-version:5.1
import PackageDescription
let package = Package(
name: "BuildTools",
platforms: [.macOS(.v10_11)],
dependencies: [
.package(url: "https://github.com/nicklockwood/SwiftFormat", from: "0.54.0"),
],
targets: [.target(name: "BuildTools", path: "")]
)
- If you are running Xcode 11.4 or later, in the
BuildTools
folder create a file calledEmpty.swift
with nothing in it. This is to satisfy a change in Swift Package Manager.
2) Add a Build phase to your app target
Click on your project in the file list, choose your target under
TARGETS
, click theBuild Phases
tabAdd a
New Run Script Phase
by clicking the little plus icon in the top leftUncheck the
Based on dependency analysis
checkboxDrag the new
Run Script
phase above theCompile Sources
phase, expand it and paste the following script:cd BuildTools SDKROOT=(xcrun --sdk macosx --show-sdk-path) #swift package update #Uncomment this line temporarily to update the version used to the latest matching your BuildTools/Package.swift file swift run -c release swiftformat "$SRCROOT"
You can also use swift run -c release --package-path BuildTools swiftformat "$SRCROOT"
if you need a more complex script and cd BuildTools
breaks stuff.
NOTE: You may wish to check BuildTools/Package.swift into your source control so that the version used by your run-script phase is kept in version control. It is recommended to add the following to your .gitignore file: BuildTools/.build
and BuildTools/.swiftpm
.
NOTE (2): If you are using Xcode 15 or later, make sure that the ENABLE_USER_SCRIPT_SANDBOXING
(aka “User Script Sandboxing”) option is set to NO, otherwise SwiftFormat won’t be able to run correctly.
Using CocoaPods
1) Add the SwiftFormat CLI to your Podfile
Add the
swiftformat
binary to your project directory via CocoaPods, by adding the following line to your Podfile then runningpod install
:pod 'SwiftFormat/CLI', '~> 0.54'
NOTE: This will only install the pre-built command-line app, not the source code for the SwiftFormat framework.
NOTE (2): When installing this way, GateKeeper may block swiftformat from running until you open it manually the first time by right-clicking in the Finder and selecting “Open”.
2) Add a Build phase to your app target
Click on your project in the file list, choose your target under
TARGETS
, click theBuild Phases
tabAdd a
New Run Script Phase
by clicking the little plus icon in the top leftUncheck the
Based on dependency analysis
checkboxDrag the new
Run Script
phase above theCompile Sources
phase, expand it and paste the following script:"${PODS_ROOT}/SwiftFormat/CommandLineTool/swiftformat" "$SRCROOT"
Alternative: Locally installed SwiftFormat
Alternatively, you could use a locally installed swiftformat command-line tool instead by putting the following in your Run Script build phase:
if which swiftformat >/dev/null; then
swiftformat .
else
echo "warning: SwiftFormat not installed, download from https://github.com/nicklockwood/SwiftFormat"
fi
This is not recommended for shared projects however, as different team members using different versions of SwiftFormat may result in noise in the commit history as code gets reformatted inconsistently.
If you installed SwiftFormat via Homebrew on Apple Silicon, you might experience this warning:
warning: SwiftFormat not installed, download from https://github.com/nicklockwood/SwiftFormat
That is because Homebrew on Apple Silicon installs the binaries into the /opt/homebrew/bin
folder by default. To instruct Xcode where to find SwiftFormat, you can either add
/opt/homebrew/bin
to the PATH
environment variable in your build phase
if [[ "$(uname -m)" == arm64 ]]; then
export PATH="/opt/homebrew/bin:$PATH"
fi
if which swiftformat > /dev/null; then
swiftformat .
else
echo "warning: SwiftFormat not installed, download from https://github.com/nicklockwood/SwiftFormat"
fi
or you can create a symbolic link in /usr/local/bin
pointing to the actual binary:
ln -s /opt/homebrew/bin/swiftformat /usr/local/bin/swiftformat
Swift Package Manager plugin
You can use SwiftFormat
as a SwiftPM command plugin.
NOTE: Swift 5.6 or higher is required. Add the package to your dependencies in your Package.swift
file.
dependencies: [
// ...
.package(url: "https://github.com/nicklockwood/SwiftFormat", from: "0.54.0"),
]
The plugin will find an existing .swiftformat
in your package root folder and honor it automatically.
Trigger Plugin From Command-Line
swift package plugin --allow-writing-to-package-directory swiftformat
You can limit the formatting to a particular target with --target
option.
You can also specify SwiftFormat
arguments, e.g. --swiftversion
.
Example
swift package plugin --allow-writing-to-package-directory swiftformat --target MyLibrary --swiftversion 5.6 --verbose
Trigger Plugin From Xcode
In Xcode 14 you can trigger the command plugin execution for a Swift package or an Xcode project.
For an Xcode project the project’s main directory will be processed and the --target
option will be ignored.
You can also specify SwiftFormat
arguments, e.g. --swiftversion
.
Via AppleScript
To run SwiftFormat on the frontmost Xcode document (project or workspace) you can use the following AppleScript:
tell application "Xcode"
set frontWindow to the first window
set myPath to path of document of frontWindow
do shell script "cd " & myPath & ";cd ..; /usr/local/bin/swiftformat ."
end tell
Some Apps you can trigger this from are BetterTouchTool, Alfred or Keyboard Maestro. Another option is to define a QuickAction for Xcode via Automator and then assign a keyboard shortcut for it in the System Preferences.
VSCode plugin
If you prefer to use Microsoft’s VSCode editor for writing Swift, Valentin Knabel has created a VSCode plugin for SwiftFormat.
Sublime Text plugin
If you prefer to use the Sublime Text editor, try the Sublime-Swift-Format plugin by Aerobounce.
Nova plugin
If you prefer to use the Nova editor, try the SwiftFormat extension by Pádraig Ó Cinnéide.
Git pre-commit hook
Follow the instructions for installing the SwiftFormat command-line tool.
Install git-format-staged.
Edit or create a
.git/hooks/pre-commit
file in your project folder. The .git folder is hidden but should already exist if you are using Git with your project, so open it with the terminal, or the Finder’sGo > Go to Folder...
menu.Add the following line in the pre-commit file. The
{}
will be replaced automatically by the path to the Swift file being formatted:#!/bin/bash git-format-staged --formatter "swiftformat stdin --stdinpath '{}'" "*.swift"
(Note that this example uses your locally installed version of SwiftFormat, not a separate copy in your project repository. You can replace
swiftformat
with the path to a copy inside your project if you prefer.)enable the hook by typing
chmod +x .git/hooks/pre-commit
in the terminal.
The pre-commit hook will now run whenever you run git commit
. Running git commit --no-verify
will skip the pre-commit hook.
NOTE: If you are using Git via a GUI client such as Tower, additional steps may be needed.
NOTE (2): Unlike the Xcode build phase approach, git pre-commit hook won’t be checked in to source control, and there’s no way to guarantee that all users of the project are using the same version of SwiftFormat. For a collaborative project, you might want to consider a post-commit hook instead, which would run on your continuous integration server.
GitHub Actions
- SwiftFormat comes preinstalled on all macOS GitHub-hosted runners. If you are self hosting you will need to ensure SwiftFormat is installed on your runner.
- Create a GitHub Actions workflow using SwiftFormat, passing the
--reporter github-actions-log
command line option. The following example action lints pull requests using SwiftFormat, reporting warnings using the GitHub Actions log.
”`yaml
format options
–allman true –indent tab # tabs FTW!
file options
–exclude Pods