Emergency server help: get in touch

Swift Cheat Sheet: Syntax, Optionals, Protocols and async

A compact Swift 6.4 reference covering SwiftPM, optionals, collections, closures, types, protocols, error handling and concurrency, on macOS or Linux.

Published 6 min read

Short answer: Create a command-line project with swift package init --type executable and run it with swift run. Use let for constants and var for variables, unwrap optionals with if let, guard let or ??, and prefer struct (value type) over class. Model states with enum and switch, mark failing functions throws and call them with try. Swift 6 checks data races at compile time; use async/await, Task and actor for concurrent code.

The examples in this Swift cheat sheet were run with Swift 6.4 (swift-6.4-RELEASE) on Ubuntu 24.04 on 9 October 2026, using Swift Package Manager and Foundation on Linux.

Swift Package Manager and toolchain

CommandWhat it does
swift --versionShow the compiler version
swift package init --type executableNew command-line package in the current directory
swift package init --type libraryNew library package
swift run / swift run Demo --flagBuild and run (with arguments)
swift build -c releaseOptimised binary in .build/release/
swift testRun tests (new packages use the Swift Testing library, @Test and #expect)
swift package updateUpdate dependencies within Package.swift rules
swiftc main.swift -o appCompile a single file without a package
swiftly install latestInstall or switch toolchains with swiftly, the installer swift.org recommends on Linux

On Linux, Swift ships with Foundation, so String(contentsOfFile:), JSONEncoder, ProcessInfo and Process work as they do on macOS. Apple frameworks such as UIKit and SwiftUI are not available there.

Variables, strings and control flow

SyntaxWhat it doesExample
letConstant; prefer it by defaultlet name = "web01"
varVariablevar port = 443; port += 1
Type annotationOptional when the type can be inferredlet ratio: Double = 0.75
"\(expr)"String interpolation"\(name):\(port)"
""" ... """Multi-line string; indentation of the closing quotes is removed
0..<3 / 1...3Half-open / closed rangefor i in 0..<3 { }
stride(from:to:by:)Stepped loopstride(from: 10, to: 0, by: -5)
while / repeat { } whileLoops
switch with ranges and listsMust be exhaustive; no implicit fall-throughcase 400..<500:
if / switch expressionsProduce a value directlylet kind = if port > 1024 { "high" } else { "low" }
let code = 404
let msg = switch code {
case 200: "ok"
case 301, 302: "redirect"
case 400..<500: "client error"
default: "other"
}
print(msg)   // client error

Optionals

SyntaxWhat it does
var nick: String? = nilA value that may be absent
if let nick { ... }Unwrap into a constant with the same name
guard let p = Int(raw) else { return nil }Unwrap or leave early; p stays in scope afterwards
nick ?? "none"Default value
user?.address?.cityOptional chaining; the result is optional
nick!Force unwrap; crashes on nil, so avoid it outside tests
func check(_ raw: String) -> Int? {
    guard let p = Int(raw), (1...65535).contains(p) else {
        return nil
    }
    return p
}
check("8080")   // Optional(8080)
check("x")      // nil

Collections and closures

SyntaxWhat it does
var nums = [5, 3, 8]Array; append, sort(), count, first, contains
nums.map { $0 * $0 }Transform each element ($0 is the first argument)
nums.filter { $0.isMultiple(of: 2) }Keep matching elements
nums.reduce(0, +)Combine into one value
["1", "x"].compactMap { Int($0) }Map and drop nil results
nums.sorted { $0 > $1 }New sorted array with a trailing closure
var ports = ["ssh": 22]Dictionary; lookups return an optional
ports["https"] = nilRemove a key
counts[w, default: 0] += 1Count with a default value
let s: Set = ["a", "b"]Set of unique values
func greet(_ person: String, from city: String = "Leeds") -> String {
    "Hello \(person) from \(city)"     // single expression: implicit return
}
greet("Ali")                 // argument label omitted with _
greet("Sam", from: "York")

func bump(_ x: inout Int) { x += 1 }
var c = 1
bump(&c)                     // c == 2

Structs, classes, enums and protocols

struct Server: Codable, Equatable {
    var name: String
    var port: Int = 22
    var address: String { "\(name):\(port)" }       // computed property
    mutating func setPort(_ p: Int) { port = p }
}

enum Event {
    case login(user: String, ok: Bool)
    case restart(String)
    case quit
}

switch event {
case .login(let user, false): print("failed login \(user)")
case .login(let user, _):     print("login \(user)")
case .restart(let svc):       print("restart \(svc)")
case .quit:                   print("quit")
}

protocol Check {
    var name: String { get }
    func healthy() -> Bool
}
extension Check {
    func healthy() -> Bool { true }       // default implementation
}
extension Server: Check {}                // Server already has `name`
SyntaxMeaning
structValue type: copied on assignment
final classReference type: assignments share one instance
enum Level: Int, CaseIterableRaw values and Level.allCases
func report(_ c: some Check)Opaque generic parameter (static dispatch)
let checks: [any Check]Existential: mixed types behind one protocol
func largest<T: Comparable>(_ xs: [T]) -> T?Generic function with a constraint
try JSONEncoder().encode(server)JSON from a Codable type

Error handling

enum ConfigError: Error {
    case missing(String)
    case badPort(String)
}

func parsePort(_ s: String) throws(ConfigError) -> Int {      // typed throws
    guard !s.isEmpty else { throw .missing("port") }
    guard let p = Int(s), (1...65535).contains(p) else { throw .badPort(s) }
    return p
}

do {
    let p = try parsePort("70000")
    print(p)
} catch .badPort(let raw) {
    print("bad port \(raw)")        // bad port 70000
} catch {
    print("other: \(error)")
}
SyntaxWhat it does
throws / throws(MyError)Function can throw any error / one error type
try f()Call a throwing function inside do or another throwing function
try? f()Returns nil on error
try! f()Crashes on error
Result { try f() }Capture success or failure as a value
defer { ... }Run cleanup when the scope exits

Concurrency: async, await, tasks and actors

func fetchStatus(_ host: String) async -> Int {
    try? await Task.sleep(for: .milliseconds(10))
    return host.count
}

actor HitCounter {                    // serialises access to its state
    private var hits = 0
    func add() { hits += 1 }
    func value() -> Int { hits }
}

async let a = fetchStatus("web01")    // runs concurrently
async let b = fetchStatus("web02")
let both = await [a, b]

let results = await withTaskGroup(of: Int.self) { group in
    for h in ["a", "bb", "ccc"] {
        group.addTask { await fetchStatus(h) }
    }
    var out: [Int] = []
    for await v in group { out.append(v) }
    return out
}

Packages with swift-tools-version: 6.0 or later use the Swift 6 language mode, which turns data-race warnings into errors. Values sent between tasks must be Sendable; structs and enums of Sendable members qualify automatically. The migration guide explains how to adopt this in older code.

Files, processes and a log example

For server admins: count requests per client IP in an access log with Foundation.

import Foundation

let path = CommandLine.arguments.dropFirst().first ?? "/var/log/nginx/access.log"
guard let text = try? String(contentsOfFile: path, encoding: .utf8) else {
    FileHandle.standardError.write(Data("cannot read \(path)\n".utf8))
    exit(1)
}

var hits: [Substring: Int] = [:]
for line in text.split(separator: "\n") {
    if let ip = line.split(separator: " ").first {
        hits[ip, default: 0] += 1
    }
}
for (ip, n) in hits.sorted(by: { $0.value > $1.value }).prefix(10) {
    print(String(format: "%7d", n), ip)
}
SyntaxWhat it does
try String(contentsOfFile: p, encoding: .utf8)Read a whole text file
try text.write(toFile: p, atomically: true, encoding: .utf8)Write a file
FileManager.default.fileExists(atPath: p)Check a path
ProcessInfo.processInfo.environment["HOME"]Environment variable
let p = Process(); p.executableURL = URL(fileURLWithPath: "/usr/bin/uptime"); try p.run()Run a program; call p.waitUntilExit() to wait

Official documentation (checked 9 October 2026): The Swift Programming Language · Swift Standard Library · Install Swift on Linux · Swift Package Manager · Swift 6 Migration Guide (data-race safety) · Swift 6.4 Released

Swift Cheat Sheet at a glance

Swift Cheat Sheet – short answer
In short: A compact Swift 6.4 reference covering SwiftPM, optionals, collections, closures, types, protocols, error handling and concurrency, on macOS or Linux.
Swift Cheat Sheet – what this guide covers
Swift Cheat Sheet: what this guide covers.

Related guides: Kotlin Cheat Sheet: Syntax, Null Safety and Collections · Dart 3 Cheat Sheet: Null Safety, Records, Patterns and async · TypeScript Cheat Sheet: Types, Generics and tsconfig.

Reading a lot of our guides? Go ad-free with srvScripts Pro for $6 a month. It also pays for new guides. Cancel any time.

Share this guide

Free website test

Is your website set up right?

Check SSL, security headers, redirects, robots.txt, sitemap, llms.txt and security.txt in one test. It takes about 30 seconds.