1---2name: ios-swift-api-design-reviewer3description: Reviews Swift function, type, and protocol interfaces for alignment with the Swift API Design Guidelines, with emphasis on call-site clarity, naming, parameter labeling, mutability conventions, and modern async/throws patterns. Use for public APIs, reusable components, SDKs, and shared modules.4---56# Swift API Design Review78## What “good” looks like910- Prioritize **clarity at the call site**, even if the declaration becomes a bit longer.11- Follow established **standard library conventions** so your API “feels Swift”.12- Prefer **precise words** over generic ones (`data`, `info`, `manager`, `handler`, `util`).1314## Naming Rules (Types, Properties, Methods)1516- **Clear at point of use**, not at declaration.17- **Omit needless words**, but do not remove words that carry meaning.18- **lowerCamelCase**: functions, methods, properties, enum cases.19- **UpperCamelCase**: types, protocols.20- Avoid “noise” suffixes like `String`, `Array`, `Data` unless they add meaning.2122### Boolean naming2324- Prefer predicates: `is`, `has`, `can`, `should`, `did`.25- Match the natural reading of the call site.26 - ✅ `if user.isEligible { … }`27 - ✅ `if cache.hasValue(forKey: k) { … }`2829### Verbs and mutability3031- **Mutating** methods are verbs: `sort()`, `append(_)`, `removeAll()`.32- **Non-mutating** counterparts use “-ed”: `sorted()`, `appending(_)`, `removingAll()` when appropriate.3334## Common Issues (with better fixes)3536| Issue | Better Fix |37| --- | --- |38| `var visible` | `var isVisible` |39| `func get()` | Use a precise verb or a noun that reads well at the call site: `func userName()`, `func loadUserName()`, `func fetchUserName()` |40| `var nameString` | `var name` |41| `func add(item: x, to: y)` | `func add(_ item: Item, to collection: Collection)` |42| `func doStuff()` | Name the domain action: `func refresh()`, `func rebuildIndex()`, `func startSession()` |43| `func handle(_ x: …)` | Be specific: `func handleDeepLink(_:)` or `func route(_:)` |4445## Parameter & Label Design (call-site first)4647- The **first argument label** should be omitted when it forms a natural phrase:48 - ✅ `add(_ item:to:)`49 - ✅ `contains(_:)`50- Use labels to clarify roles, units, and semantics:51 - ✅ `move(from:to:)`52 - ✅ `setDeadline(_:, for:)`53 - ✅ `resize(to:)` (size), `resize(by:)` (scale factor)54- Keep **default parameters last** when it improves scanning and discoverability.55- Closure parameters are usually **last**, but:56 - If there are **multiple closures**, label them clearly.57 - If a closure is *configuration* rather than *action*, it may be clearer earlier.5859### Preferred label vocabulary (common Swift patterns)6061- `in:` container or scope62- `from:` source63- `to:` destination64- `at:` position or index65- `with:` accompanying value66- `using:` algorithm/tool dependency67- `for:` beneficiary or target entity68- `by:` delta, factor, or means6970## Return Types & Error Handling7172- Use **optional** only when `nil` is a meaningful “no value” state.73- Use **throws** for failures that should be handled via `do/catch`.74- Use **Result** when:75 - You need to store/transport outcomes,76 - You are bridging callback-based APIs,77 - You want explicit success/failure as a value.78- Prefer **structs** over tuples when:79 - More than 2–3 fields,80 - Fields need names that matter,81 - The value is passed around broadly.8283## Async / Concurrency (modern Swift)8485- Prefer `async`/`await` over completion handlers for new APIs.86- Avoid `Async` suffixes unless required for disambiguation.87 - ✅ `func refresh() async throws`88 - ✅ `func loadImage() async -> Image`89- Cancellation:90 - Prefer being cancellation-cooperative rather than inventing custom cancel APIs.91 - Consider how the API behaves when the task is cancelled (does it throw `CancellationError`?).92- Actor isolation:93 - Avoid marking pure data models `@MainActor`.94 - Keep UI-bound types `@MainActor` when they are truly view-facing.9596## Type & Protocol Naming9798- Protocols should name *capabilities*:99 - ✅ `Cache`, `ImageLoading`, `Persisting`100- Types should name *what they are*:101 - ✅ `ImageCache`, `URLSessionImageLoader`, `KeychainStore`102- Avoid vague names:103 - 🚫 `Manager`, `Helper`, `Util`, `Common`, `Base` (unless truly established in the domain)104105## Quick Review Checklist106107- [ ] Does every API read clearly **at the call site**?108- [ ] Are names consistent with **stdlib conventions** (mutating vs non-mutating)?109- [ ] Are parameter labels meaningful (roles, units, direction: `from/to/at/with`)?110- [ ] Are “get”, “do”, “handle”, “data/info” avoided unless truly accurate?111- [ ] Are return types chosen intentionally (optional vs throws vs Result)?112- [ ] Do async/throws APIs follow modern Swift patterns without “Async” noise?113114## Severity115116- 🔴 **Critical**: Violates guidelines or likely to cause misuse/confusion.117- 🟡 **Improvement**: Usable, but naming/labels could be clearer and more Swift-like.118- 🟢 **Enhancement**: Polish that improves consistency and ergonomics.119120## Output format (recommended)121122- **Summary**: 2–5 bullets of highest-impact issues.123- **Findings**: Grouped by Naming, Parameters, Return Types, Concurrency.124- Each issue labeled with 🔴🟡🟢 and includes a **before → after** suggestion.