# Swift

> Lint, format, build, and test Swift packages and Xcode projects.

gspot checks Swift packages and Xcode projects. SwiftLint and SwiftFormat run at commit. At push, gspot builds the package or Xcode scheme, finds declarations that nothing uses, and measures test coverage. These checks run for the `swift` and `xcode` configurations:

| Check                                                                             | Stage    | What it does                                                                                                                     |
| --------------------------------------------------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------- |
| [`swift/swiftlint`](/reference/checks/swift/swiftlint/)                           | `commit` | Lints Swift files with the SwiftLint files of each scope and nested folder, and treats warnings as errors.                       |
| [`swift/swiftformat`](/reference/checks/swift/swiftformat/)                       | `commit` | Checks the layout of every Swift file against the shipped SwiftFormat rules.                                                     |
| [`swift/build`](/reference/checks/swift/build/)                                   | `push`   | Builds the package or Xcode scheme incrementally to report compiler errors.                                                      |
| [`swift/swiftlint-analyze`](/reference/checks/swift/swiftlint-analyze/)           | `manual` | Runs the SwiftLint analyzer rules over the compiler log of the build: unused imports and captured variables.                     |
| [`swift/periphery`](/reference/checks/swift/periphery/)                           | `push`   | Scans the built project for declarations nothing uses.                                                                           |
| [`swift/skip-reasons`](/reference/checks/swift/skip-reasons/)                     | `commit` | Checks that skip calls and disabled traits name a nonempty reason, and unavailable tests carry an explanation.                   |
| [`swift/coverage`](/reference/checks/swift/coverage/)                             | `push`   | Measures each source target in Xcode projects and Swift packages against `coverage.lines` and its `coverage.swift_target` floor. |
| [`xcode/plutil`](/reference/checks/xcode/plutil/)                                 | `commit` | Parses every property list and entitlements file with plutil.                                                                    |
| [`xcode/xcstrings`](/reference/checks/xcode/xcstrings/)                           | `commit` | Checks that each string catalog parses and translates every string into all its locales.                                         |
| [`xcode/assets`](/reference/checks/xcode/assets/)                                 | `commit` | Checks that each asset `Contents.json` parses, and that its image set holds each file it names.                                  |
| [`xcode/unused-assets`](/reference/checks/xcode/unused-assets/)                   | `commit` | Finds asset sets that no source or Xcode build setting names.                                                                    |
| [`xcode/files-without-target`](/reference/checks/xcode/files-without-target/)     | `commit` | Finds the Swift files in the tree that no target of the project names.                                                           |
| [`xcode/entitlements`](/reference/checks/xcode/entitlements/)                     | `commit` | Checks each entitlement against `xcode.allowed_entitlements`, when the settings hold that list.                                  |
| [`xcode/app-transport-security`](/reference/checks/xcode/app-transport-security/) | `commit` | Refuses a property list that allows arbitrary loads, which turns transport security off for every host.                          |

## Before you start

Install the Swift toolchain, then install gspot with mise, as the [Quickstart](/start/quickstart/) shows.

## Xcode projects

`gspot init` writes the Xcode project, scheme, and destination that it finds. To set them yourself:

gspot.toml

```toml
[swift]
xcode_project = "App.xcodeproj"
xcode_scheme = "App"
xcode_destination = "generic/platform=iOS Simulator"
```

With `swift.xcode_project` set, the build, Periphery, analyzer, and coverage checks use that project or workspace. These checks need macOS with Xcode selected by `xcode-select`, and Periphery runs on macOS only.

The `xcode` configuration also checks property lists, build settings files, string catalogs, asset catalogs, and entitlements against `xcode.allowed_entitlements`. Only `xcode/plutil` needs macOS.

## Analyzer

`swift/swiftlint-analyze` runs the SwiftLint analyzer on the build log. It runs only on macOS, and only when you name it:

```shell
gspot check --only swift/swiftlint-analyze
```

List an import it flags in error under `tools.swiftlint.always_keep_imports`.

## Tests

The `swift` configuration also checks your XCTest and Swift Testing tests. gspot writes a `.swiftlint.yml` into each `Tests` or `*Tests` folder. It turns off `force_unwrapping`, `missing_docs`, and `no_magic_numbers` in tests, while your source files keep those lint rules.

`gspot check --only swift/swiftlint` reads these nested files. In an editor, run SwiftLint without `--config`, because that option turns off the nested files.

`swift/skip-reasons` asks each disabled test for a reason. `swift/coverage` measures each target against its coverage floor, and skips a scope that holds no tests.

## Coverage

To set a line coverage limit for a Swift target, write a record by hand; `gspot set` writes no record lists:

gspot.toml

```toml
[[coverage.swift_target]]
name = "Orders"
lines = 80
```

Replace `Orders` with the target named in the coverage report. Add `reason` when `lines` falls below `coverage.lines`. Then apply the record and run the check:

```shell
gspot apply
gspot check --only swift/coverage
```

## Security rules

Semgrep also runs the Swift security lint rules of the `swift` configuration on Swift sources and plist files. The [Swift configuration](/reference/configurations/swift/) lists them.
