Difference between revisions of "Locating macOS app support, preferences folders"

From Free Pascal wiki
Jump to navigationJump to search
(New macOS content :-)
 
Line 23: Line 23:
 
   {platform-independent method to retrieve application support/preferences directories
 
   {platform-independent method to retrieve application support/preferences directories
 
    
 
    
   FolderTypes: kApplicationSupportFolderType _or_ kPreferencesFolderType}
+
   FolderTypes: kApplicationSupportFolderType _or_ kPreferencesFolderType
 
    
 
    
 
   User preferences live in the location returned by FSFindFolder(kUserDomain,kPreferencesFolderType).
 
   User preferences live in the location returned by FSFindFolder(kUserDomain,kPreferencesFolderType).

Revision as of 01:09, 8 January 2020

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.

Application Support and Preferences Folders

The function below will return the location the macOS user/global application support directories and the user/global application preferences directories. You would not normally need to manually locate the macOS user preferences directory because the CFPreferences read/write methods will do this for you automatically.

As a bonus, the function below will also return the user/global application support directories for other operating systems.

...

Uses
  {$IFDEF DARWIN}
  MacOSAll, Files
  {$ENDIF}

...

  {platform-independent method to retrieve application support/preferences directories
  
   FolderTypes: kApplicationSupportFolderType _or_ kPreferencesFolderType
  
   User preferences live in the location returned by FSFindFolder(kUserDomain,kPreferencesFolderType).
   User application support items live in the location returned by FSFindFolder(kUserDomain, kApplicationSupportFolderType).
   Global preferences live in the location returned by FSFindFolder(kLocalDomain,kPreferencesFolderType).
   Global application support items live in the location returned by FSFindFolder(kLocalDomain, kApplicationSupportFolderType).
  }

function GetSupportDir(Global:boolean; FolderType:LongWord): String;

{$IFDEF DARWIN}
const
  kMaxPath = 1024;
var
  theError: OSErr;
  theRef: FSRef;
  pathBuffer: PChar;
{$ENDIF}
begin
  {$IFDEF DARWIN}
    theRef := Default(FSRef);   // init 

    try
      pathBuffer := Allocmem(kMaxPath);
    except on exception 
      do exit;
    end;

    try
      Fillchar(pathBuffer^, kMaxPath, #0);
      Fillchar(theRef, Sizeof(theRef), #0);
      if Global then   // kLocalDomain
        theError := FSFindFolder(kLocalDomain, FolderType, kDontCreateFolder, theRef)
      else             // kUserDomain
        theError := FSFindFolder(kUserDomain , FolderType, kDontCreateFolder, theRef);
      if (pathBuffer <> nil) and (theError = noErr) then
        begin
          theError := FSRefMakePath(theRef, pathBuffer, kMaxPath);
          if theError = noErr then 
            GetSupportDir := UTF8ToAnsi(StrPas(pathBuffer)) + '/' + ApplicationName + '/';
        end;
    finally
      Freemem(pathBuffer);
    end
  {$ELSE}
    //
    // Other operating systems
    //
    GetSupportDir := GetAppConfigDirUTF8(Global);
  {$ENDIF}
end;