Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases
日本語の概要は準備中です。原文の説明を表示しています。
Use when building native iOS with SwiftUI - small composable views, observable state models, atomic components, Swift 6.2+ concurrency, and system styling over hardcoded values
インストール方法を見るインストールする前に、エージェントに与えられる指示の中身を確認できます。
Native iOS (SwiftUI) is chosen when a task needs deep Apple-platform integration or the app is already native (see native-vs-flutter-decision). Same discipline as Flutter: small composed views, state out of the view, reusable atomic components.
Core principle: Views are a function of state. Data and business logic live in an observable model, not in the View.
View types (not @ViewBuilder funcs) so each has its own body and preview.@State for local ephemeral UI only (and it is always private); app/business state in an @MainActor @Observable model injected via init/@Environment. Views send intents to the model; the model owns the logic and the networking.Color semantic roles, spacing/typography from a tokens file (see mobile-design-system-foundation) — not scattered magic numbers. Support Dynamic Type and dark mode.#Preview every reusable view in its key states (loading/data/error), and in the matrix: Dynamic Type .accessibility3, dark, traits: .landscapeLeft.struct) for models and view state; reference types only where identity is needed.Task — it shadows _Concurrency.Task, which every async/.task {} call site needs; a rename (BoardItem, WorkItem, …) is a five-minute fix versus a confusing compile error later.@MainActor isolation, so a view model that touches UI state should be @MainActor @Observable explicitly rather than relying on inference holding across Swift versions.DispatchQueue.main.async, etc.) in new code — async/await, Task { }, Task.sleep(for:)..task { } on the view, not onAppear + a detached Task.struct BoardItem: Identifiable, Sendable { let id: Int; let title: String } // never name a model `Task`
enum LoadState<T> { case loading, empty, data(T), failed(String) }
@MainActor @Observable final class ItemListModel {
private(set) var state: LoadState<[BoardItem]> = .loading
private let repo: any BoardItemRepository
init(repo: any BoardItemRepository) { self.repo = repo }
func load() async {
state = .loading
do { let items = try await repo.list(); state = items.isEmpty ? .empty : .data(items) }
catch { state = .failed(error.localizedDescription) }
}
}
struct ItemListScreen: View {
@State private var model: ItemListModel
init(model: ItemListModel) { _model = State(initialValue: model) }
var body: some View {
Group {
switch model.state {
case .loading: AppSpinner()
case .empty: ContentUnavailableView("No items yet", systemImage: "tray")
case .failed(let message):
ContentUnavailableView {
Label("Couldn't load items", systemImage: "exclamationmark.triangle")
} description: { Text(message) } actions: {
Button("Try again") { Task { await model.load() } }
}
case .data(let items): ItemList(items: items)
}
}
.task { await model.load() }
}
}
Typechecks with swiftc -swift-version 6 (verified). The original example's domain struct Task shadowed _Concurrency.Task, giving error: missing argument for parameter 'title' in call at every Task { } call site — renamed to BoardItem here. Note the explicit .empty case rendered with ContentUnavailableView and a retry action on .failed, and the init that seeds State(initialValue:) so the model can be injected.
Previews at the matrix (typechecked against the iOS 18 simulator SDK):
#Preview("Phone, AX3, dark") { ItemListScreen(model: .preview).environment(\.dynamicTypeSize, .accessibility3).preferredColorScheme(.dark) }
#Preview("Landscape", traits: .landscapeLeft) { ItemListScreen(model: .preview) }
For a layout that must switch at large accessibility sizes: typeSize.isAccessibilitySize ? AnyLayout(VStackLayout()) : AnyLayout(HStackLayout()). For an icon-only control: Button("Add to cart", systemImage: "cart.badge.plus", action:) with .labelStyle(.iconOnly) and .frame(minWidth: 44, minHeight: 44) (see mobile-accessibility).
@Observable model with a mocked repository (no UI).import Testing, @Test, #expect) where the target already uses Xcode 16+; XCTest stays for existing UI tests and app.performAccessibilityAudit(). Test-first.foregroundStyle (not foregroundColor), .clipShape(.rect(cornerRadius:)) (not .cornerRadius), the Tab API for tab bars, the two-parameter onChange(of:) { old, new in }, .topBarTrailing placement, containerRelativeFrame instead of GeometryReader when it covers the case, never UIScreen.main.bounds.Color.withValues is not a thing in SwiftUI (that's the Flutter equivalent) — use asset-catalog colours or Color(.sRGB, ...)/.opacity() as the repo already does..glassEffect only on custom floating controls, and only when the task asks for it.UIDesignRequiresCompatibility is ignored when building with the iOS 27 SDK — don't rely on it to opt back out of the new look.body / View.@ViewBuilder helper funcs instead of real subviews.Task.async/await.View with a URLSession call in it.Color(red:...) and paddings sprinkled across views.body.Task anywhere in the diff.まだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases
日本語の概要は準備中です。原文の説明を表示しています。
Use when the diff adds or changes an endpoint, resolver, RPC, job or query that takes an object id, a role check, a request binding or a tenant filter - BOLA/IDOR, function-level authorization, mass assignment and tenant scoping
日本語の概要は準備中です。原文の説明を表示しています。
Use on every UI change - semantic HTML, labels for controls, keyboard-navigable dialogs/menus, visible focus, and never color as the only signal
日本語の概要は準備中です。原文の説明を表示しています。
Use when a task changes any screen, form, dialog, menu or control - Lighthouse/axe scan of the changed screens, a keyboard walk, and the thresholds that fail a task
日本語の概要は準備中です。原文の説明を表示しています。
How to work a task returned with review, QA or UAT findings. Use when a task is in need_revision or PR review comments are in your context.
日本語の概要は準備中です。原文の説明を表示しています。
Use when deciding whether a request needs an analiz task before implementation - the conditions that require the architect's analysis versus going straight to implementation
日本語の概要は準備中です。原文の説明を表示しています。