Swift Cheatsheet - Swift & iOS Development Command Reference
This reference is for Swift developers shipping iOS/macOS apps, command-line tools, or server code, spanning the two toolchains you bounce between: the Swift/SwiftPM CLI and xcodebuild/xcrun simctl. It covers compiling and running scripts, initializing and building Swift packages, building/testing/archiving a scheme, driving simulators, and the syntax idioms (let/var, optional binding, map/filter/reduce) plus debug/assert helpers you reach for daily. Unlike a flat Swift command list, entries are grouped by the actual cycle of compile → test → archive → run on simulator. After reading, you should be able to take a package from swift package init to a passing swift test, and drive an Xcode scheme from the terminal.
Typical Use Case
For developers who want to run Swift without the IDE, and for CI maintainers who need one build script across iOS and macOS. This sheet covers three tracks: the swift interpreter plus the swift package / build / test workflow, headless building with xcodebuild and simulator control via xcrun simctl, and the language-level traps around optional unwrapping and collection higher-order functions. It fits whenever you need to run tests on CI or validate a piece of logic locally without launching the full IDE.
Compile & Run 6
swift main.swiftswiftc main.swift -o mainswift main.swiftcswift -e "print("Hello")"swift package init --type executableswift package init --type librarySwift Package Manager 8
swift buildswift build -c releaseswift runswift testswift package resolveswift package updateswift package resetswift package show-dependenciesXcode CLI 7
xcodebuild -listxcodebuild -scheme MyApp buildxcodebuild -scheme MyApp testxcodebuild archive -scheme MyAppxcrun simctl list devicesxcrun simctl boot <device-id>xcrun simctl install booted MyApp.appCommon Syntax 8
var name: String = "Swift"let age: Int = 18if let value = optional { ... }guard let value = optional else { return }array.map { $0 * 2 }array.filter { $0 > 5 }array.reduce(0) { $0 + $1 }for (index, value) in array.enumerated()Debug & Performance 5
print("debug: \(variable)")debugPrint(object)assert(condition, "message")precondition(condition, "message")InstrumentsParameter matrix
| Parameter | Effect | Example |
|---|---|---|
swift build -c release | Optimized build used for shipping and performance work; keep the default debug build while coding | swift build -c release |
guard let ... else | Optional binding with early exit, collapsing the bad path at the top of the function | guard let value = optional else { return } |
xcodebuild -scheme MyApp test | Runs a scheme test suite headlessly, which is what CI needs | xcodebuild -scheme MyApp test |
Common pitfalls
SymptomRuntime crash: fatal error: unexpectedly found nil.
CauseA force unwrap ! was used on an optional that really is nil on some paths.
FixHandle the branches with if let value = optional { ... } or guard let value = optional else { return }.
SymptomAfter editing one line, swift build fails with errors unrelated to the change.
CauseThe .build incremental cache is out of sync with the source tree.
FixRun swift package reset to clear the cache, then build again.
SymptomCI fails on a fresh dependency resolution while the local machine is fine.
CauseThe local checkout has an older Package.resolved; CI resolves from scratch and picks newer versions.
FixResolve with swift package resolve, commit Package.resolved, and only then run swift package update.
SymptomAn assert never fires in the release build, so the bug only shows up in production.
Causeassert is stripped in release configuration.
FixUse precondition(condition, "message") for invariants, since it is evaluated in every configuration.
Troubleshooting
1List the schemes before picking a build target
xcodebuild -listGet the exact scheme name first, otherwise -scheme simply fails with an unknown-target error.
2Grab a simulator id and install the build for manual verification
xcrun simctl install booted MyApp.appThe id comes from xcrun simctl list devices, and the simulator must be booted first.
3Confirm the dependency tree and the locked versions
swift package show-dependenciesPrints the tree with the origin and version of each package, which exposes version conflicts.
Command Examples
Run a script and compile it to an executable
swift main.swift
swiftc main.swift -o mainThe first line executes the script directly, the second produces a standalone binary; swift -e "print(...)" runs a single line of code.
Initialize an executable package and run its tests
swift package init --type executable
swift build
swift testProducts land in the .build directory; swift test exits non-zero on failure, which lets CI block a regression.
Release build and locked dependency resolution
swift build -c release
swift package resolve
swift package show-dependenciesAfter a fresh clone run resolve first, then use show-dependencies to see where each package comes from and which version is pinned.
Unwrapping optionals and combining collection transforms
if let value = optional {
print(value)
}
array.map { $0 * 2 }
array.filter { $0 > 5 }
array.reduce(0) { $0 + $1 }All three return new values and leave the original array untouched: map converts models, filter keeps matching elements, reduce folds from an initial value.
Common Pitfalls
- assert fires only in debug builds and is skipped entirely by a release build; use precondition for a check that must hold in every configuration.
- Force-unwrapping an optional with ! crashes at runtime the moment it is nil, so route bad paths through if let or guard let instead.
- swift build -c release turns optimizations on and compiles markedly slower; keep debug as the default while iterating.
- swift package reset wipes .build and forces a full rebuild, so the next build costs much more time. Use it only when incremental errors stop matching your edits.
- A simulator device id can only be taken from the output of xcrun simctl list devices, and the target must be available before you boot it.
Tips
- swift package init generates Package.swift, the SPM manifest.
- Optionals are core to Swift safety; unwrap with if let / guard let.
- xcodebuild CLI fits CI/CD automated builds and tests.
FAQ
How does swift run differ from building first and launching the binary yourself?
swift run compiles the package per Package.swift and then executes the product of the executable target, so the only difference is that it saves you locating the artifact under .build yourself. Splitting the two steps is useful when you want to inspect the compiler output on its own; in CI, where the question is only whether the product runs, a single swift run is enough. Note that swift run is meaningless for a library target, since there is nothing to execute.
Why does the code compile locally but swift test fails in CI?
Dependency versions are usually the culprit. A local checkout already has a .build cache and resolved packages, while CI starts from a fresh clone and must run swift package resolve first to land on the versions pinned in Package.resolved. Only when that file is current and committed do both sides agree. If a dependency manifest changed on CI, run swift package show-dependencies to print the tree and check each package origin and version before deciding whether to commit Package.resolved or tighten the constraint.
When should I use if let and when should I use guard let?
The difference is whether unwrapping failure exits the current scope. With if let value = optional the following block is skipped entirely when unwrapping fails, so control flow stays inside one branch. With guard let value = optional else { return } failure returns immediately (or continues in a loop), so everything after the guard sees value already unwrapped and needs no question mark. In practice put guards at the top of a function or loop to collapse the bad path, and the rest of the body can be written as if the value were non-optional.
When is swift package reset worth running?
It clears the .build cache and forces a full rebuild, so it belongs to the last-resort tier. The signal is an incremental compile error that plainly has nothing to do with the line you just touched, or a stale message that no longer matches your source. The cost is that the next swift build recompiles everything and takes noticeably longer, so do not treat it as a routine step: first make sure the error really points at cached state rather than at a dependency or your own code.
What are the steps to verify a build on the simulator?
The order is fixed. First xcodebuild -list to confirm the scheme name, then xcodebuild -scheme MyApp build to produce the .app. Next xcrun simctl list devices to read the UDID of the target device, and xcrun simctl boot that id. Then xcrun simctl install booted MyApp.app to install the product into the running simulator, and finally click through it manually. The UDID can only come from the simctl list output; guessing one always fails.
Official References
Each command links to its official documentation below, so you can verify the latest usage and read deeper.
Maintained by LaoHand
Publicly updated on Jul 21, 2026, continuously proofread against official docs.
Contact Us
Wrong command or description? Send us corrections, business inquiries or product feedback by email.
Contact Us