Add expert SwiftUI best practices guidance to your AI coding tool. Benefits developers by improving SwiftUI API usage, state management, and performance. Integrates with any AI coding tool supporting the Agent Skills open format.
git clone https://github.com/AvdLee/SwiftUI-Agent-Skill.githttps://skills.sh/avdlee/swiftui-agent-skill/swiftui-expert-skill
[{"step":"Paste your SwiftUI code snippet into your AI coding tool (e.g., Claude, Cursor, or GitHub Copilot).","tip":"Include the full view hierarchy and any relevant state management code. The more context you provide, the better the review."},{"step":"Use the prompt template to generate a SwiftUI expert review. Replace [CODE_SNITPET] with your actual code.","tip":"For large projects, focus on critical views first (e.g., those with performance issues or complex state logic)."},{"step":"Review the AI's suggestions and apply the recommended changes to your code.","tip":"Compare the original and refactored code side-by-side to understand the improvements. Test the changes in a simulator or device."},{"step":"Iterate by running the AI review again after making changes to catch any remaining issues.","tip":"Use version control (e.g., Git) to track changes and revert if needed. Focus on one improvement area at a time (e.g., state management first, then performance)."},{"step":"Integrate the refactored code into your project and monitor for runtime issues or regressions.","tip":"Use Xcode's Instruments tool to profile performance if the AI flags potential bottlenecks. Check for memory leaks or excessive view updates."}]
Review existing SwiftUI code for state management and modern API improvements.
Refactor SwiftUI views to enhance performance and maintainability.
Implement best practices for lists, sheets, and navigation in SwiftUI applications.
Optimize image handling and layout patterns for better performance.
No install command available. Check the GitHub repository for manual installation instructions.
git clone https://github.com/AvdLee/SwiftUI-Agent-SkillCopy the install command above and run it in your terminal.
Launch Claude Code, Cursor, or your preferred AI coding agent.
Use the prompt template or examples below to test the skill.
Adapt the skill to your specific use case and workflow.
Act as a SwiftUI expert. Review the following SwiftUI code snippet: [CODE_SNITPET]. Identify any anti-patterns, performance bottlenecks, or best practice violations. Suggest concrete improvements with code examples. Focus on: state management (e.g., @State vs @Binding vs @ObservedObject), view lifecycle (e.g., .onAppear vs .task), and performance optimizations (e.g., avoiding unnecessary view updates). Prioritize changes that align with modern SwiftUI conventions (iOS 15+).
```swift
// Original Code Snippet (Flawed)
struct UserProfileView: View {
@State private var user: User
@State private var isLoading = false
var body: some View {
VStack {
if isLoading {
ProgressView()
}
Text(user.name)
Text(user.bio)
Button("Save") {
Task {
isLoading = true
await saveUser()
isLoading = false
}
}
}
}
private func saveUser() async {
// Network call
}
}
// Expert Review:
1. **State Management Issues**:
- `user` should be `@StateObject` or `@ObservedObject` if owned externally, not `@State`. `@State` is for value types owned by the view. For reference types (e.g., `User` as a class), use `@StateObject` or `@ObservedObject` to ensure proper observation.
- `isLoading` is correctly marked as `@State` (value type), but its usage is problematic. The `Task` closure captures `isLoading` weakly, which can lead to race conditions. Use `withAnimation` or `DispatchQueue.main.async` for state updates.
2. **Performance Bottleneck**:
- The entire view re-renders when `isLoading` changes, even though only the `ProgressView` needs to update. Use `if` with a computed property or a separate `LoadingView` to isolate updates:
```swift
var body: some View {
VStack {
if isLoading { ProgressView() }
else {
Text(user.name)
Text(user.bio)
Button("Save") { ... }
}
}
}
```
3. **Modern SwiftUI Conventions**:
- Replace `Task` with `.task(priority:)` modifier for async work tied to the view's lifecycle. This ensures cancellation when the view disappears:
```swift
.task {
isLoading = true
await saveUser()
isLoading = false
}
```
- Consider using `ObservableObject` for `User` to leverage `@Published` properties and Combine integration for reactive updates.
4. **Suggested Refactor**:
```swift
class UserViewModel: ObservableObject {
@Published var user: User
@Published var isLoading = false
func saveUser() async { ... }
}
struct UserProfileView: View {
@StateObject private var viewModel = UserViewModel()
var body: some View {
VStack {
if viewModel.isLoading {
ProgressView()
} else {
Text(viewModel.user.name)
Text(viewModel.user.bio)
Button("Save") {
Task { await viewModel.saveUser() }
}
}
}
.task { await viewModel.loadUser() }
}
}
```
Key Takeaway: Always prefer `@StateObject`/`@ObservedObject` for reference types, isolate state changes to minimize view updates, and use modern SwiftUI modifiers for async work.We create engaging workshops for companies and private events centred around plants, flowers and all things botanical.
IronCalc is a spreadsheet engine and ecosystem
ITIL-aligned IT service management platform
Customer feedback management made simple
Enterprise workflow automation and service management platform
Automate your spreadsheet tasks with AI power
Take a free 3-minute scan and get personalized AI skill recommendations.
Take free scan