mcpField
M
macos-app-structure

macos-app-structure

github.com/makgunay开发144 次安装38 周前更新
代码仓库

关于 macos-app-structure

面向构建或审查 Mac 应用的开发者,提供 SwiftUI macOS 应用结构参考。内容涵盖场景选择、窗口、导航、项目布局及常见的平台特定错误。

主要功能

  1. 01macOS 场景与窗口模式
  2. 02菜单栏应用结构
  3. 03侧边栏导航指南
  4. 04项目布局约定
  5. 05Info.plist 与权限配置参考
  6. 06常见错误与修正

适用场景

  1. 01规划 SwiftUI macOS 应用结构
  2. 02添加菜单栏或多窗口支持
  3. 03检查 macOS 导航与设置场景

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/makgunay/claude-swift-skills --skill macos-app-structure

安装后在 Claude Code 中输入/macos-app-structure确认已加载。

详细介绍

macOS 应用结构

关键限制

  • ❌ 不要使用仅适用于 iOS 的场景(以 TabView 作为根场景)→ ✅ 使用 WindowGroup、Window 或 NavigationSplitView
  • ❌ 不要使用 UIApplicationDelegate → ✅ 使用 NSApplicationDelegateAdaptor 接入 AppKit
  • ❌ 不要忘记为偏好设置添加 Settings 场景 → ✅ macOS 应用应包含 Settings 场景
  • ❌ 不要假设只有一个窗口 → ✅ macOS 应用可以有多个窗口;设计时应考虑这一点
  • ❌ 不要使用 iOS 导航模式 → ✅ 在 macOS 上使用 NavigationSplitView(侧边栏 + 详情)

标准 macOS 应用

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
    }
}

菜单栏应用

@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()
        }
    }
}

要隐藏程序坞图标,请在 Info.plist 中添加:

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

多个命名窗口

@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") }

带侧边栏的内容视图

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")
    }
}

项目结构约定

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

关键 Info.plist 条目(macOS)

<key>LSUIElement</key>           
<key>NSAccessibilityUsageDescription</key>  
<key>NSAppleEventsUsageDescription</key>    

关键权利配置


<key>com.apple.security.app-sandbox</key><true/>


<key>com.apple.security.network.client</key><true/>


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


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

常见错误与修复方法

错误修复方法
没有 Settings 场景添加 Settings { SettingsView() } — 这是 macOS 的预期配置
关闭最后一个窗口后应用不会退出实现 applicationShouldTerminateAfterLastWindowClosed
菜单栏应用显示程序坞图标在 Info.plist 中添加 LSUIElement = true
macOS 上的窗口太小在 WindowGroup 中添加 .defaultSize(width:height:)
使用 TabView 作为主导航在 macOS 上使用带侧边栏的 NavigationSplitView

参考资料

评论

支持 Markdown