agentleFS
wtsi-hgiwtsi-hgi/agentskills/skills/swift-conventions/SKILL.md

swift-conventions

Skill1 starsChanged 40 days agoMITView on GitHub

Shared conventions for Swift projects on macOS and iOS. XcodeGen project layout, Swift Testing, simulator and Mac UI testing, signing, current SDK facts, and commands. Referenced by swift-implementor, swift-reviewer, and workflow skills.

The file

We split this skill into the rules it gives an agent

4 rules. About 0 are common, 0 are distinctive, and 4 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈0

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 4

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    No copyright or license header in .swift files, unlike the other stacks' conventions.

    line 39
  2. Very specific:

    XcodeGen: Commit project.yml; generate and gitignore the .xcodeproj.

    line 47
  3. Very specific:

    Wait with confirmation(expectedCount:) or await, never Task.sleep.

    line 70
  4. Very specific:

    Every spec.md acceptance test MUST have a corresponding test.

    line 78

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Swift Conventions

Single source of truth for Swift code standards. Other skills reference this.

Toolchain And SDK Facts

These post-date most model training. Verified on the dev Mac on 2026-11-06; before relying on one that matters, check it against the installed SDK (xcrun --sdk macosx|iphoneos --show-sdk-path, then grep the framework's .swiftinterface) rather than memory.

  • macOS 27.2, Xcode 27.2 (27B52), Swift 6.4.2 (swift-tools-version: 6.4), macOS and iOS 27.2 SDKs, iOS 27.2 simulator runtime (iPhone 18 Pro/Pro Max, 17, 17e, Air, several iPads). No watchOS or visionOS runtimes.
  • @available(anyAppleOS 27.0, *) and #available(anyAppleOS 27.0, *) cover every Apple platform at once; the 27 SDKs use it.
  • FoundationModels: the on-device SystemLanguageModel (since 26) is the only model available to these projects. PrivateCloudComputeLanguageModel (new in 27) needs a managed entitlement a free Personal Team cannot get.
  • App Intents in the 27 SDKs have a calendar schema: @AppIntent(schema: .calendar.createEvent) (also updateEvent, deleteEvent, and calendar entities and enums).
  • An Xcode 27.2 scheme can override Foundation Models availability, so model-unavailable states are tested without changing system settings.
  • swift format ships with the toolchain; SwiftLint is not installed. Without a committed .swift-format, it lints for 2-space indentation.

Code Quality

  • Swift 6 language mode with complete strict concurrency. Fix data-race diagnostics; never silence them with @unchecked Sendable or nonisolated(unsafe) without a comment naming the invariant that makes it safe.
  • No copyright or license header in .swift files, unlike the other stacks' conventions. Leave existing headers as they are.
  • Doc comments on all public and package declarations.
  • Functions ~30 lines max; early returns and guard over nested if.
  • One responsibility per file; filenames describe the responsibility.

Architecture

  • XcodeGen. Commit project.yml; generate and gitignore the .xcodeproj. Regenerate before every build, and edit project.yml, never the generated project.
  • Local Swift package for all non-UI logic, tested with swift test. App and extension targets hold only wiring, UI, and calls into system frameworks, like Go's cmd/.
  • System frameworks (EventKit, FoundationModels, WidgetKit, App Intents) and UI are tested through xcodebuild test. Put them behind a protocol only where a package test needs a fake; test the real framework in the app's test target.
  • A widget or other extension's bundle ID must be prefixed by its containing app's bundle ID.

Testing

Swift Testing

  • Swift Testing (import Testing) for unit and integration tests; XCTest only for XCUITest UI tests.
  • #expect for checks, #require where later lines depend on the value.
  • Table tests with @Test(arguments:), one argument tuple per spec example.
  • Tests run in parallel by default. Mark a suite .serialized when its tests share an external store (EventKit, UserDefaults, a shared file).
  • Wait with confirmation(expectedCount:) or await, never Task.sleep; give async suites a .timeLimit so a missed signal fails instead of hanging.
  • Per-test temp directories: a UUID-named directory under FileManager.default.temporaryDirectory, removed in the suite's deinit.
  • Generated input: no built-in fuzzer. Use a small seeded generator (for example SplitMix64 conforming to RandomNumberGenerator) with a fixed seed; testing-principles owns when and what to assert.
  • Every spec.md acceptance test MUST have a corresponding test. No stubs, no hardcoded results, no swallowed failures, no .disabled or withKnownIssue to get green.

Simulator And Mac UI Tests

  • Grant iOS simulator permissions without prompts before UI tests: xcrun simctl privacy <device> grant calendar|contacts|location|siri <bundle-id>. There is no pasteboard grant.
  • Simulators share nothing with the Mac's accounts; tests seed their own data.
  • The iOS simulator can be driven by agents. The Mac desktop cannot: Mac UI is exercised only by XCUITest, which needs macOS Automation Mode. If automationmodetool reports it needs authentication, ask the user to run sudo automationmodetool enable-automationmode-without-authentication once; never run sudo yourself.
  • XCUIApplication.launch kills a running instance, so test builds use a separate bundle ID and never register login items.

Signing

  • Free Personal Team. App Groups work; iCloud and Push Notifications do not, so nothing syncs between devices.
  • Sign Mac builds with the stable Apple Development identity, never ad hoc: ad-hoc signing ties macOS privacy (TCC) grants to the code hash, so every rebuild re-prompts.

Commands

# Project
xcodegen generate

# Package tests (non-UI logic)
swift test --package-path <pkg> --filter <Suite/test>

# App tests
xcodebuild test -scheme <scheme> -destination 'platform=macOS' -only-testing:<Target/Suite/test>
xcodebuild test -scheme <scheme> -destination 'platform=iOS Simulator,name=iPhone 18 Pro' -only-testing:<Target/Suite/test>

# Builds
xcodebuild build -scheme <scheme> -destination 'generic/platform=iOS Simulator'

# Format, then lint
swift format --in-place --recursive <paths>
swift format lint --strict --recursive <paths>

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.