Use when building SwiftUI views, managing state with @State/@Binding/@ObservableObject, or implementing declarative UI patterns in iOS apps.
Provides SwiftUI state management patterns using @State/@Binding/@ObservableObject and declarative UI best practices for iOS apps. Use when building SwiftUI views or managing view state.
/plugin marketplace add TheBushidoCollective/han/plugin install jutsu-go@hanThis skill is limited to using the following tools:
Modern declarative UI development for iOS, macOS, watchOS, and tvOS applications.
SwiftUI provides a hierarchy of property wrappers for different state needs:
@Observable
class UserModel {
var name: String = ""
var email: String = ""
var isLoggedIn: Bool = false
}
struct ContentView: View {
@State private var user = UserModel()
var body: some View {
UserProfileView(user: user)
}
}
class UserViewModel: ObservableObject {
@Published var name: String = ""
@Published var isLoading: Bool = false
func fetchUser() async {
isLoading = true
defer { isLoading = false }
// fetch logic
}
}
struct UserView: View {
@StateObject private var viewModel = UserViewModel()
var body: some View {
// view implementation
}
}
Break complex views into smaller, focused components:
struct OrderSummaryView: View {
let order: Order
var body: some View {
VStack(spacing: 16) {
OrderHeaderView(order: order)
OrderItemsListView(items: order.items)
OrderTotalView(total: order.total)
}
}
}
Use structs for models when possible to leverage SwiftUI's efficient diffing:
struct Product: Identifiable, Equatable {
let id: UUID
var name: String
var price: Decimal
var quantity: Int
}
struct CardModifier: ViewModifier {
func body(content: Content) -> some View {
content
.padding()
.background(Color(.systemBackground))
.cornerRadius(12)
.shadow(radius: 4)
}
}
extension View {
func cardStyle() -> some View {
modifier(CardModifier())
}
}
struct UserDetailView: View {
let userId: String
@State private var user: User?
var body: some View {
Group {
if let user {
UserContent(user: user)
} else {
ProgressView()
}
}
.task {
user = await fetchUser(id: userId)
}
}
}
struct ContentView: View {
@State private var path = NavigationPath()
var body: some View {
NavigationStack(path: $path) {
ProductListView()
.navigationDestination(for: Product.self) { product in
ProductDetailView(product: product)
}
.navigationDestination(for: Category.self) { category in
CategoryView(category: category)
}
}
}
}
struct ItemView: View {
@State private var showingDetail = false
@State private var showingDeleteAlert = false
var body: some View {
Button("View Details") {
showingDetail = true
}
.sheet(isPresented: $showingDetail) {
DetailSheet()
}
.alert("Delete Item?", isPresented: $showingDeleteAlert) {
Button("Delete", role: .destructive) { deleteItem() }
Button("Cancel", role: .cancel) { }
}
}
}
@Model
class Task {
var title: String
var isCompleted: Bool
var createdAt: Date
init(title: String) {
self.title = title
self.isCompleted = false
self.createdAt = Date()
}
}
struct TaskListView: View {
@Query(sort: \Task.createdAt, order: .reverse)
private var tasks: [Task]
@Environment(\.modelContext) private var modelContext
var body: some View {
List(tasks) { task in
TaskRowView(task: task)
}
}
}
Bad:
struct BadView: View {
var body: some View {
VStack {
// 200+ lines of nested views
}
}
}
Good: Extract into focused subviews.
Bad:
struct BadView: View {
@ObservedObject var viewModel = ViewModel() // Re-created on every view init!
}
Good:
struct GoodView: View {
@StateObject private var viewModel = ViewModel()
}
Bad:
var body: some View {
let _ = print("View rendered") // Side effect!
Text("Hello")
}
Good: Use .task, .onAppear, or .onChange for side effects.
Bad:
Text(user!.name) // Crash risk
Good:
if let user {
Text(user.name)
}
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.