swift-code-reviewer-skill 1.2.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -169
- package/README.md +43 -2
- package/SKILL.md +107 -742
- package/bin/install.js +1 -1
- package/package.json +2 -1
- package/references/companion-skills.md +70 -0
- package/skills/README.md +43 -0
- package/skills/swift-concurrency/NOTICE.md +18 -0
- package/skills/swift-concurrency/SKILL.md +235 -0
- package/skills/swift-concurrency/references/actors.md +640 -0
- package/skills/swift-concurrency/references/async-await-basics.md +249 -0
- package/skills/swift-concurrency/references/async-sequences.md +635 -0
- package/skills/swift-concurrency/references/core-data.md +533 -0
- package/skills/swift-concurrency/references/glossary.md +96 -0
- package/skills/swift-concurrency/references/linting.md +38 -0
- package/skills/swift-concurrency/references/memory-management.md +542 -0
- package/skills/swift-concurrency/references/migration.md +721 -0
- package/skills/swift-concurrency/references/performance.md +574 -0
- package/skills/swift-concurrency/references/sendable.md +578 -0
- package/skills/swift-concurrency/references/tasks.md +604 -0
- package/skills/swift-concurrency/references/testing.md +565 -0
- package/skills/swift-concurrency/references/threading.md +452 -0
- package/skills/swift-expert/NOTICE.md +18 -0
- package/skills/swift-expert/SKILL.md +226 -0
- package/skills/swift-expert/references/async-concurrency.md +363 -0
- package/skills/swift-expert/references/memory-performance.md +380 -0
- package/skills/swift-expert/references/protocol-oriented.md +357 -0
- package/skills/swift-expert/references/swiftui-patterns.md +294 -0
- package/skills/swift-expert/references/testing-patterns.md +402 -0
- package/skills/swift-testing/NOTICE.md +18 -0
- package/skills/swift-testing/SKILL.md +295 -0
- package/skills/swift-testing/references/async-testing.md +245 -0
- package/skills/swift-testing/references/dump-snapshot-testing.md +265 -0
- package/skills/swift-testing/references/fixtures.md +193 -0
- package/skills/swift-testing/references/integration-testing.md +189 -0
- package/skills/swift-testing/references/migration-xctest.md +301 -0
- package/skills/swift-testing/references/parameterized-tests.md +171 -0
- package/skills/swift-testing/references/snapshot-testing.md +201 -0
- package/skills/swift-testing/references/test-doubles.md +243 -0
- package/skills/swift-testing/references/test-organization.md +231 -0
- package/skills/swiftui-expert-skill/NOTICE.md +18 -0
- package/skills/swiftui-expert-skill/SKILL.md +281 -0
- package/skills/swiftui-expert-skill/references/accessibility-patterns.md +151 -0
- package/skills/swiftui-expert-skill/references/animation-advanced.md +403 -0
- package/skills/swiftui-expert-skill/references/animation-basics.md +284 -0
- package/skills/swiftui-expert-skill/references/animation-transitions.md +326 -0
- package/skills/swiftui-expert-skill/references/charts-accessibility.md +135 -0
- package/skills/swiftui-expert-skill/references/charts.md +602 -0
- package/skills/swiftui-expert-skill/references/image-optimization.md +203 -0
- package/skills/swiftui-expert-skill/references/latest-apis.md +464 -0
- package/skills/swiftui-expert-skill/references/layout-best-practices.md +266 -0
- package/skills/swiftui-expert-skill/references/liquid-glass.md +414 -0
- package/skills/swiftui-expert-skill/references/list-patterns.md +394 -0
- package/skills/swiftui-expert-skill/references/macos-scenes.md +318 -0
- package/skills/swiftui-expert-skill/references/macos-views.md +357 -0
- package/skills/swiftui-expert-skill/references/macos-window-styling.md +303 -0
- package/skills/swiftui-expert-skill/references/performance-patterns.md +403 -0
- package/skills/swiftui-expert-skill/references/scroll-patterns.md +293 -0
- package/skills/swiftui-expert-skill/references/sheet-navigation-patterns.md +363 -0
- package/skills/swiftui-expert-skill/references/state-management.md +417 -0
- package/skills/swiftui-expert-skill/references/view-structure.md +389 -0
- package/skills/swiftui-ui-patterns/NOTICE.md +18 -0
- package/skills/swiftui-ui-patterns/SKILL.md +95 -0
- package/skills/swiftui-ui-patterns/references/app-wiring.md +201 -0
- package/skills/swiftui-ui-patterns/references/async-state.md +96 -0
- package/skills/swiftui-ui-patterns/references/components-index.md +50 -0
- package/skills/swiftui-ui-patterns/references/controls.md +57 -0
- package/skills/swiftui-ui-patterns/references/deeplinks.md +66 -0
- package/skills/swiftui-ui-patterns/references/focus.md +90 -0
- package/skills/swiftui-ui-patterns/references/form.md +97 -0
- package/skills/swiftui-ui-patterns/references/grids.md +71 -0
- package/skills/swiftui-ui-patterns/references/haptics.md +71 -0
- package/skills/swiftui-ui-patterns/references/input-toolbar.md +51 -0
- package/skills/swiftui-ui-patterns/references/lightweight-clients.md +93 -0
- package/skills/swiftui-ui-patterns/references/list.md +86 -0
- package/skills/swiftui-ui-patterns/references/loading-placeholders.md +38 -0
- package/skills/swiftui-ui-patterns/references/macos-settings.md +71 -0
- package/skills/swiftui-ui-patterns/references/matched-transitions.md +59 -0
- package/skills/swiftui-ui-patterns/references/media.md +73 -0
- package/skills/swiftui-ui-patterns/references/menu-bar.md +101 -0
- package/skills/swiftui-ui-patterns/references/navigationstack.md +159 -0
- package/skills/swiftui-ui-patterns/references/overlay.md +45 -0
- package/skills/swiftui-ui-patterns/references/performance.md +62 -0
- package/skills/swiftui-ui-patterns/references/previews.md +48 -0
- package/skills/swiftui-ui-patterns/references/scroll-reveal.md +133 -0
- package/skills/swiftui-ui-patterns/references/scrollview.md +87 -0
- package/skills/swiftui-ui-patterns/references/searchable.md +71 -0
- package/skills/swiftui-ui-patterns/references/sheets.md +155 -0
- package/skills/swiftui-ui-patterns/references/split-views.md +72 -0
- package/skills/swiftui-ui-patterns/references/tabview.md +114 -0
- package/skills/swiftui-ui-patterns/references/theming.md +71 -0
- package/skills/swiftui-ui-patterns/references/title-menus.md +93 -0
- package/skills/swiftui-ui-patterns/references/top-bar.md +49 -0
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
# Async/Await Basics
|
|
2
|
+
|
|
3
|
+
Core patterns and best practices for async/await in Swift.
|
|
4
|
+
|
|
5
|
+
## Function Declaration
|
|
6
|
+
|
|
7
|
+
Mark functions with `async` to indicate asynchronous work:
|
|
8
|
+
|
|
9
|
+
```swift
|
|
10
|
+
func fetchData() async -> Data {
|
|
11
|
+
// async work
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
func fetchData() async throws -> Data {
|
|
15
|
+
// async work that can fail
|
|
16
|
+
}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**Key benefit over closures**: The compiler enforces return values. No forgotten completion handlers.
|
|
20
|
+
|
|
21
|
+
> **Course Deep Dive**: This topic is covered in detail in [Lesson 2.1: Introduction to async/await syntax](https://www.swiftconcurrencycourse.com?utm_source=github&utm_medium=agent-skill&utm_campaign=lesson-reference)
|
|
22
|
+
|
|
23
|
+
## Calling Async Functions
|
|
24
|
+
|
|
25
|
+
### From synchronous context
|
|
26
|
+
|
|
27
|
+
Use `Task` to bridge from sync to async:
|
|
28
|
+
|
|
29
|
+
```swift
|
|
30
|
+
Task {
|
|
31
|
+
let data = try await fetchData()
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### From async context
|
|
36
|
+
|
|
37
|
+
Use `await` directly:
|
|
38
|
+
|
|
39
|
+
```swift
|
|
40
|
+
func processData() async throws {
|
|
41
|
+
let data = try await fetchData()
|
|
42
|
+
// process data
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Execution Order
|
|
47
|
+
|
|
48
|
+
Structured concurrency executes top-to-bottom in the order you expect:
|
|
49
|
+
|
|
50
|
+
```swift
|
|
51
|
+
let first = try await fetchData(1) // Waits for completion
|
|
52
|
+
let second = try await fetchData(2) // Starts after first completes
|
|
53
|
+
let third = try await fetchData(3) // Starts after second completes
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Code after `await` only executes once the awaited function returns.
|
|
57
|
+
|
|
58
|
+
> **Course Deep Dive**: This topic is covered in detail in [Lesson 2.2: Understanding the order of execution](https://www.swiftconcurrencycourse.com?utm_source=github&utm_medium=agent-skill&utm_campaign=lesson-reference)
|
|
59
|
+
|
|
60
|
+
## Parallel Execution with async let
|
|
61
|
+
|
|
62
|
+
Use `async let` to run multiple operations concurrently:
|
|
63
|
+
|
|
64
|
+
```swift
|
|
65
|
+
async let data1 = fetchData(1)
|
|
66
|
+
async let data2 = fetchData(2)
|
|
67
|
+
async let data3 = fetchData(3)
|
|
68
|
+
|
|
69
|
+
let results = try await [data1, data2, data3]
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### How async let works
|
|
73
|
+
|
|
74
|
+
- **Starts immediately**: The function executes right away, even before `await`
|
|
75
|
+
- **Structured concurrency**: Automatically canceled when leaving scope
|
|
76
|
+
- **Error handling**: If one fails, others are implicitly canceled when awaiting grouped results
|
|
77
|
+
- **No redundant keywords**: Don't use `try await` in the `async let` line itself
|
|
78
|
+
|
|
79
|
+
```swift
|
|
80
|
+
// Redundant - avoid this
|
|
81
|
+
async let data = try await fetchData()
|
|
82
|
+
|
|
83
|
+
// Correct - errors handled at await point
|
|
84
|
+
async let data = fetchData()
|
|
85
|
+
let result = try await data
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### When to use async let
|
|
89
|
+
|
|
90
|
+
**Use when:**
|
|
91
|
+
- Tasks don't depend on each other
|
|
92
|
+
- Number of tasks known at compile-time
|
|
93
|
+
- Want automatic cancellation on scope exit
|
|
94
|
+
|
|
95
|
+
**Avoid when:**
|
|
96
|
+
- Tasks must run sequentially
|
|
97
|
+
- Need dynamic task spawning (use `TaskGroup`)
|
|
98
|
+
- Need manual cancellation control
|
|
99
|
+
|
|
100
|
+
### Limitations
|
|
101
|
+
|
|
102
|
+
- Cannot use at top-level declarations (only within function bodies)
|
|
103
|
+
- Tasks not explicitly awaited may be canceled implicitly
|
|
104
|
+
|
|
105
|
+
> **Course Deep Dive**: This topic is covered in detail in [Lesson 2.3: Calling async functions in parallel using async let](https://www.swiftconcurrencycourse.com?utm_source=github&utm_medium=agent-skill&utm_campaign=lesson-reference)
|
|
106
|
+
|
|
107
|
+
## URLSession with Async/Await
|
|
108
|
+
|
|
109
|
+
URLSession provides async alternatives to closure-based APIs:
|
|
110
|
+
|
|
111
|
+
```swift
|
|
112
|
+
// Closure-based (old)
|
|
113
|
+
URLSession.shared.dataTask(with: request) { data, response, error in
|
|
114
|
+
guard let data = data, error == nil else { return }
|
|
115
|
+
// handle response
|
|
116
|
+
}.resume()
|
|
117
|
+
|
|
118
|
+
// Async/await (modern)
|
|
119
|
+
let (data, response) = try await URLSession.shared.data(for: request)
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Benefits over closures
|
|
123
|
+
|
|
124
|
+
- No optional `data` or `response` to unwrap
|
|
125
|
+
- Automatic error throwing
|
|
126
|
+
- Compiler enforces return values
|
|
127
|
+
- Simpler error handling with do-catch
|
|
128
|
+
|
|
129
|
+
### Complete network request pattern
|
|
130
|
+
|
|
131
|
+
```swift
|
|
132
|
+
func fetchUser(id: Int) async throws -> User {
|
|
133
|
+
let url = URL(string: "https://api.example.com/users/\(id)")!
|
|
134
|
+
var request = URLRequest(url: url)
|
|
135
|
+
request.httpMethod = "GET"
|
|
136
|
+
|
|
137
|
+
let (data, response) = try await URLSession.shared.data(for: request)
|
|
138
|
+
|
|
139
|
+
guard let httpResponse = response as? HTTPURLResponse,
|
|
140
|
+
(200...299).contains(httpResponse.statusCode) else {
|
|
141
|
+
throw NetworkError.invalidResponse
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return try JSONDecoder().decode(User.self, from: data)
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### POST requests with JSON
|
|
149
|
+
|
|
150
|
+
```swift
|
|
151
|
+
func createUser(_ user: User) async throws -> User {
|
|
152
|
+
let url = URL(string: "https://api.example.com/users")!
|
|
153
|
+
var request = URLRequest(url: url)
|
|
154
|
+
request.httpMethod = "POST"
|
|
155
|
+
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
|
|
156
|
+
request.httpBody = try JSONEncoder().encode(user)
|
|
157
|
+
|
|
158
|
+
let (data, response) = try await URLSession.shared.data(for: request)
|
|
159
|
+
|
|
160
|
+
guard let httpResponse = response as? HTTPURLResponse,
|
|
161
|
+
(200...299).contains(httpResponse.statusCode) else {
|
|
162
|
+
throw NetworkError.invalidResponse
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return try JSONDecoder().decode(User.self, from: data)
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
> **Course Deep Dive**: This topic is covered in detail in [Lesson 2.4: Performing network requests using URLSession and async/await](https://www.swiftconcurrencycourse.com?utm_source=github&utm_medium=agent-skill&utm_campaign=lesson-reference)
|
|
170
|
+
|
|
171
|
+
## Typed Errors (Swift 6)
|
|
172
|
+
|
|
173
|
+
Specify exact error types for better API contracts:
|
|
174
|
+
|
|
175
|
+
```swift
|
|
176
|
+
enum NetworkError: Error {
|
|
177
|
+
case invalidResponse
|
|
178
|
+
case decodingFailed(DecodingError)
|
|
179
|
+
case requestFailed(URLError)
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
func fetchData() async throws(NetworkError) -> Data {
|
|
183
|
+
do {
|
|
184
|
+
let (data, _) = try await URLSession.shared.data(from: url)
|
|
185
|
+
return data
|
|
186
|
+
} catch let error as URLError {
|
|
187
|
+
throw .requestFailed(error)
|
|
188
|
+
} catch {
|
|
189
|
+
throw .invalidResponse
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Callers know exactly which errors to handle.
|
|
195
|
+
|
|
196
|
+
## Migration Strategy
|
|
197
|
+
|
|
198
|
+
When converting closure-based code:
|
|
199
|
+
|
|
200
|
+
1. **Add new async method alongside old one** - keeps code compiling
|
|
201
|
+
2. **Update method signature** - add `async`, remove completion parameter
|
|
202
|
+
3. **Replace closure calls with await** - use URLSession async APIs
|
|
203
|
+
4. **Remove optional unwrapping** - async APIs return non-optional values
|
|
204
|
+
5. **Simplify error handling** - use do-catch instead of nested closures
|
|
205
|
+
6. **Return directly** - compiler enforces return values
|
|
206
|
+
|
|
207
|
+
## Common Patterns
|
|
208
|
+
|
|
209
|
+
### Sequential execution (when order matters)
|
|
210
|
+
|
|
211
|
+
```swift
|
|
212
|
+
let user = try await fetchUser(id: 1)
|
|
213
|
+
let posts = try await fetchPosts(userId: user.id)
|
|
214
|
+
let comments = try await fetchComments(postIds: posts.map(\.id))
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Parallel execution (when independent)
|
|
218
|
+
|
|
219
|
+
```swift
|
|
220
|
+
async let user = fetchUser(id: 1)
|
|
221
|
+
async let settings = fetchSettings()
|
|
222
|
+
async let notifications = fetchNotifications()
|
|
223
|
+
|
|
224
|
+
let (userData, settingsData, notificationsData) = try await (user, settings, notifications)
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Mixed execution
|
|
228
|
+
|
|
229
|
+
```swift
|
|
230
|
+
// Fetch user first (required for next step)
|
|
231
|
+
let user = try await fetchUser(id: 1)
|
|
232
|
+
|
|
233
|
+
// Then fetch related data in parallel
|
|
234
|
+
async let posts = fetchPosts(userId: user.id)
|
|
235
|
+
async let followers = fetchFollowers(userId: user.id)
|
|
236
|
+
async let following = fetchFollowing(userId: user.id)
|
|
237
|
+
|
|
238
|
+
let profile = Profile(
|
|
239
|
+
user: user,
|
|
240
|
+
posts: try await posts,
|
|
241
|
+
followers: try await followers,
|
|
242
|
+
following: try await following
|
|
243
|
+
)
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
## Further Learning
|
|
247
|
+
|
|
248
|
+
For in-depth coverage of async/await patterns, error handling strategies, and real-world migration scenarios, see [Swift Concurrency Course](https://www.swiftconcurrencycourse.com).
|
|
249
|
+
|