A wrapper for implementing macOS-exclusive SwiftUI features and native behaviors.
Install
mkdir -p .claude/skills/macos && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/13420" && unzip -o skill.zip -d .claude/skills/macos && rm skill.zipInstalls to .claude/skills/macos
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.
Implementa funcionalidades específicas de macOS em apps SwiftUI — Scenes (Settings, MenuBarExtra, WindowGroup, Window, UtilityWindow, DocumentGroup), estilos de janela e toolbar, NavigationSplitView, Inspector, Commands, HSplitView, Table, operações de arquivo, drag-drop entre apps, e interop AppKit. Use quando o usuário precisar de qualquer API exclusiva ou com comportamento diferenciado no macOS.Key capabilities
- →Implement macOS-specific SwiftUI scenes (Settings, MenuBarExtra, WindowGroup, Window, UtilityWindow, DocumentGroup)
- →Configure window styles, sizing, and Inspectors
- →Integrate NavigationSplitView and Commands/keyboard shortcuts
- →Utilize HSplitView/VSplitView and Table views
- →Perform file operations and drag-drop between apps
- →Enable AppKit interop using NSViewRepresentable/NSViewControllerRepresentable
How it works
The skill provides expertise and code examples for implementing macOS-specific SwiftUI APIs, ensuring they are guarded with `#if os(macOS)` in multi-platform projects.
Inputs & outputs
When to use macos
- →Implementing macOS toolbar styles
- →Creating native macOS windows
- →Integrating drag-and-drop on Mac
- →Adding app menu items
About this skill
Skill: macOS
Você é um especialista em APIs SwiftUI específicas do macOS.
Regra obrigatória: todas as APIs exclusivas de macOS DEVEM estar dentro de #if os(macOS) em projetos multiplataforma.
Identificação do Modo
Se $ARGUMENTS não especificar o modo, pergunte:
"Qual aspecto macOS você quer implementar?
- scenes — configurar cenas do app (Settings, MenuBarExtra, Window…)
- window — estilos de toolbar/janela, Inspector, NavigationSplitView, Commands
- views — HSplitView, Table, arquivos, drag-drop, NSViewRepresentable"
Modo: scenes
Antes de criar
- Leia o
@mainApp atual para entender as cenas existentes. - Identifique qual cena adicionar ou ajustar.
- Wrap sempre em
#if os(macOS)quando o projeto é multiplataforma.
Referência de Cenas
| Cena | Disponibilidade | macOS-only? | Uso |
|---|---|---|---|
WindowGroup | macOS 11.0+ | Não | Múltiplas janelas, tabs, Window menu automático |
Window | macOS 13.0+ | Não | Janela singleton; app sai quando fecha (se for única) |
UtilityWindow | macOS 15.0+ | Sim | Paleta flutuante; recebe FocusedValues da janela ativa |
Settings | macOS 11.0+ | Sim | Janela de preferências (Cmd+,) |
MenuBarExtra | macOS 13.0+ | Sim | Ícone/menu persistente na barra de menus |
DocumentGroup | macOS 11.0+ | Não | Menus File automáticos; múltiplos documentos |
Settings
#if os(macOS)
Settings {
TabView {
Tab("General", systemImage: "gear") { GeneralSettingsView() }
Tab("Advanced", systemImage: "star") { AdvancedSettingsView() }
}
.scenePadding()
.frame(maxWidth: 350, minHeight: 100)
}
#endif
Abrir programaticamente (macOS 14.0+):
struct OpenSettingsButton: View {
@Environment(\.openSettings) private var openSettings
var body: some View {
Button("Preferências") { openSettings() }
}
}
SettingsLink (macOS 14.0+):
SettingsLink {
Label("Preferências", systemImage: "gear")
}
MenuBarExtra
Estilo menu (dropdown):
#if os(macOS)
MenuBarExtra("MyApp", systemImage: "hammer") {
Button("Ação") { /* ... */ }
Divider()
Button("Sair") { NSApplication.shared.terminate(nil) }
}
#endif
Estilo window (painel popover):
#if os(macOS)
MenuBarExtra("Status", systemImage: "chart.bar") {
DashboardView()
.frame(width: 240)
}
.menuBarExtraStyle(.window)
#endif
App somente na barra de menus:
- Use
MenuBarExtracomo única cena - Adicione
LSUIElement = YESno Info.plist para ocultar o ícone no Dock - O app se encerra automaticamente se o usuário remover o ícone da barra
Visibilidade controlável:
@AppStorage("showMenuBarExtra") private var showMenuBarExtra = true
MenuBarExtra("Status", systemImage: "bolt", isInserted: $showMenuBarExtra) { ... }
WindowGroup (macOS)
@main
struct MyApp: App {
var body: some Scene {
// Janela principal (suporta múltiplas instâncias + tabs)
WindowGroup {
ContentView()
}
// Janela de dados tipados — aberta programaticamente
WindowGroup("Detalhe", for: Item.ID.self) { $itemID in
ItemDetailView(itemID: itemID)
}
}
}
// Abrir programaticamente
struct OpenButton: View {
var item: Item
@Environment(\.openWindow) private var openWindow
var body: some View {
Button("Abrir Detalhe") {
openWindow(value: item.id)
}
}
}
Window (singleton)
@main
struct MyApp: App {
var body: some Scene {
WindowGroup { ContentView() }
// Janela singleton suplementar
Window("Connection Doctor", id: "connection-doctor") {
ConnectionDoctorView()
}
}
}
// Abrir — traz ao frente se já aberta
struct OpenDoctorButton: View {
@Environment(\.openWindow) private var openWindow
var body: some View {
Button("Connection Doctor") {
openWindow(id: "connection-doctor")
}
}
}
Prefira
WindowGrouppara a cena principal. UseWindowapenas para janelas suplementares singleton.
UtilityWindow (macOS 15.0+)
Paleta flutuante que recebe FocusedValues da janela principal ativa.
#if os(macOS)
UtilityWindow("Informações", id: "photo-info") {
PhotoInfoViewer()
}
#endif
// Dentro da UtilityWindow — reflete seleção da janela ativa
struct PhotoInfoViewer: View {
@FocusedValue(PhotoSelection.self) private var selectedPhotos
var body: some View {
if let photos = selectedPhotos {
Text("\(photos.count) fotos selecionadas")
} else {
Text("Sem seleção").foregroundStyle(.secondary)
}
}
}
DocumentGroup
DocumentGroup(newDocument: MyDocument()) { config in
ContentView(document: config.$document)
}
struct MyDocument: FileDocument {
static var readableContentTypes: [UTType] { [.plainText] }
var text: String = ""
init() {}
init(configuration: ReadConfiguration) throws {
text = String(data: configuration.file.regularFileContents ?? Data(),
encoding: .utf8) ?? ""
}
func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {
FileWrapper(regularFileWithContents: Data(text.utf8))
}
}
Modo: window
Toolbar Styles (macOS-only)
Aplique no nível da Scene:
WindowGroup { ContentView() }
.windowToolbarStyle(.unified) // Título + toolbar em uma linha (recomendado)
.windowToolbarStyle(.unifiedCompact) // Idem, menor altura vertical
.windowToolbarStyle(.expanded) // Título acima da toolbar
.windowToolbarStyle(.unified(showsTitle: false)) // Sem título
Conteúdo da toolbar na View:
.toolbar {
ToolbarItem(placement: .automatic) {
Button(action: addItem) {
Label("Adicionar", systemImage: "plus")
}
}
}
.searchable(text: $searchText, placement: .sidebar)
Window Sizing & Positioning
WindowGroup {
ContentView()
.frame(minWidth: 600, minHeight: 400) // Mínimos no conteúdo
}
.defaultSize(width: 900, height: 600) // Tamanho inicial
.defaultPosition(.center) // Posição inicial
.windowResizability(.contentMinSize) // Usa minWidth/minHeight do frame
windowResizability opções:
| Valor | Comportamento |
|---|---|
.automatic | Sistema decide |
.contentSize | Tamanho fixo, sem redimensione |
.contentMinSize | Redimensionável com mínimo pelo frame |
Posicionamento preciso (macOS 15.0+):
.windowIdealPlacement { context in
let screen = context.defaultDisplay.visibleArea
return WindowPlacement(x: screen.midX, y: screen.midY,
width: screen.width / 2,
height: screen.height)
}
Window Style
// Padrão — barra de título visível
WindowGroup { ContentView() }
.windowStyle(.titleBar)
// Sem barra de título — janelas imersivas
WindowGroup { ContentView() }
.windowStyle(.hiddenTitleBar)
NavigationSplitView no macOS
No macOS, as colunas são exibidas lado a lado (nunca sobrepostas). A sidebar recebe fundo translúcido automaticamente.
NavigationSplitView {
List(items, selection: $selectedID) { item in
Text(item.name)
}
.navigationSplitViewColumnWidth(min: 180, ideal: 220, max: 300)
} detail: {
DetailView(id: selectedID)
}
.navigationSplitViewStyle(.balanced)
Três colunas:
NavigationSplitView {
SidebarView()
} content: {
ContentListView(selection: $selectedItem)
} detail: {
DetailView(item: selectedItem)
}
Inspector (macOS 14.0+)
Painel lateral direito redimensionável pelo usuário.
struct ContentView: View {
@State private var showInspector = false
var body: some View {
MainContent()
.inspector(isPresented: $showInspector) {
InspectorView()
.inspectorColumnWidth(min: 200, ideal: 250, max: 400)
}
.toolbar {
ToolbarItem {
Button {
showInspector.toggle()
} label: {
Label("Inspetor", systemImage: "info.circle")
}
}
}
}
}
Commands & Atalhos de Teclado
// Na Scene
.commands {
CommandMenu("Ferramentas") {
Button("Executar Análise") { /* ... */ }
.keyboardShortcut("r", modifiers: [.command, .shift])
}
CommandGroup(after: .newItem) {
Button("Novo Pelo Template…") { /* ... */ }
}
}
Atalhos em botões:
Button("Salvar") { save() }
.keyboardShortcut("s", modifiers: .command)
Button("Excluir") { delete() }
.keyboardShortcut(.delete, modifiers: .command)
Posicionamentos de CommandGroup: .newItem, .saveItem, .help, .toolbar, .sidebar
Use .replacing(_:) para substituir um grupo do sistema.
Modo: views
HSplitView / VSplitView (macOS-only)
Use para layouts IDE-style onde todos os painéis são pares iguais. Para navegação
sidebar → conteúdo, prefira NavigationSplitView.
HSplitView {
FileTreeView()
.frame(minWidth: 200)
CodeEditorView()
.frame(minWidth: 400)
PreviewPane()
.frame(minWidth: 200)
}
VSplitView é idêntico mas divide verticalmente (use minHeight em vez de minWidth).
Table (macOS 12.0+)
struct PeopleTable: View {
@State private var people: [Person] = Person.samples
@State private var selection: Set<Person.ID> = []
@State private var sortOrder = [KeyPathComparator(\Person.name)]
var body:
---
*Content truncated.*
When not to use it
- →When implementing functionalities that are not exclusive to macOS
- →When the project is not a multi-platform SwiftUI application
- →When the user does not need to use macOS-specific APIs
Limitations
- →All macOS-exclusive APIs MUST be within `#if os(macOS)` in multi-platform projects.
- →UtilityWindow is only available on macOS 15.0+.
- →NSViewRepresentable should not directly define frame/bounds on the managed NSView.
How it compares
This skill provides specialized guidance and code templates for macOS-specific SwiftUI features, including scene configuration and AppKit interop, unlike general SwiftUI development.
Compared to similar skills
macos side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| macos (this skill) | 0 | 4mo | No flags | Intermediate |
| liquid-glass-developer | 23 | 3mo | No flags | Intermediate |
| swiftui-liquid-glass | 15 | 4mo | No flags | Intermediate |
| swiftui-expert-skill | 13 | 4mo | 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
liquid-glass-developer
anyproto
Context-aware routing to iOS 26 Liquid Glass implementation patterns. Use when working with glass effects, GlassEffectContainer, morphing transitions, or iOS 26 visual effects.
swiftui-liquid-glass
Dimillian
Implement, review, or improve SwiftUI features using the iOS 26+ Liquid Glass API. Use when asked to adopt Liquid Glass in new SwiftUI UI, refactor an existing feature to Liquid Glass, or review Liquid Glass usage for correctness, performance, and design alignment.
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.
design-system-developer
anyproto
Context-aware routing to the Anytype iOS design system including icons, typography, colors, and spacing. Use when working with Figma-to-code translation, design assets, or UI components.
ios-dev-guidelines
anyproto
Context-aware routing to Swift/iOS development patterns, architecture, and best practices. Use when working with .swift files, ViewModels, Coordinators, refactoring, or discussing Swift/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.