Listen for and respond to a user’s preference changes in your Mac app built with Mac Catalyst using Combine.
- iOS 13.0+
- Xcode 11.1+
- Mac Catalyst 13.0+
With Combine, your app can listen for changes a user makes to the app’s Preferences window, and respond to those changes. The sample app provides a Preferences window with one setting: background color. When the user selects a color, the background of the main view changes to match their selection.
This sample code project shows how to:
Add a Preferences window in a Mac app built with Mac Catalyst.
Register default values for the preferences.
Retrieve current preference values.
Listen for and respond to changes the user makes in the Preferences window.
To use the sample app, open the sample code project in Xcode and select My Mac as the destination. Then, build and run the sample project.
Provide a Preferences Window in the App
The sample app includes a
Settings file that the system uses to automatically add the standard Preferences menu item to the app menu. Selecting the menu item displays a Preferences window that the system generates based on the preference specifiers defined in the Settings bundle. To learn more, see Displaying a Preferences Window.
The Settings bundle for the sample app has a preference specifier for setting the background color of the main view. It also has a child pane preference specifier, which displays a second tab of preferences in the Preferences windows. The Settings bundle file
Root defines these specifiers, while the file
Other defines the preference specifiers for the child pane.
Register Default Preference Values
When the user changes preferences in the Preferences window, the window saves them to the application domain of the user defaults system. To store and retrieve the preference values within the app, the sample app uses
NSUser. However, when you launch the sample app for the first time, the preference values don’t exist in the user defaults system. If the app tries retrieving a value,
To ensure that the app always retrieves a non-
nil value, the sample app registers the default preference values with the registration domain. However, this domain doesn’t persist these values between app launches, so the sample app registers the default values each time the user launches the app.
register retrieves the default values from the Settings bundle by retrieving the preference specifiers from the
Root file and parsing the specifiers for their default value. After retrieving the values, the method registers the default values.
To parse the preference specifiers, the
parse() method loops through the array of specifiers, copying the default values into the dictionary
default. If the method detects the
PSChild type, it gets the name of the child pane property list file, and merges the default values in the file into the
default dictionary. After gathering the default values, the method returns the dictionary to the caller.
Retrieve Preference Values
After registering the default values with the registration domain, the app can retrieve a preference value without the possibility of encountering an unavailable value. To simplify access to the background color preference value, the sample app extends
NSUser to include properties for each preference value.
Handle Changes Made in the Preferences Window
As the user changes the background color setting in the Preferences window, the app changes the background color of its main view. To accomplish this, the view controller for the main view creates a subscriber in the
view method. When the background color value changes, the subscriber receives the new value, maps it to a
UIColor object, and assigns the color to the view’s