makgunay/claude-swift-skills

macos-app-structure

macOS application architecture patterns covering App protocol (@main), Scene types (WindowGroup, Window, Settings, MenuBarExtra), multi-window management, NSApplicationDelegateAdaptor for AppKit lifecycle hooks, Info.plist configuration (LSUIElement for menu bar apps, NSAccessibilityUsageDescription), entitlements for sandbox/hardened runtime, and project structure conventions. Use when scaffolding a new macOS app, configuring scenes and windows, setting up menu bar apps, or resolving macOS-spe…

First seen Feb 14, 2026

Installation

$ npx skills add makgunay/claude-swift-skills --skill macos-app-structure

Summary

  • macOS application architecture patterns covering App protocol (@main), Scene types (WindowGroup, Window, Settings, MenuBarExtra), multi-window management, NSApplicationDelegateAdaptor for AppKit lifecycle hooks, Info.plist configuration (LSUIElement for menu bar apps, NSAccessibilityUsageDescription), entitlements for sandbox/hardened runtime, and project structure conventions.
  • Use when scaffolding a new macOS app, configuring scenes and windows, setting up menu bar apps, or resolving macOS-specific lifecycle issues.
  • Corrects the common LLM mistake of generating iOS-only app structures.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from makgunay/claude-swift-skills · top by installs.

npx skills add makgunay/claude-swift-skills

Browse all from makgunay/claude-swift-skills

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 1
License LICENSE
Default branch main
Open issues 0
Status Active

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 5,928 B
  • docs SUMMARY.md 620 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 43 installs

SKILL.md

macOS App Structure

Critical Constraints

  • ❌ DO NOT use iOS-only scenes (TabView as root scene) → ✅ Use WindowGroup, Window, or NavigationSplitView
  • ❌ DO NOT use UIApplicationDelegate → ✅ Use NSApplicationDelegateAdaptor for AppKit hooks
  • ❌ DO NOT forget Settings scene for Preferences → ✅ macOS apps should have a Settings scene
  • ❌ DO NOT assume single-window → ✅ macOS apps can have multiple windows; design for it
  • ❌ DO NOT use iOS navigation patterns → ✅ Use NavigationSplitView (sidebar + detail) for macOS

Standard macOS App

import SwiftUI

@main
struct MyApp: App {
    @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .defaultSize(width: 900, height: 600)

        Settings {
            SettingsView()
        }
    }
}

class AppDelegate: NSObject, NSApplicationDelegate {
    func applicationDidFinishLaunching(_ notification: Notification) {
        // AppKit lifecycle hooks
    }
    func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
        return true  // Quit when last window closes
    }
}

Menu Bar App

@main
struct MenuBarApp: App {
    var body: some Scene {
        MenuBarExtra("My App", systemImage: "command") {
            MenuBarView()
        }
        .menuBarExtraStyle(.window)  // Full window popover (not just menu items)

        Settings {
            SettingsView()
        }
    }
}

To hide dock icon, add to Info.plist:

<key>LSUIElement</key>
<true/>

Multiple Named Windows

@main
struct MultiWindowApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }

        Window("Inspector", id: "inspector") {
            InspectorView()
        }
        .defaultSize(width: 300, height: 400)
        .defaultPosition(.trailing)

        Settings {
            SettingsView()
        }
    }
}

// Open a named window from code
@Environment(\.openWindow) private var openWindow
Button("Open Inspector") { openWindow(id: "inspector") }

Content View with Sidebar

struct ContentView: View {
    @State private var selection: SidebarItem? = .library

    var body: some View {
        NavigationSplitView {
            List(selection: $selection) {
                Section("Library") {
                    Label("All Items", systemImage: "square.grid.2x2")
                        .tag(SidebarItem.library)
                    Label("Favorites", systemImage: "heart")
                        .tag(SidebarItem.favorites)
                }
            }
            .navigationSplitViewColumnWidth(min: 180, ideal: 220)
        } detail: {
            switch selection {
            case .library: LibraryView()
            case .favorites: FavoritesView()
            case nil: ContentUnavailableView("Select an item", systemImage: "sidebar.left")
            }
        }
        .navigationTitle("My App")
    }
}

Project Structure Convention

MyApp/
├── MyApp.swift              # @main App struct
├── AppDelegate.swift        # NSApplicationDelegateAdaptor (if needed)
├── Models/                  # SwiftData @Model classes
├── Views/
│   ├── ContentView.swift    # Main navigation structure
│   ├── Components/          # Reusable view components
│   └── Settings/            # Settings/Preferences views
├── ViewModels/              # @Observable view models
├── Services/                # Business logic, networking, persistence
├── Utilities/               # Extensions, helpers
├── Resources/
│   ├── Assets.xcassets
│   └── Localizable.xcstrings
├── Info.plist
└── MyApp.entitlements

Key Info.plist Entries (macOS)

<key>LSUIElement</key>           <!-- true = menu bar only, no dock icon -->
<key>NSAccessibilityUsageDescription</key>  <!-- Required for Accessibility API -->
<key>NSAppleEventsUsageDescription</key>    <!-- Required for AppleScript -->

Key Entitlements

<!-- App Sandbox (required for App Store) -->
<key>com.apple.security.app-sandbox</key><true/>

<!-- Network access -->
<key>com.apple.security.network.client</key><true/>

<!-- File access -->
<key>com.apple.security.files.user-selected.read-write</key><true/>

<!-- iCloud -->
<key>com.apple.developer.icloud-container-identifiers</key>

Common Mistakes & Fixes

Mistake Fix
No Settings scene Add Settings { SettingsView() } — expected on macOS
App doesn't quit when last window closes Implement applicationShouldTerminateAfterLastWindowClosed
Dock icon showing for menu bar app Add LSUIElement = true to Info.plist
Window too small on macOS Add .defaultSize(width:height:) to WindowGroup
Using TabView as main navigation Use NavigationSplitView with sidebar on macOS

References