Slash Command
/swift
- Prefer Swift-native string methods over Foundation equivalents: use `replacing("a", with: "b")` not `replacingOccurrences(of: "a", with: "b")`.
From swiftuiInstall
1
Run in your terminal$
npx claudepluginhub fradser/dotclaude --plugin swiftuiDetails
Namespace
swiftui-review/references/Command Content
Swift
- Prefer Swift-native string methods over Foundation equivalents: use
replacing("a", with: "b")notreplacingOccurrences(of: "a", with: "b"). - Prefer modern Foundation API:
URL.documentsDirectoryinstead ofFileManagerdirectory lookups,appending(path:)to append strings to a URL. - Never use C-style number formatting like
String(format: "%.2f", value). UseText(value, format: .number.precision(.fractionLength(2)))or similarFormatStyleAPIs. - Prefer static member lookup to struct instances where possible, such as
.circlerather thanCircle(), and.borderedProminentrather thanBorderedProminentButtonStyle(). - Avoid force unwraps (
!) and forcetryunless the failure is truly unrecoverable, and even then prefer usingfatalError()with a clear description. If possible, useif let,guard let, nil-coalescing, ortry?/do-catch. - Filtering text based on user-input must be done using
localizedStandardContains()as opposed tocontains()orlocalizedCaseInsensitiveContains(). - Strongly prefer
DoubleoverCGFloat, except when using optionals orinout; Swift is able to bridge the two freely except in those two cases. - If you want to count array objects that match a predicate, always use
count(where:)rather thanfilter()followed bycount. - Prefer
Date.nowoverDate()for clarity. - When
import SwiftUIis already in a file, you do not need to addimport UIKitorimport AppKitto access things likeUIImageorNSImage– they are imported automatically on the appropriate platform. - When dealing with the names of people, strongly prefer to use
PersonNameComponentswith modern formatting over simple string interpolation such asText("\(firstName) \(lastName)"). - If a given type of data is repeatedly sorted using an identical closure, e.g.
books.sorted { $0.author < $1.author }, prefer to make the type in question conform toComparableso the sort order is centralized. - Prefer to avoid manual date formatting strings if possible. If manual date formatting is used for user display, at least make sure to use “y” rather than “yyyy” for years, so the year value is correct in all localizations. If the purpose is data exchange with an API, this rule does not apply.
- When trying to convert a string to a date, prefer the modern
Dateinitializer API such asDate(myString, strategy: .iso8601). - Flag instances where errors triggered by a user action are swallowed silently, e.g. using
print(error.localizedDescription)rather than showing an alert or similar. - Prefer
if let value {shorthand overif let value = value {. - Omit return for single expression functions.
ifandswitchcan be used as expressions when returning values and assigning to variables.
For example, this kind of code:
var tileColor: Color {
if isCorrect {
return .green
} else {
return .red
}
}
Should be written like this:
var tileColor: Color {
if isCorrect {
.green
} else {
.red
}
}
Swift Concurrency
- If an API offers both modern
async/awaitequivalents and older closure-based variants, always prefer theasync/awaitversions. - Never use Grand Central Dispatch (
DispatchQueue.main.async(),DispatchQueue.global(), etc.). Always use modern Swift concurrency (async/await, actors,Task). - Never use
Task.sleep(nanoseconds:); useTask.sleep(for:)instead. - Flag any mutable shared state that isn't protected by an actor or
@MainActor, unless the project is configured to use MainActor default actor isolation. - Assume strict concurrency rules are being applied; flag
@Sendableviolations and data races. - When evaluating
MainActor.run(), check whether the project has its default actor isolation set to Main Actor first, becauseMainActor.run()might not be needed. Task.detached()is often a bad idea. Check any usage extremely carefully.
Other plugins with /swift
Stats
Parent Repo Stars474
Parent Repo Forks37
Last CommitMar 9, 2026