# Swift Swiftui

Swift 6 and SwiftUI code rules for macOS apps, including concurrency, state, SwiftData...

- Repository: https://github.com/daveebbelaar/bama (1284 stars)
- Category: Testing
- License: MIT
- Last updated: 2026-11-01
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add daveebbelaar/bama --skill swift-swiftui -g -a claude-code -y`
Codex: `npx skills add daveebbelaar/bama --skill swift-swiftui -g -a codex -y`
Cursor: `npx skills add daveebbelaar/bama --skill swift-swiftui -g -a cursor -y`
Gemini CLI: `npx skills add daveebbelaar/bama --skill swift-swiftui -g -a gemini-cli -y`
Claude Code plugin marketplace: `/plugin marketplace add daveebbelaar/bama`

## Description

Swift 6 and SwiftUI code rules for macOS apps, including concurrency, state, SwiftData, AppKit bridges, and fixes for common compiler errors. Use when writing, reviewing, or debugging Swift code in a Mac app, or on concurrency, Sendable, or "not in scope" errors.

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# Swift and SwiftUI

The code is right when it compiles with zero warnings in Swift 6 language
mode and the app does what the story says. For how it should look, call the
Skill tool with `mac-design`. For copyable view code, read
[../../design/mac-design/patterns.md](../../design/mac-design/patterns.md).

## Concurrency

The template sets main-actor default isolation: every type and function runs
on the main actor unless you say otherwise. UI code needs no annotations.

| Work | Put it in |
| --- | --- |
| UI state, views, view models | Default (main actor) |
| CPU-heavy pure work (parsing, image work, diffing) | A `nonisolated` function marked `@concurrent` |
| Shared mutable state used off the main thread | An `actor` |
| A C callback (event tap, Carbon hotkey, CoreAudio listener) | A `nonisolated` static func that hops back with `Task { @MainActor in ... }` |

- Data that crosses actors is `Sendable`: structs and enums of `Sendable`
  values, or `final class` with only `let` properties.
- `MainActor.assumeIsolated { }` inside a callback you know runs on the main
  thread (a main run loop `Timer`, a main queue notification).
- `Task { }` inherits the actor. `Task.detached` only when it must not.
- Fix a concurrency error at its type, not with `@unchecked Sendable` or
  `nonisolated(unsafe)`. Those two are a last resort, with a comment why.
- **Runtime trap the compiler misses.** A closure created inside a
  `@MainActor` type and passed to an API without a `@Sendable` closure
  parameter (`DispatchSource.setEventHandler`, `DispatchWorkItem`,
  `addPeriodicTimeObserver`, CoreAudio listener blocks) inherits the main
  actor. When it runs on a background queue, Swift 6 crashes the app. Write
  it as `{ @Sendable in ... }`, and run every background path once after
  any concurrency change.

## State

The rest: https://github.com/daveebbelaar/bama/blob/HEAD/skills/code/swift-swiftui/SKILL.md
