Mac Preferences Read and Write
This article applies to macOS only.
See also: Multiplatform Programming Guide
│
English (en) │
macOS File Storage Overview
Before we go any further, let's recap where the Apple Guidelines indicate your application should store its files:
- Use the /Applications or /Applications/Utilities directory for the application bundle. The application bundle should contain everything: libraries, dependencies, help, every file that the application needs to run except those created by the application itself. If the application bundle is copied to another machine's /Applications or /Applications/Utilities directory, it should be able to run. Installing to these folders requires Admin privileges. The data in these folders is backed up by Time Machine.
- Use the ~/Applications directory should Admin privileges not be available. This is the standard location for a single user application. This directory should not be expected to exist. The application bundle should contain everything: libraries, dependencies, help, every file that the application needs to run except those created by the application itself. If the application bundle is copied to another machine's /Applications or /Applications/Utilities directory, it should be able to run. This data is backed up by Time Machine.
- Use the Application Support directory (this data is backed up by Time Machine), appending your <bundle_ID>, for:
- Resource and data files that your application creates and manages for the user. You might use this directory to store application state information, computed or downloaded data, or even user created data that you manage on behalf of the user.
- Autosave files.
- Use the Caches directory (this is not backed up by Time Machine), appending your <bundle_ID>, for cached data files or any files that your application can recreate easily.
- Use CFPreferences to read and write your application's preferences. This will automatically write preferences to the appropriate location and read them from the appropriate location. This data is backed up by Time Machine.
- Use the application Resources directory (this is backed up by Time Machine) for your application-supplied image files, sound files, icon files and other unchanging data files necessary for your application's operation.
- Use NSTemporaryDirectory (this is not backed up by Time Machine) to store temporary files that you intend to use immediately for some ongoing operation but then plan to discard later. Delete temporary files as soon as you are done with them.
CFPreferences
For those who want to read and write preferences for a macOS application, this can be done using the following methods:
CODE FOR READING PREFERENCES |
---|
uses MacOSAll, CFPreferences;
var
IsValid: Boolean; // On return indicates if key exists and has valid data
Pref: Integer;
procedure TForm1.FormCreate(Sender: TObject);
begin
try
Pref := CFPreferencesGetAppIntegerValue(CFStr('Check1'),kCFPreferencesCurrentApplication,IsValid);
if (Pref = 1) then
CheckBox1.Checked := true
else
CheckBox1.Checked := false;
Pref := CFPreferencesGetAppIntegerValue(CFStr('Check2'),kCFPreferencesCurrentApplication,IsValid);
if (Pref = 1) then
CheckBox2.Checked := true
else
CheckBox2.Checked := false;
Pref := CFPreferencesGetAppIntegerValue(CFStr('Check3'),kCFPreferencesCurrentApplication,IsValid);
if (Pref = 1) then
CheckBox3.Checked := true
else
CheckBox3.Checked := false;
Pref := CFPreferencesGetAppIntegerValue(CFStr('Check4'),kCFPreferencesCurrentApplication,IsValid);
if (Pref = 1) then
CheckBox4.Checked := true
else
CheckBox4.Checked := false;
except
on E : Exception do
ShowMessage(E.ClassName+' error raised, with message : '+E.Message);
end;
end;
CODE FOR WRITING PREFERENCES |
---|
uses MacOSAll, CFPreferences;
var
ItemName: CFStringRef;
ItemVal: CFPropertyListRef;
procedure TForm1.FormClose(Sender: TObject);
begin
try
if (CheckBox1.Checked) then
begin
ItemName := CFStr('Check1');
ItemVal := CFStringCreateWithPascalString(kCFAllocatorDefault,'1',kCFStringEncodingUTF8);
CFPreferencesSetAppValue(ItemName,ItemVal,kCFPreferencesCurrentApplication);
end
else
begin
ItemName := CFStr('Check1');
ItemVal := CFStringCreateWithPascalString(kCFAllocatorDefault,'0',kCFStringEncodingUTF8);
CFPreferencesSetAppValue(ItemName,ItemVal,kCFPreferencesCurrentApplication);
end;
if (CheckBox2.Checked) then
begin
ItemName := CFStr('Check2');
ItemVal := CFStringCreateWithPascalString(kCFAllocatorDefault,'1',kCFStringEncodingUTF8);
CFPreferencesSetAppValue(ItemName,ItemVal,kCFPreferencesCurrentApplication);
end
else
begin
ItemName := CFStr('Check2');
ItemVal := CFStringCreateWithPascalString(kCFAllocatorDefault,'0',kCFStringEncodingUTF8);
CFPreferencesSetAppValue(ItemName,ItemVal,kCFPreferencesCurrentApplication);
end;
if (CheckBox3.Checked) then
begin
ItemName := CFStr('Check3');
ItemVal := CFStringCreateWithPascalString(kCFAllocatorDefault,'1',kCFStringEncodingUTF8);
CFPreferencesSetAppValue(ItemName,ItemVal,kCFPreferencesCurrentApplication);
end
else
begin
ItemName := CFStr('Check3');
ItemVal := CFStringCreateWithPascalString(kCFAllocatorDefault,'0',kCFStringEncodingUTF8);
CFPreferencesSetAppValue(ItemName,ItemVal,kCFPreferencesCurrentApplication);
end;
if (CheckBox4.Checked) then
begin
ItemName := CFStr('Check4');
ItemVal := CFStringCreateWithPascalString(kCFAllocatorDefault,'1',kCFStringEncodingUTF8);
CFPreferencesSetAppValue(ItemName,ItemVal,kCFPreferencesCurrentApplication);
end
else
begin
ItemName := CFStr('Check4');
ItemVal := CFStringCreateWithPascalString(kCFAllocatorDefault,'0',kCFStringEncodingUTF8);
CFPreferencesSetAppValue(ItemName,ItemVal,kCFPreferencesCurrentApplication);
end;
// write out the preference data
CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication);
except
on E : Exception do
ShowMessage(E.ClassName+' error raised, with message : '+E.Message);
end;
NSUserDefaults
The NSUserDefaults class, available since Mac OS X 10.0 (Cheetah), provides a programmatic interface for interacting with the defaults system which allows an application to customise its behaviour to match a user’s preferences.
Unfortunately there were serious problems with NSUserdefaults in iOS 9 and macOS 10.12 (Sierra) and 10.13 (High Sierra) which mitigate against its use. Some of the issues are mentioned in this Apple Developer Forum thread.
See also
- macOS Form Position Save and Restore - Automatic save and restore using just one line of code!
- Introduction to platform-sensitive development
- Proper macOS file locations
- macOS Programming Tips