Data flow
Help your agent trace how data moves between views and resolve issues in how it is shared, so each view receives the data it needs.
SwiftFairy Scroll
Correct subtle bugs and performance issues in data flow, state ownership, and view updates by using SwiftUI as it was designed to be used.
Help your agent trace how data moves between views and resolve issues in how it is shared, so each view receives the data it needs.
Give your agent guidance on where state belongs and which view owns it, helping it manage that state throughout the view's lifecycle.
Identify changes in view identity that can unexpectedly discard state, with guidance and code examples to help your agent preserve it.
Find dependencies that trigger unnecessary view updates and repeated work, helping your agent improve performance by using SwiftUI as it was designed to be used.
Proper SwiftUI flags over 100 issues in your code. Each finding arrives at the line where the issue occurs, with the guidance and code example written for that case.
Your agent skips millions of tokens of reasoning and reads guidance only for the issues flagged.
Follows your view hierarchy across files and presentations, beyond single views and functions.
Built on our books and articles, and Natalia's work on Apple's SwiftUI team.
These examples show the patterns SwiftFairy flags and the guidance your agent can use to address them. Highlighted lines mark the code to review; each finding indicates whether the guidance is a requirement, recommendation, or consideration.
Must not
When we use a helper function or a computed property to return some View, we are simply moving a piece of the parent's body logic to a different location in the same component. This does not give the extracted code independent dependency tracking. When the parent reevaluates its body, the helper's logic runs again, even if the data it uses hasn't changed.
struct AnimalDetailView: View {
let animal: Animal
var body: some View {
habitatSection
}
@ViewBuilder
private var habitatSection: some View {
AnimalInfoSection(
header: "Habitat",
info: animal.habitatName
)
}
}
// In AnimalDetailView.body:
AnimalHabitatSection(
habitatName: animal.habitatName
)
struct AnimalHabitatSection: View {
let habitatName: String
var body: some View {
AnimalInfoSection(
header: "Habitat",
info: habitatName
)
}
}
Extract the section into a separate view struct, passing it only the information it needs to display its contents. When the parent updates, a new instance of AnimalHabitatSection is created. If its habitat name hasn't changed, SwiftUI can skip the execution of its body.
Should not
When a ForEach inside a list produces a variable number of rows per element, SwiftUI must evaluate its content for each item in the list to determine which rows exist. Filtering the collection beforehand allows rows to be created lazily.
ForEach(walks) { walk in
if walk.isShort {
Text(walk.name)
}
}
ForEach(shortWalks) { walk in
Text(walk.name)
}
Prepare shortWalks when the source data or filter changes. ForEach then receives a collection with known membership and produces exactly one row per element.
…and over 100 other issues.
Ask your agent to review a code change or a complete codebase with SwiftFairy. Your agent uses the findings and their accompanying code examples to resolve issues in your code.
How to use SwiftFairyActivate your free trial within the app at any time.
Choose lifetime access, a fixed term, or a subscription for this Scroll, or get all four together in a bundle.
Build interfaces that adapt to any window size, device, and text size by sizing views flexibly, structuring scrolling content correctly, and choosing the right SwiftUI layout API for each job.
Improve rendering and interaction performance by structuring charts and surrounding views to limit unnecessary updates and use Swift Charts APIs effectively.
Refine code for clarity, maintainability, and performance through idiomatic use of modern Swift APIs, including modern Swift concurrency and collection processing.