Windows and commands

Add a Settings scene

Store small preferences with AppStorage and let SwiftUI connect a normal settings window to the application menu.

12 minute lesson

~~~

Every Mac app has a Settings item in its application menu, with ⌘, as the shortcut. Users do not think about this — they expect it, the way they expect Quit at the bottom of the same menu.

SwiftUI wires all of it from one scene declaration. Add it beside your other scenes:

Settings {
  SettingsView()
}

That is the whole integration. The menu item appears, ⌘, works, and macOS presents a standard settings window. You never write “open the settings window” code.

Inside, build a form. For small preferences, @AppStorage connects a property straight to UserDefaults:

struct SettingsView: View {
  @AppStorage("showLineNumbers") private var showLineNumbers = true
  @AppStorage("fontSize") private var fontSize = 14.0

  var body: some View {
    Form {
      Toggle("Show line numbers", isOn: $showLineNumbers)
      Slider(value: $fontSize, in: 10...24) {
        Text("Font size")
      }
    }
    .padding()
    .frame(width: 350)
  }
}

Reading the same key elsewhere gives you a live value. Declare @AppStorage("showLineNumbers") in the note detail view and the UI updates the moment the toggle changes — no notification code, no manual refresh.

Two rules keep this clean. First, key names are permanent: rename "showLineNumbers" in a later version and every user silently loses their preference. Define keys once and never touch them again. Second, every key needs a sensible default, because the first launch has no stored value.

If settings grow, split them into tabs the way system apps do:

TabView {
  GeneralSettings()
    .tabItem { Label("General", systemImage: "gearshape") }
  EditorSettings()
    .tabItem { Label("Editor", systemImage: "textformat") }
}

Know what does not belong here. UserDefaults stores plain text in a plist anyone can read with one Terminal command, so API tokens and passwords go in the Keychain — we will do exactly that in a later lesson. Primary documents, like the notes themselves, need real files with atomic saves, not preference storage.

Verify by running the app: the application menu shows Settings…, ⌘, opens the window, toggling the switch updates the editor immediately, and the value survives a relaunch. If the menu item is missing, your Settings scene is probably declared inside another scene’s body instead of beside it.

Lesson completed

Take this course offline

Get every free book and course as PDF and EPUB files.

Get the download library →