Summary
Detect .onChange(of:) modifiers using the two-parameter closure when only the new value is used.
Problem
// Bad - oldValue is unused
.onChange(of: someValue) { oldValue, newValue in
handleChange(newValue)
}
// Also bad - underscore shows intent but still uses wrong API
.onChange(of: someValue) { _, newValue in
handleChange(newValue)
}
Preferred
// Good - single parameter closure
.onChange(of: someValue) { newValue in
handleChange(newValue)
}
// Good - direct method reference
.onChange(of: someValue, perform: handleChange)
Detection Logic
- Find
.onChange(of:_:) calls (the two-param version)
- Check if first closure parameter is:
- Unused (no references in body)
- Named
_ (explicit discard)
- If either, trigger warning
Origin
Discovered via vector DB analysis of AGENT directives in edit logs:
- "must not use the two parameter onchange when you're only using the new data"
- "I meant .onChange(of: ..., perform: ...)"
Implementation Notes
- SwiftSyntax rule in CustomRules package
- Could offer auto-fix to single-param version
- Related to closure indirection pattern (separate rule candidate)
Summary
Detect
.onChange(of:)modifiers using the two-parameter closure when only the new value is used.Problem
Preferred
Detection Logic
.onChange(of:_:)calls (the two-param version)_(explicit discard)Origin
Discovered via vector DB analysis of AGENT directives in edit logs:
Implementation Notes