Skills/swift-best-practices/SKILL.md
This skill should be used when writing or reviewing Swift code for iOS or macOS projects. Apply modern Swift 6+ best practices, concurrency patterns, API design guidelines, and migration strategies. Covers async/await, actors, MainActor, Sendable, typed throws, and Swift 6 breaking changes.
npx skillsauth add sammcj/agentic-coding swift-best-practicesInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Apply modern Swift development best practices focusing on Swift 6+ features, concurrency safety, API design principles, and code quality guidelines for iOS and macOS projects targeting macOS 15.7+.
Use this skill when:
var greeting = "Hello" not var string = "Hello"Swift 6 enables complete concurrency checking by default with region-based isolation (SE-0414). The compiler now proves code safety, eliminating many false positives whilst catching real concurrency issues at compile time.
Critical understanding:
@MainActor ensures UI-related code executes on the main threadSendable// Parallel execution with async let
func fetchData() async -> (String, Int) {
async let stringData = fetchString()
async let intData = fetchInt()
return await (stringData, intData)
}
// Always check cancellation in long-running operations
func process(_ items: [Item]) async throws -> [Result] {
var results: [Result] = []
for item in items {
try Task.checkCancellation()
results.append(await process(item))
}
return results
}
// Apply at type level for consistent isolation
@MainActor
class ContentViewModel: ObservableObject {
@Published var images: [UIImage] = []
func fetchData() async throws {
self.images = try await fetchImages()
}
}
// Avoid MainActor.run when direct await works
await doMainActorStuff() // Good
await MainActor.run { doMainActorStuff() } // Unnecessary
actor DataCache {
private var cache: [String: Data] = [:]
func store(_ data: Data, forKey key: String) {
cache[key] = data // No await needed inside actor
}
nonisolated func cacheType() -> String {
return "DataCache" // No await needed - doesn't access isolated state
}
}
async unnecessarily - async calling convention has overheadDispatchSemaphore with async/await - risk of deadlockTask.checkCancellation()UpperCamelCaselowerCamelCase-able, -ible, -ing suffixes (Equatable, ProgressReporting)make (x.makeIterator())x.sort() / x.sorted())x.distance(to: y))x.append(y), x.sort())min(number1, number2)Int64(someUInt32)x.removeBoxes(havingLength: 12)Property wrappers no longer infer actor isolation automatically.
@MainActor
struct LogInView: View {
@StateObject private var model = ViewModel()
}
static let config = Config() // Constant - OK
@MainActor static var state = State() // Actor-isolated - OK
nonisolated(unsafe) var cache = [String: Data]() // Unsafe - use with caution
@UIApplicationMain/@NSApplicationMain deprecated (use @main)any required for existential types// Basic availability
@available(macOS 15, iOS 18, *)
func modernAPI() { }
// Deprecation with message
@available(*, deprecated, message: "Use newMethod() instead")
func oldMethod() { }
// Renaming with auto-fix
@available(*, unavailable, renamed: "newMethod")
func oldMethod() { }
// Runtime checking
if #available(iOS 18, *) {
// iOS 18+ code
}
// Inverted checking (Swift 5.6+)
if #unavailable(iOS 18, *) {
// iOS 17 and lower
}
Key differences:
deprecated - Warning, allows usageobsoleted - Error from specific versionunavailable - Error, completely prevents usage@MainActor for UI, actors for mutable state)count(where:) over filter().countInlineArray for fixed-size, performance-critical dataSendable conformancesDetailed reference material to load when in-depth information is needed:
@available attribute usage, deprecation strategies, and platform version managementLoad these references when detailed information is needed beyond the core guidelines provided above.
#available for runtime platform detection@available for API availability markingtools
Provides tools for managing MarkEdit, a macOS markdown editor
tools
Provides knowledge on using the `glean` CLI tool to access company knowledge and documents through Glean. Use when the user asks you to use Glean to search, read or otherwise access knowledge from their company's Confluence, Slack, Google Drive Files (Slides, Documents, Sheets) etc.
development
Applies the Diataxis framework to create or improve technical documentation. Use when being asked to write high quality tutorials, how-to guides, reference docs, or explanations, when reviewing documentation quality, or when deciding what type of documentation to create. Helps identify documentation types using the action/cognition and acquisition/application dimensions.
development
Use when answering questions from this machine-learning knowledge base. Triggers: questions about transformers, attention cost and efficiency, and long-context scaling; 'what do we know about attention', 'check the ML wiki'. Read-only querying of compiled knowledge; to add, update, supersede, lint, audit, or critique, use the llm-wiki skill instead.