Generates structured SwiftUI Views and ViewModels using the MVVM pattern. It handles file scaffolding and standard navigation requirements for iOS 15+ apps.
Install
mkdir -p .claude/skills/view && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/10114" && unzip -o skill.zip -d .claude/skills/view && rm skill.zipInstalls to .claude/skills/view
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Cria uma nova View SwiftUI seguindo o padrao MVVM do projeto (iOS 15+). Use quando o usuario pedir para criar uma nova tela, view ou screen.Key capabilities
- →Create SwiftUI views
- →Scaffold ViewModels
- →Integrate repositories
- →Standardize UI components
- →Implement MVVM pattern
How it works
It generates a SwiftUI view and ViewModel pair following the MVVM pattern, including state management and repository injection.
Inputs & outputs
When to use view
- →Creating a new screen for an iOS application
- →Scaffolding a view with a dedicated ViewModel
- →Standardizing UI components within an MVVM codebase
About this skill
Crie uma nova View SwiftUI seguindo o padrao MVVM do projeto. Target minimo: iOS 15.
Argumentos
Nome da View em PascalCase: $ARGUMENTS
Se $ARGUMENTS estiver vazio, pergunte: "Qual o nome da View? (ex: ProductDetail, Profile)"
A partir do nome PascalCase, derive:
<Name>Viewpara o nome da struct da View<Name>ViewModelpara o nome da classe do ViewModel- Diretorio:
Views/<Name>/
Perguntas a fazer (se nao informadas nos argumentos)
- ViewModel dedicado: precisa de ViewModel? (padrao: sim)
- Repository: qual Repository sera injetado no ViewModel? (ex:
UserRepository) — se nao souber, use um placeholder - Navegacao: a View sera usada dentro de um
NavigationView? (padrao: sim). Se nao, omita o wrapperNavigationView,.navigationViewStyle(.stack)e o.navigationTitle.
O que criar
1. Views/<Name>/<Name>View.swift
Para suportar previews com estados diferentes, use o init com StateObject injetavel:
import SwiftUI
struct <Name>View: View {
@StateObject private var viewModel: <Name>ViewModel
init(viewModel: <Name>ViewModel = <Name>ViewModel()) {
_viewModel = StateObject(wrappedValue: viewModel)
}
var body: some View {
NavigationView {
Group {
switch viewModel.state {
case .idle:
EmptyView()
case .loading:
ProgressView("Carregando...")
case .success(let data):
content(data)
case .error(let message):
ErrorStateView(message: message) {
Task { await viewModel.load() }
}
}
}
.navigationTitle("<Name>")
}
.navigationViewStyle(.stack)
.task {
await viewModel.load()
}
}
// MARK: - Subviews
private func content(_ data: <DataType>) -> some View {
ScrollView {
VStack(spacing: 16) {
// TODO: Adicione o conteudo aqui
}
.padding()
}
}
}
// MARK: - Preview
#Preview {
<Name>View()
}
#Preview("Loading") {
<Name>View(viewModel: <Name>ViewModel(repository: Mock<Repository>(state: .loading)))
}
#Preview("Error") {
<Name>View(viewModel: <Name>ViewModel(repository: Mock<Repository>(state: .failure)))
}
2. ViewModels/<Name>ViewModel.swift (se solicitado)
Para padrões completos de ViewModel (busca, paginação, múltiplos estados), use a skill
view-model.
import Foundation
@MainActor
final class <Name>ViewModel: ObservableObject {
// MARK: - State
@Published private(set) var state: ViewState<<DataType>> = .idle
// MARK: - Dependencies
private let repository: <Repository>Protocol
// MARK: - Init
init(repository: <Repository>Protocol = <Repository>()) {
self.repository = repository
}
// MARK: - Actions
func load() async {
state = .loading
do {
let data = try await repository.fetch()
state = .success(data)
} catch {
state = .error(error.localizedDescription)
}
}
}
3. Views/<Name>/Components/ (diretorio)
Crie o diretorio para componentes futuros da View. Nao crie arquivos dentro dele, apenas informe o usuario que subcomponentes devem ser colocados aqui.
Apos criar os arquivos
Informe o usuario que ainda precisa:
- Verificar se
Utilities/ViewState.swiftexiste no projeto — se nao, crie-o - Verificar se
Views/Shared/ErrorStateView.swiftexiste no projeto — se nao, crie o arquivo com o codigo abaixo:
import SwiftUI
struct ErrorStateView: View {
let message: String
let retryAction: () -> Void
var body: some View {
VStack(spacing: 16) {
Image(systemName: "exclamationmark.triangle")
.font(.system(size: 48))
.foregroundColor(.secondary)
Text(message)
.font(.body)
.multilineTextAlignment(.center)
.foregroundColor(.secondary)
Button(action: retryAction) {
Text("Tentar novamente")
.fontWeight(.medium)
}
.buttonStyle(.bordered)
}
.padding()
}
}
- Criar o Repository correspondente em
Repositories/(se ainda nao existir), seguindo o padrao Protocol + implementacao concreta - Adicionar a rota no
AppRouterse estiver usando navegacao centralizada
Regras
View
- Structs que conformam com
View— nunca classes - Declarativas e enxutas — sem logica de negocio no body
- Extraia subviews privadas quando o body ultrapassar ~40 linhas
- Use
@Statepara estado local da View (toggle, campo de texto) - Use
@StateObjectpara criar o ViewModel,@ObservedObjectpara receber de fora - Prefira
.task {}para chamadas async ao aparecer a View - Use
switchsobre oViewStatepara reagir a cada estado - Use
NavigationView+.navigationViewStyle(.stack)— nuncaNavigationStack(requer iOS 16) - Use
NavigationLink(destination:)— nuncaNavigationLink(value:)(requer iOS 16) - Toda View deve ter um
#Previewfuncional
ViewModel
- Nunca importar SwiftUI — apenas
FoundationeCombine - Conforma com
ObservableObject— nunca@Observable(requer iOS 17) - Marcado como
@MainActor - Usa
ViewState<T>para gerenciar estado — nunca booleans avulsos - Propriedades de estado usam
@Published private(set) - Dependencias injetadas via
init(para testabilidade) - Metodos publicos representam acoes do usuario
Nomenclatura
| Tipo | Convencao | Exemplo |
|---|---|---|
| View | PascalCase + sufixo View | ProductDetailView |
| ViewModel | PascalCase + sufixo ViewModel | ProductDetailViewModel |
| Componente | PascalCase + sufixo View | ProductCardView |
| Diretorio | PascalCase (nome da feature) | Views/ProductDetail/ |
APIs proibidas (acima do iOS 15)
| NAO usar | Requer | Usar no lugar |
|---|---|---|
@Observable | iOS 17 | ObservableObject + @Published |
@State com class | iOS 17 | @StateObject |
@Bindable | iOS 17 | @ObservedObject |
NavigationStack | iOS 16 | NavigationView + .navigationViewStyle(.stack) |
NavigationLink(value:) | iOS 16 | NavigationLink(destination:) |
navigationDestination(for:) | iOS 16 | Remover |
ContentUnavailableView | iOS 17 | ErrorStateView customizada |
.environment() com Observable | iOS 17 | @EnvironmentObject |
Geral
- Nenhum import SwiftUI fora de Views
async/awaitpara concorrencia — prefira sobre Combine para novas features- Dependency Inversion — ViewModels dependem de protocolos, nao de implementacoes concretas
- Unidirectional Data Flow — View observa ViewModel, ViewModel atualiza estado, View re-renderiza
Checklist de Revisao
- Struct conforma com
View(nuncaclass) - Sem logica de negocio no
body -
@StateObjectcom init injetavel para suportar previews - Subviews extraidas quando body > 40 linhas
-
switchexaustivo sobreViewState(todos os 4 casos tratados) -
.task {}usado para carregamento async (naoonAppear) -
NavigationView+.navigationViewStyle(.stack)(nuncaNavigationStack) -
NavigationLink(destination:)(nuncaNavigationLink(value:)) -
ErrorStateViewpresente emViews/Shared/ -
ViewState.swiftpresente emUtilities/ -
#Previewfuncional com pelo menos estado de sucesso - Diretorio
Components/criado para subcomponentes futuros
When not to use it
- →Non-SwiftUI projects
Prerequisites
Limitations
- →Requires iOS 15+
How it compares
It enforces a strict MVVM architecture for iOS development, ensuring consistency and testability.
Compared to similar skills
view side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| view (this skill) | 0 | 4mo | No flags | Intermediate |
| swiftui-expert-skill | 13 | 4mo | No flags | Intermediate |
| swiftui-ui-patterns | 1 | 5mo | No flags | Intermediate |
| ios-navigation | 2 | 3mo | No flags | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by andrelucassvt
View all by andrelucassvt →You might also like
swiftui-expert-skill
sickn33
Write, review, or improve SwiftUI code following best practices for state management, view composition, performance, modern APIs, Swift concurrency, and iOS 26+ Liquid Glass adoption. Use when building new SwiftUI features, refactoring existing views, reviewing code quality, or adopting modern SwiftUI patterns.
swiftui-ui-patterns
Dimillian
Best practices and example-driven guidance for building SwiftUI views and components. Use when creating or refactoring SwiftUI UI, designing tab architecture with TabView, composing screens, or needing component-specific patterns and examples.
ios-navigation
HoangNguyen0403
SwiftUI navigation and deep linking using NavigationStack and Universal Links.
macos-menubar-tuist-app
HCMUTE-RTIC
Build, refactor, or review macOS menubar apps that use Tuist and SwiftUI. Use when creating or maintaining LSUIElement menubar utilities, defining Tuist targets/manifests, implementing model-client-store-view architecture, adding script-based launch flows, or validating reliable local build/run beha
swiftui-whats-new-27
CamilleScholtz
New SwiftUI APIs, behaviors, and deprecations introduced in the 2027 OS releases (iOS 27, macOS 27, watchOS 27, tvOS 27, visionOS 27). Use when a SwiftUI view using @State fails to compile with \"used before being initialized\", \"invalid redeclaration of synthesized property\", or \"extraneous argu
swift
bouclem
Expert in Swift and SwiftUI development for iOS, macOS, and Apple platforms