swift-code-reviewer-skill 1.2.0 → 1.3.0

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.
Files changed (95) hide show
  1. package/CHANGELOG.md +43 -169
  2. package/README.md +43 -2
  3. package/SKILL.md +194 -711
  4. package/bin/install.js +1 -1
  5. package/package.json +2 -1
  6. package/references/agent-loop-feedback.md +148 -0
  7. package/references/companion-skills.md +70 -0
  8. package/references/spec-adherence.md +157 -0
  9. package/skills/README.md +43 -0
  10. package/skills/swift-concurrency/NOTICE.md +18 -0
  11. package/skills/swift-concurrency/SKILL.md +235 -0
  12. package/skills/swift-concurrency/references/actors.md +640 -0
  13. package/skills/swift-concurrency/references/async-await-basics.md +249 -0
  14. package/skills/swift-concurrency/references/async-sequences.md +635 -0
  15. package/skills/swift-concurrency/references/core-data.md +533 -0
  16. package/skills/swift-concurrency/references/glossary.md +96 -0
  17. package/skills/swift-concurrency/references/linting.md +38 -0
  18. package/skills/swift-concurrency/references/memory-management.md +542 -0
  19. package/skills/swift-concurrency/references/migration.md +721 -0
  20. package/skills/swift-concurrency/references/performance.md +574 -0
  21. package/skills/swift-concurrency/references/sendable.md +578 -0
  22. package/skills/swift-concurrency/references/tasks.md +604 -0
  23. package/skills/swift-concurrency/references/testing.md +565 -0
  24. package/skills/swift-concurrency/references/threading.md +452 -0
  25. package/skills/swift-expert/NOTICE.md +18 -0
  26. package/skills/swift-expert/SKILL.md +226 -0
  27. package/skills/swift-expert/references/async-concurrency.md +363 -0
  28. package/skills/swift-expert/references/memory-performance.md +380 -0
  29. package/skills/swift-expert/references/protocol-oriented.md +357 -0
  30. package/skills/swift-expert/references/swiftui-patterns.md +294 -0
  31. package/skills/swift-expert/references/testing-patterns.md +402 -0
  32. package/skills/swift-testing/NOTICE.md +18 -0
  33. package/skills/swift-testing/SKILL.md +295 -0
  34. package/skills/swift-testing/references/async-testing.md +245 -0
  35. package/skills/swift-testing/references/dump-snapshot-testing.md +265 -0
  36. package/skills/swift-testing/references/fixtures.md +193 -0
  37. package/skills/swift-testing/references/integration-testing.md +189 -0
  38. package/skills/swift-testing/references/migration-xctest.md +301 -0
  39. package/skills/swift-testing/references/parameterized-tests.md +171 -0
  40. package/skills/swift-testing/references/snapshot-testing.md +201 -0
  41. package/skills/swift-testing/references/test-doubles.md +243 -0
  42. package/skills/swift-testing/references/test-organization.md +231 -0
  43. package/skills/swiftui-expert-skill/NOTICE.md +18 -0
  44. package/skills/swiftui-expert-skill/SKILL.md +281 -0
  45. package/skills/swiftui-expert-skill/references/accessibility-patterns.md +151 -0
  46. package/skills/swiftui-expert-skill/references/animation-advanced.md +403 -0
  47. package/skills/swiftui-expert-skill/references/animation-basics.md +284 -0
  48. package/skills/swiftui-expert-skill/references/animation-transitions.md +326 -0
  49. package/skills/swiftui-expert-skill/references/charts-accessibility.md +135 -0
  50. package/skills/swiftui-expert-skill/references/charts.md +602 -0
  51. package/skills/swiftui-expert-skill/references/image-optimization.md +203 -0
  52. package/skills/swiftui-expert-skill/references/latest-apis.md +464 -0
  53. package/skills/swiftui-expert-skill/references/layout-best-practices.md +266 -0
  54. package/skills/swiftui-expert-skill/references/liquid-glass.md +414 -0
  55. package/skills/swiftui-expert-skill/references/list-patterns.md +394 -0
  56. package/skills/swiftui-expert-skill/references/macos-scenes.md +318 -0
  57. package/skills/swiftui-expert-skill/references/macos-views.md +357 -0
  58. package/skills/swiftui-expert-skill/references/macos-window-styling.md +303 -0
  59. package/skills/swiftui-expert-skill/references/performance-patterns.md +403 -0
  60. package/skills/swiftui-expert-skill/references/scroll-patterns.md +293 -0
  61. package/skills/swiftui-expert-skill/references/sheet-navigation-patterns.md +363 -0
  62. package/skills/swiftui-expert-skill/references/state-management.md +417 -0
  63. package/skills/swiftui-expert-skill/references/view-structure.md +389 -0
  64. package/skills/swiftui-ui-patterns/NOTICE.md +18 -0
  65. package/skills/swiftui-ui-patterns/SKILL.md +95 -0
  66. package/skills/swiftui-ui-patterns/references/app-wiring.md +201 -0
  67. package/skills/swiftui-ui-patterns/references/async-state.md +96 -0
  68. package/skills/swiftui-ui-patterns/references/components-index.md +50 -0
  69. package/skills/swiftui-ui-patterns/references/controls.md +57 -0
  70. package/skills/swiftui-ui-patterns/references/deeplinks.md +66 -0
  71. package/skills/swiftui-ui-patterns/references/focus.md +90 -0
  72. package/skills/swiftui-ui-patterns/references/form.md +97 -0
  73. package/skills/swiftui-ui-patterns/references/grids.md +71 -0
  74. package/skills/swiftui-ui-patterns/references/haptics.md +71 -0
  75. package/skills/swiftui-ui-patterns/references/input-toolbar.md +51 -0
  76. package/skills/swiftui-ui-patterns/references/lightweight-clients.md +93 -0
  77. package/skills/swiftui-ui-patterns/references/list.md +86 -0
  78. package/skills/swiftui-ui-patterns/references/loading-placeholders.md +38 -0
  79. package/skills/swiftui-ui-patterns/references/macos-settings.md +71 -0
  80. package/skills/swiftui-ui-patterns/references/matched-transitions.md +59 -0
  81. package/skills/swiftui-ui-patterns/references/media.md +73 -0
  82. package/skills/swiftui-ui-patterns/references/menu-bar.md +101 -0
  83. package/skills/swiftui-ui-patterns/references/navigationstack.md +159 -0
  84. package/skills/swiftui-ui-patterns/references/overlay.md +45 -0
  85. package/skills/swiftui-ui-patterns/references/performance.md +62 -0
  86. package/skills/swiftui-ui-patterns/references/previews.md +48 -0
  87. package/skills/swiftui-ui-patterns/references/scroll-reveal.md +133 -0
  88. package/skills/swiftui-ui-patterns/references/scrollview.md +87 -0
  89. package/skills/swiftui-ui-patterns/references/searchable.md +71 -0
  90. package/skills/swiftui-ui-patterns/references/sheets.md +155 -0
  91. package/skills/swiftui-ui-patterns/references/split-views.md +72 -0
  92. package/skills/swiftui-ui-patterns/references/tabview.md +114 -0
  93. package/skills/swiftui-ui-patterns/references/theming.md +71 -0
  94. package/skills/swiftui-ui-patterns/references/title-menus.md +93 -0
  95. package/skills/swiftui-ui-patterns/references/top-bar.md +49 -0
