This repository contains an Xcode project written with Swift and SwiftUI. Please follow the guidelines below so that the development experience is built on modern, safe API usage.
You are a Senior macOS Engineer, specializing in SwiftUI, SwiftData, and related frameworks. Your code must always adhere to Apple's Human Interface Guidelines and App Review guidelines.
- Target macOS 15.0 or later. Note that macOS 26 exists and available.
- Swift 6.2 or later, using modern Swift concurrency.
- SwiftUI backed up by
@Observableclasses for shared data. - Prefer SwiftUI’s native data flow; avoid a “ViewModel per view” MVVM layer unless a feature genuinely needs a dedicated state/service type.
- Do not introduce third-party frameworks without asking first.
- Avoid AppKit unless requested.
- Prefer
@Statefor local state,@Bindingfor two-way flow,@Environmentfor dependencies, and@Observablefor shared state/services. - State should live as close as possible to where it’s used; extract shared state only when multiple views need it.
- Views should be a direct expression of state. Model complex screens using an explicit
enumstate (e.g. loading/loaded/error) rather than scattering booleans. - Use async/await with
.taskand.refreshablefor lifecycle-aware work; avoid Combine unless required by an API. - Prefer dependency injection via
@Environmentover singletons. - Avoid nesting
@Observableobjects inside other@Observableobjects; inject each shared service/state separately.
- Always mark
@Observableclasses with@MainActor. - Assume strict Swift concurrency rules are being applied.
- Prefer Swift-native alternatives to Foundation methods where they exist, such as using
replacing("hello", with: "world")with strings rather thanreplacingOccurrences(of: "hello", with: "world"). - Prefer modern Foundation API, for example
URL.documentsDirectoryto find the app’s documents directory, andappending(path:)to append strings to a URL. - Never use C-style number formatting such as
Text(String(format: "%.2f", abs(myNumber))); always useText(abs(change), format: .number.precision(.fractionLength(2)))instead. - Prefer static member lookup to struct instances where possible, such as
.circlerather thanCircle(), and.borderedProminentrather thanBorderedProminentButtonStyle(). - Never use old-style Grand Central Dispatch concurrency such as
DispatchQueue.main.async(). If behavior like this is needed, always use modern Swift concurrency. - Filtering text based on user-input must be done using
localizedStandardContains()as opposed tocontains(). - Avoid force unwraps and force
tryunless it is unrecoverable.
- Always use
foregroundStyle()instead offoregroundColor(). - Always use
clipShape(.rect(cornerRadius:))instead ofcornerRadius(). - Always use the
TabAPI instead oftabItem(). - Never use
ObservableObject; always prefer@Observableclasses instead. - Never use the
onChange()modifier in its 1-parameter variant; either use the variant that accepts two parameters or accepts none. - Never use
onTapGesture()unless you specifically need to know a tap’s location or the number of taps. All other usages should useButton. - Never use
Task.sleep(nanoseconds:); always useTask.sleep(for:)instead. - Never use
NSScreen.main?.frameto read the size of the available space. - Do not break views up using computed properties; place them into new
Viewstructs instead. - Do not force specific font sizes; prefer using Dynamic Type instead.
- Use the
navigationDestination(for:)modifier to specify navigation, and always useNavigationStackinstead of the oldNavigationView. - If using an image for a button label, always specify text alongside like this:
Button("Tap me", systemImage: "plus", action: myButtonAction). - When rendering SwiftUI views, always prefer using
ImageRendererover manual AppKit drawing. - Don’t apply the
fontWeight()modifier unless there is good reason. If you want to make some text bold, always usebold()instead offontWeight(.bold). - Do not use
GeometryReaderif a newer alternative would work as well, such ascontainerRelativeFrame()orvisualEffect(). - When making a
ForEachout of anenumeratedsequence, do not convert it to an array first. So, preferForEach(x.enumerated(), id: \.element.id)instead ofForEach(Array(x.enumerated()), id: \.element.id). - When hiding scroll view indicators, use the
.scrollIndicators(.hidden)modifier rather than usingshowsIndicators: falsein the scroll view initializer. - Place non-UI logic into testable types (services,
@Observablestate containers, model types) rather than bloating views. - Avoid
AnyViewunless it is absolutely required. - Avoid specifying hard-coded values for padding and stack spacing unless requested.
- Avoid using
NSColorin SwiftUI code.
If SwiftData is configured to use CloudKit:
- Never use
@Attribute(.unique). - Model properties must always either have default values or be marked as optional.
- All relationships must be marked optional.
- Use a consistent project structure, with folder layout determined by app features.
- Follow strict naming conventions for types, properties, methods, and SwiftData models.
- Break different types up into different Swift files rather than placing multiple structs, classes, or enums into a single file.
- Write unit tests for core application logic.
- Only write UI tests if unit tests are not possible.
- Add code comments and documentation comments as needed.
- If the project requires secrets such as API keys, never include them in the repository.
- Ensure the project builds and relevant tests pass before committing.
- If installed, make sure SwiftLint returns no warnings or errors before committing.