swift-optimization
| Type | Skill |
| Plugin | awl-ios · v0.0.6 |
| Invoke | /awl-ios:swift-optimization |
| Tools | Read, Write, Edit, Bash, Glob, Grep |
| Source | plugins/awl-ios/skills/swift-optimization/SKILL.md |
When Claude uses it
Abschnitt betitelt „When Claude uses it“Optimize Swift/SwiftUI code with modern patterns. Triggers: “optimize swift”, “refactor swiftui”, “fix deprecated”, “modernize swift”, “swift best practices”, “review swift code”, “migrate to Swift 6”, “fix concurrency warnings”. Replaces deprecated APIs, improves accessibility, fixes Swift 6 strict-concurrency errors under main-actor default isolation, and targets the AWL template baseline (Swift 6.0, iOS 26.4). NOT for writing tests (use awl-testing testing-swift), not for build or simulator commands (use awl-ios-ref), not for KMP shared Kotlin code (use awl-android kotlin-expert).
Trigger phrases: optimize swift · refactor swiftui · fix deprecated · modernize swift · swift best practices · review swift code · migrate to Swift 6 · fix concurrency warnings
Definition
Abschnitt betitelt „Definition“Modernize Swift/SwiftUI code by replacing deprecated APIs, improving accessibility, and applying performance best practices.
Target baseline
Abschnitt betitelt „Target baseline““Modernize” means the AWL iOS template baseline from Project.swift, not an older floor:
| Setting | Value |
|---|---|
SWIFT_VERSION |
6.0 (strict concurrency, data races are errors) |
SWIFT_DEFAULT_ACTOR_ISOLATION |
MainActor (everything is main-actor isolated unless nonisolated) |
SWIFT_APPROACHABLE_CONCURRENCY |
YES (nonisolated async runs on the caller; @concurrent moves work off the main actor) |
minIosVersion |
26.4 for the app template, 18.0 for the KMP iOS shell |
Consequences: @Observable, NavigationStack, Tab, containerRelativeFrame, and two-parameter onChange are always available, so drop #available(iOS 17, *) and #available(iOS 18, *) gates; only Liquid Glass (iOS 26) needs a gate, and only in the KMP shell. Check Project.swift before applying this to a project that was not built from the template.
Instructions
Abschnitt betitelt „Instructions“Step 1: Identify Target Files
Abschnitt betitelt „Step 1: Identify Target Files“# Find Swift files to optimizefind . -name "*.swift" -type f | head -20Step 2: Scan for Deprecated Patterns
Abschnitt betitelt „Step 2: Scan for Deprecated Patterns“Search for these common issues:
foregroundColor(- replace withforegroundStyle(cornerRadius(- replace withclipShape(.rect(cornerRadius:NavigationView- replace withNavigationStackObservableObject- consider@ObservablemacroonTapGestureon interactive elements - replace withButtonTask.sleep(nanoseconds:- replace withTask.sleep(for:DispatchQueue.main.asyncandawait MainActor.run- remove the hop; code is already main-actor isolated under default isolationDispatchQueue.global,Task.detachedfor CPU work - replace with a@concurrent nonisolated func@MainActoron views, view models, or@Observableclasses in template targets - remove, it is redundant underSWIFT_DEFAULT_ACTOR_ISOLATION = MainActor#available(iOS 17, *)/#available(iOS 18, *)- remove, the deployment target already covers them
Step 3: Apply Fixes
Abschnitt betitelt „Step 3: Apply Fixes“For each file, apply modernizations in order:
- Import changes (if needed)
- Type-level changes (@Observable)
- Modifier replacements
- Accessibility improvements
Quick Reference
Abschnitt betitelt „Quick Reference“| Deprecated | Modern |
|---|---|
foregroundColor(.blue) |
foregroundStyle(.blue) |
cornerRadius(10) |
clipShape(.rect(cornerRadius: 10)) |
NavigationView { } |
NavigationStack { } |
@StateObject var vm |
@State var vm (with @Observable) |
.onChange(of: x) { val in } |
.onChange(of: x) { old, new in } |
Examples
Abschnitt betitelt „Examples“Navigation Modernization
Abschnitt betitelt „Navigation Modernization“// BeforeNavigationView { NavigationLink(destination: DetailView(item: item)) { Text(item.name) }}
// AfterNavigationStack { List(items) { item in NavigationLink(value: item) { Text(item.name) } } .navigationDestination(for: Item.self) { DetailView(item: $0) }}Observable Pattern
Abschnitt betitelt „Observable Pattern“// Beforeclass ViewModel: ObservableObject { @Published var items: [Item] = []}struct ContentView: View { @StateObject var viewModel = ViewModel()}
// After@Observable class ViewModel { var items: [Item] = []}struct ContentView: View { @State var viewModel = ViewModel()}Accessibility Fix
Abschnitt betitelt „Accessibility Fix“// Before (bad for VoiceOver)Image(systemName: "plus").onTapGesture { addItem() }
// AfterButton("Add Item", systemImage: "plus", action: addItem)Troubleshooting
Abschnitt betitelt „Troubleshooting“| Issue | Solution |
|---|---|
| @Observable not available | Only on targets below iOS 17; every AWL template target is above that, so check Project.swift before keeping ObservableObject. |
| NavigationStack crashes | Ensure navigation values conform to Hashable. |
| onChange signature error | Use two-param { old, new in } or zero-param { } version. |
| “Main actor-isolated … cannot be called from a nonisolated context” | The caller is nonisolated (protocol witness, @concurrent function, or a package without default isolation). Either make the caller main-actor isolated or pass Sendable values across and hop with await. |
| “Sending value of non-Sendable type … risks causing data races” | Mark the type Sendable (struct with let properties, or final class with immutable state), or keep the value inside one isolation region as the KMP template’s GreetingViewModel does. |
| Heavy work blocks the UI | Move it to a @concurrent nonisolated func; a plain nonisolated async function still runs on the main actor under approachable concurrency. |
Checklist
Abschnitt betitelt „Checklist“- Deprecated modifiers replaced
- Navigation modernized
- Observable pattern updated
- Accessibility improved (Button over onTapGesture)
- Concurrency uses structured patterns; no
DispatchQueue, no redundant@MainActor, heavy work in@concurrent - Builds without Swift 6 data-race errors
- No
#availablegates below the deployment target - No fixed frame sizes (use flexible layouts)
- One type per file
References
Abschnitt betitelt „References“- Detailed patterns:
references/swift-patterns.md - Based on: hackingwithswift.com/articles/281/what-to-fix-in-ai-generated-swift-code