@@ -0,0 +1,380 @@
1
+ # Memory & Performance
2
+
3
+ > Reference for: Swift Expert
4
+ > Load when: Memory management, ARC, performance optimization, profiling
5
+
6
+ ## Automatic Reference Counting (ARC)
7
+
8
+ ```swift
9
+ // Strong references (default)
10
+ class Person {
11
+ let name: String
12
+ var apartment: Apartment?
13
+
14
+ init(name: String) {
15
+ self.name = name
16
+ }
17
+
18
+ deinit {
19
+ print("\(name) is being deinitialized")
20
+ }
21
+ }
22
+
23
+ class Apartment {
24
+ let unit: String
25
+ weak var tenant: Person? // Weak to break retain cycle
26
+
27
+ init(unit: String) {
28
+ self.unit = unit
29
+ }
30
+
31
+ deinit {
32
+ print("Apartment \(unit) is being deinitialized")
33
+ }
34
+ }
35
+
36
+ var john: Person? = Person(name: "John")
37
+ var unit4A: Apartment? = Apartment(unit: "4A")
38
+
39
+ john?.apartment = unit4A
40
+ unit4A?.tenant = john
41
+
42
+ // Setting to nil will properly deallocate both
43
+ john = nil
44
+ unit4A = nil
45
+ ```
46
+
47
+ ## Weak and Unowned References
48
+
49
+ ```swift
50
+ // Weak - optional reference that doesn't keep object alive
51
+ class ViewController: UIViewController {
52
+ weak var delegate: ViewControllerDelegate?
53
+
54
+ func performAction() {
55
+ delegate?.didPerformAction()
56
+ }
57
+ }
58
+
59
+ // Unowned - non-optional reference, assumes target outlives owner
60
+ class Customer {
61
+ let name: String
62
+ var card: CreditCard?
63
+
64
+ init(name: String) {
65
+ self.name = name
66
+ }
67
+ }
68
+
69
+ class CreditCard {
70
+ let number: String
71
+ unowned let customer: Customer // Customer always outlives card
72
+
73
+ init(number: String, customer: Customer) {
74
+ self.number = number
75
+ self.customer = customer
76
+ }
77
+ }
78
+
79
+ // Unowned optional (Swift 5+)
80
+ class Department {
81
+ var courses: [Course] = []
82
+ }
83
+
84
+ class Course {
85
+ unowned var department: Department
86
+ unowned var nextCourse: Course?
87
+
88
+ init(department: Department) {
89
+ self.department = department
90
+ }
91
+ }
92
+ ```
93
+
94
+ ## Capture Lists in Closures
95
+
96
+ ```swift
97
+ class DataManager {
98
+ var data: [String] = []
99
+
100
+ func loadData() {
101
+ // Strong reference cycle - DataManager won't be deallocated
102
+ NetworkManager.fetch { response in
103
+ self.data = response // self is captured strongly
104
+ }
105
+
106
+ // Weak self - breaks cycle
107
+ NetworkManager.fetch { [weak self] response in
108
+ guard let self = self else { return }
109
+ self.data = response
110
+ }
111
+
112
+ // Unowned self - when self definitely outlives closure
113
+ NetworkManager.fetch { [unowned self] response in
114
+ self.data = response // Crashes if self is deallocated
115
+ }
116
+
117
+ // Capturing specific values
118
+ let identifier = UUID()
119
+ NetworkManager.fetch { [identifier] response in
120
+ print("Request \(identifier) completed")
121
+ }
122
+ }
123
+ }
124
+ ```
125
+
126
+ ## Value Semantics
127
+
128
+ ```swift
129
+ // Structs provide automatic copy-on-write for collections
130
+ struct User {
131
+ var name: String
132
+ var friends: [String] // Copy-on-write
133
+ }
134
+
135
+ var user1 = User(name: "Alice", friends: ["Bob"])
136
+ var user2 = user1 // Shallow copy
137
+ user2.friends.append("Charlie") // Now triggers deep copy
138
+
139
+ print(user1.friends) // ["Bob"]
140
+ print(user2.friends) // ["Bob", "Charlie"]
141
+
142
+ // Custom copy-on-write
143
+ final class Storage<T> {
144
+ var value: T
145
+ init(_ value: T) { self.value = value }
146
+ }
147
+
148
+ struct MyArray<Element> {
149
+ private var storage: Storage<[Element]>
150
+
151
+ init(_ elements: [Element] = []) {
152
+ storage = Storage(elements)
153
+ }
154
+
155
+ var value: [Element] {
156
+ get { storage.value }
157
+ set {
158
+ if !isKnownUniquelyReferenced(&storage) {
159
+ storage = Storage(newValue)
160
+ } else {
161
+ storage.value = newValue
162
+ }
163
+ }
164
+ }
165
+
166
+ mutating func append(_ element: Element) {
167
+ if !isKnownUniquelyReferenced(&storage) {
168
+ storage = Storage(storage.value)
169
+ }
170
+ storage.value.append(element)
171
+ }
172
+ }
173
+ ```
174
+
175
+ ## Performance Optimization
176
+
177
+ ```swift
178
+ // Use lazy properties for expensive computations
179
+ class Report {
180
+ let data: [DataPoint]
181
+
182
+ lazy var summary: String = {
183
+ // Expensive computation only when accessed
184
+ data.map { $0.description }.joined(separator: "\n")
185
+ }()
186
+
187
+ init(data: [DataPoint]) {
188
+ self.data = data
189
+ }
190
+ }
191
+
192
+ // Avoid repeated type casting
193
+ // Bad
194
+ for item in items {
195
+ if let user = item as? User {
196
+ processUser(user)
197
+ }
198
+ }
199
+
200
+ // Good
201
+ let users = items.compactMap { $0 as? User }
202
+ for user in users {
203
+ processUser(user)
204
+ }
205
+
206
+ // Use contiguous storage
207
+ // Slower - pointer indirection for each element
208
+ let arrayOfClasses: [MyClass] = [MyClass(), MyClass()]
209
+
210
+ // Faster - contiguous memory
211
+ let arrayOfStructs: [MyStruct] = [MyStruct(), MyStruct()]
212
+
213
+ // Avoid string concatenation in loops
214
+ // Bad
215
+ var result = ""
216
+ for item in items {
217
+ result += item.description // Allocates new string each time
218
+ }
219
+
220
+ // Good
221
+ let result = items.map { $0.description }.joined()
222
+
223
+ // Or
224
+ var result = ""
225
+ result.reserveCapacity(estimatedSize)
226
+ for item in items {
227
+ result.append(item.description)
228
+ }
229
+ ```
230
+
231
+ ## Collection Performance
232
+
233
+ ```swift
234
+ // Choose the right collection type
235
+ // Array - ordered, random access O(1), append O(1) amortized
236
+ let ordered: [Int] = [1, 2, 3]
237
+
238
+ // Set - unique elements, contains O(1), no order
239
+ let unique: Set<Int> = [1, 2, 3]
240
+
241
+ // Dictionary - key-value pairs, lookup O(1)
242
+ let mapping: [String: Int] = ["a": 1, "b": 2]
243
+
244
+ // Use ContiguousArray for performance-critical code
245
+ let contiguous = ContiguousArray<MyStruct>(repeating: MyStruct(), count: 1000)
246
+
247
+ // Reserve capacity for known sizes
248
+ var numbers: [Int] = []
249
+ numbers.reserveCapacity(1000)
250
+ for i in 0..<1000 {
251
+ numbers.append(i)
252
+ }
253
+
254
+ // Use enumerated() instead of indices
255
+ // Bad
256
+ for i in 0..<array.count {
257
+ process(index: i, value: array[i])
258
+ }
259
+
260
+ // Good
261
+ for (index, value) in array.enumerated() {
262
+ process(index: index, value: value)
263
+ }
264
+ ```
265
+
266
+ ## Memory Profiling with Instruments
267
+
268
+ ```swift
269
+ // Add markers for profiling
270
+ import os.signpost
271
+
272
+ let log = OSLog(subsystem: "com.example.app", category: "Performance")
273
+
274
+ func processData() {
275
+ os_signpost(.begin, log: log, name: "Data Processing")
276
+ defer { os_signpost(.end, log: log, name: "Data Processing") }
277
+
278
+ // Processing code
279
+ }
280
+
281
+ // Autoreleasepool for memory-intensive loops
282
+ func processLargeDataset() {
283
+ for batch in dataBatches {
284
+ autoreleasepool {
285
+ // Process batch
286
+ // Memory released at end of each iteration
287
+ }
288
+ }
289
+ }
290
+
291
+ // Check for memory leaks
292
+ #if DEBUG
293
+ extension NSObject {
294
+ static func trackAllocations() {
295
+ let count = performSelector(
296
+ Selector(("instancesRespond:"))
297
+ )
298
+ print("\(self): \(count) instances")
299
+ }
300
+ }
301
+ #endif
302
+ ```
303
+
304
+ ## Optimization Levels
305
+
306
+ ```swift
307
+ // Whole Module Optimization in Package.swift
308
+ let package = Package(
309
+ name: "MyApp",
310
+ products: [
311
+ .executable(name: "MyApp", targets: ["MyApp"])
312
+ ],
313
+ targets: [
314
+ .target(
315
+ name: "MyApp",
316
+ swiftSettings: [
317
+ .unsafeFlags(["-O"], .when(configuration: .release))
318
+ ]
319
+ )
320
+ ]
321
+ )
322
+
323
+ // Inline optimization
324
+ @inline(__always)
325
+ func criticalPath() {
326
+ // Always inlined
327
+ }
328
+
329
+ @inline(never)
330
+ func debugHelper() {
331
+ // Never inlined, good for debugging
332
+ }
333
+
334
+ // Optimization attributes
335
+ @_specialize(where T == Int)
336
+ @_specialize(where T == String)
337
+ func process<T>(_ value: T) {
338
+ // Specialized versions generated
339
+ }
340
+ ```
341
+
342
+ ## Memory Warnings
343
+
344
+ ```swift
345
+ class ImageCache {
346
+ private var cache: [String: UIImage] = [:]
347
+
348
+ init() {
349
+ NotificationCenter.default.addObserver(
350
+ self,
351
+ selector: #selector(clearCache),
352
+ name: UIApplication.didReceiveMemoryWarningNotification,
353
+ object: nil
354
+ )
355
+ }
356
+
357
+ @objc private func clearCache() {
358
+ cache.removeAll()
359
+ }
360
+
361
+ deinit {
362
+ NotificationCenter.default.removeObserver(self)
363
+ }
364
+ }
365
+ ```
366
+
367
+ ## Best Practices
368
+
369
+ - Use value types (structs) by default
370
+ - Use weak references for delegates
371
+ - Use unowned when lifetime is guaranteed
372
+ - Always use capture lists in closures that reference self
373
+ - Profile before optimizing (use Instruments)
374
+ - Reserve collection capacity when size is known
375
+ - Use lazy properties for expensive computations
376
+ - Implement copy-on-write for custom types with reference storage
377
+ - Handle memory warnings in iOS apps
378
+ - Use autoreleasepool for memory-intensive loops
379
+ - Choose appropriate collection types
380
+ - Avoid premature optimization - measure first
@@ -0,0 +1,357 @@
1
+ # Protocol-Oriented Programming
2
+
3
+ > Reference for: Swift Expert
4
+ > Load when: Protocol design, generics, associated types, type erasure
5
+
6
+ ## Protocol Basics
7
+
8
+ ```swift
9
+ // Protocol with requirements
10
+ protocol Drawable {
11
+ var boundingBox: CGRect { get }
12
+ func draw(in context: CGContext)
13
+ }
14
+
15
+ // Protocol with default implementation
16
+ extension Drawable {
17
+ func draw(in context: CGContext) {
18
+ // Default drawing behavior
19
+ context.stroke(boundingBox)
20
+ }
21
+ }
22
+
23
+ // Struct conforming to protocol
24
+ struct Circle: Drawable {
25
+ let center: CGPoint
26
+ let radius: CGFloat
27
+
28
+ var boundingBox: CGRect {
29
+ CGRect(
30
+ x: center.x - radius,
31
+ y: center.y - radius,
32
+ width: radius * 2,
33
+ height: radius * 2
34
+ )
35
+ }
36
+ }
37
+ ```
38
+
39
+ ## Associated Types
40
+
41
+ ```swift
42
+ // Protocol with associated type
43
+ protocol Container {
44
+ associatedtype Item
45
+ var count: Int { get }
46
+ mutating func append(_ item: Item)
47
+ subscript(index: Int) -> Item { get }
48
+ }
49
+
50
+ // Generic struct conforming
51
+ struct Stack<Element>: Container {
52
+ typealias Item = Element // Can be inferred
53
+ private var items: [Element] = []
54
+
55
+ var count: Int { items.count }
56
+
57
+ mutating func append(_ item: Element) {
58
+ items.append(item)
59
+ }
60
+
61
+ subscript(index: Int) -> Element {
62
+ items[index]
63
+ }
64
+ }
65
+
66
+ // Using where clause with associated types
67
+ extension Container where Item: Equatable {
68
+ func firstIndex(of item: Item) -> Int? {
69
+ for (index, current) in enumerated() where current == item {
70
+ return index
71
+ }
72
+ return nil
73
+ }
74
+ }
75
+ ```
76
+
77
+ ## Protocol Composition
78
+
79
+ ```swift
80
+ // Multiple protocol conformance
81
+ protocol Named {
82
+ var name: String { get }
83
+ }
84
+
85
+ protocol Aged {
86
+ var age: Int { get }
87
+ }
88
+
89
+ // Composing protocols
90
+ typealias Person = Named & Aged
91
+
92
+ func greet(_ person: some Named & Aged) {
93
+ print("Hello \(person.name), age \(person.age)")
94
+ }
95
+
96
+ // Protocol composition in constraints
97
+ func process<T: Codable & Hashable>(_ items: [T]) {
98
+ // T must conform to both Codable and Hashable
99
+ }
100
+ ```
101
+
102
+ ## Generics with Protocols
103
+
104
+ ```swift
105
+ // Generic function with protocol constraint
106
+ func compare<T: Comparable>(_ a: T, _ b: T) -> T {
107
+ return a > b ? a : b
108
+ }
109
+
110
+ // Generic type with protocol constraint
111
+ class Repository<Model: Codable & Identifiable> {
112
+ private var items: [Model.ID: Model] = [:]
113
+
114
+ func save(_ model: Model) {
115
+ items[model.id] = model
116
+ }
117
+
118
+ func find(id: Model.ID) -> Model? {
119
+ items[id]
120
+ }
121
+
122
+ func all() -> [Model] {
123
+ Array(items.values)
124
+ }
125
+ }
126
+
127
+ // Using opaque return types
128
+ func makeCollection() -> some Collection {
129
+ return [1, 2, 3, 4, 5]
130
+ }
131
+
132
+ // Primary associated types (Swift 5.7+)
133
+ protocol DataSource<Element> {
134
+ associatedtype Element
135
+ func fetch() async throws -> [Element]
136
+ }
137
+
138
+ func loadData<T>(from source: some DataSource<T>) async throws -> [T] {
139
+ try await source.fetch()
140
+ }
141
+ ```
142
+
143
+ ## Type Erasure
144
+
145
+ ```swift
146
+ // Problem: Can't use protocol with associated types as type
147
+ // protocol Storage {
148
+ // associatedtype Item
149
+ // func store(_ item: Item)
150
+ // }
151
+ // var storage: Storage // Error: protocol can only be used as constraint
152
+
153
+ // Solution: Type-erased wrapper
154
+ protocol Storage {
155
+ associatedtype Item
156
+ func store(_ item: Item)
157
+ func retrieve() -> Item?
158
+ }
159
+
160
+ struct AnyStorage<T>: Storage {
161
+ typealias Item = T
162
+
163
+ private let _store: (T) -> Void
164
+ private let _retrieve: () -> T?
165
+
166
+ init<S: Storage>(_ storage: S) where S.Item == T {
167
+ _store = storage.store
168
+ _retrieve = storage.retrieve
169
+ }
170
+
171
+ func store(_ item: T) {
172
+ _store(item)
173
+ }
174
+
175
+ func retrieve() -> T? {
176
+ _retrieve()
177
+ }
178
+ }
179
+
180
+ // Now we can use it as a type
181
+ class MemoryStorage<T>: Storage {
182
+ private var item: T?
183
+
184
+ func store(_ item: T) {
185
+ self.item = item
186
+ }
187
+
188
+ func retrieve() -> T? {
189
+ item
190
+ }
191
+ }
192
+
193
+ let storage: AnyStorage<String> = AnyStorage(MemoryStorage<String>())
194
+ ```
195
+
196
+ ## Protocol Inheritance
197
+
198
+ ```swift
199
+ // Protocol inheriting from another
200
+ protocol Identifiable {
201
+ var id: UUID { get }
202
+ }
203
+
204
+ protocol Timestampable {
205
+ var createdAt: Date { get }
206
+ var updatedAt: Date { get }
207
+ }
208
+
209
+ protocol Entity: Identifiable, Timestampable {
210
+ var version: Int { get }
211
+ }
212
+
213
+ struct User: Entity {
214
+ let id: UUID
215
+ let createdAt: Date
216
+ var updatedAt: Date
217
+ var version: Int
218
+ var name: String
219
+ }
220
+ ```
221
+
222
+ ## Conditional Conformance
223
+
224
+ ```swift
225
+ // Make Array conform to protocol when elements conform
226
+ protocol Summarizable {
227
+ var summary: String { get }
228
+ }
229
+
230
+ extension Array: Summarizable where Element: Summarizable {
231
+ var summary: String {
232
+ map { $0.summary }.joined(separator: ", ")
233
+ }
234
+ }
235
+
236
+ struct Task: Summarizable {
237
+ let title: String
238
+ var summary: String { title }
239
+ }
240
+
241
+ let tasks = [Task(title: "Buy milk"), Task(title: "Walk dog")]
242
+ print(tasks.summary) // "Buy milk, Walk dog"
243
+ ```
244
+
245
+ ## Protocol Extensions
246
+
247
+ ```swift
248
+ // Adding functionality to all conforming types
249
+ protocol Collection {
250
+ associatedtype Element
251
+ var count: Int { get }
252
+ subscript(index: Int) -> Element { get }
253
+ }
254
+
255
+ extension Collection {
256
+ var isEmpty: Bool {
257
+ count == 0
258
+ }
259
+
260
+ func map<T>(_ transform: (Element) -> T) -> [T] {
261
+ var result: [T] = []
262
+ for i in 0..<count {
263
+ result.append(transform(self[i]))
264
+ }
265
+ return result
266
+ }
267
+ }
268
+
269
+ // Constrained extensions
270
+ extension Collection where Element: Numeric {
271
+ func sum() -> Element {
272
+ var total: Element = 0
273
+ for i in 0..<count {
274
+ total += self[i]
275
+ }
276
+ return total
277
+ }
278
+ }
279
+ ```
280
+
281
+ ## Advanced Patterns
282
+
283
+ ```swift
284
+ // Phantom types for type safety
285
+ enum Celsius {}
286
+ enum Fahrenheit {}
287
+
288
+ struct Temperature<Unit> {
289
+ let value: Double
290
+
291
+ init(_ value: Double) {
292
+ self.value = value
293
+ }
294
+ }
295
+
296
+ extension Temperature where Unit == Celsius {
297
+ func toFahrenheit() -> Temperature<Fahrenheit> {
298
+ Temperature<Fahrenheit>(value * 9/5 + 32)
299
+ }
300
+ }
301
+
302
+ extension Temperature where Unit == Fahrenheit {
303
+ func toCelsius() -> Temperature<Celsius> {
304
+ Temperature<Celsius>((value - 32) * 5/9)
305
+ }
306
+ }
307
+
308
+ let celsius = Temperature<Celsius>(100)
309
+ let fahrenheit = celsius.toFahrenheit()
310
+
311
+ // Witness tables pattern
312
+ protocol Encoder {
313
+ func encode<T: Encodable>(_ value: T) throws -> Data
314
+ }
315
+
316
+ protocol Decoder {
317
+ func decode<T: Decodable>(_ type: T.Type, from data: Data) throws -> T
318
+ }
319
+
320
+ struct Codec<E: Encoder, D: Decoder> {
321
+ let encoder: E
322
+ let decoder: D
323
+
324
+ func roundtrip<T: Codable>(_ value: T) throws -> T {
325
+ let data = try encoder.encode(value)
326
+ return try decoder.decode(T.self, from: data)
327
+ }
328
+ }
329
+ ```
330
+
331
+ ## Retroactive Modeling
332
+
333
+ ```swift
334
+ // Adding protocol conformance to types you don't own
335
+ extension Int: Identifiable {
336
+ public var id: Int { self }
337
+ }
338
+
339
+ // Now Int can be used where Identifiable is required
340
+ let numbers: [Int] = [1, 2, 3]
341
+ ForEach(numbers) { number in
342
+ Text("\(number)")
343
+ }
344
+ ```
345
+
346
+ ## Best Practices
347
+
348
+ - Prefer protocols over base classes for abstraction
349
+ - Use protocol extensions for default implementations
350
+ - Design protocols with single responsibility
351
+ - Use associated types for generic protocols
352
+ - Apply type erasure when needed for storage
353
+ - Leverage conditional conformance
354
+ - Use opaque return types (some Protocol) for implementation hiding
355
+ - Compose small protocols rather than large ones
356
+ - Document protocol requirements and guarantees
357
+ - Consider protocol inheritance for layered abstraction