Recent

Author Topic: Mac Library path  (Read 10631 times)

WildMan

  • New Member
  • *
  • Posts: 22
Mac Library path
« on: July 01, 2012, 01:48:56 pm »
I need to store some data, user files, images and such, in a Mac app.  On the Windows version of my app that stuff is saved into a directory within the My Documents directly.  If I understand this correctly, on the Mac I should shove all that into /Library/MyApp.  Is it OK to hard code that directory, or should I be calling a function to retrieve the location of the Library path?  (Can I assume that the Library path will always be /Library?) In Windows, the app calls a function to determine the location of the My Documents directory.

Would it be acceptable to store everything in directories within /Library/MyApp (with a directory for user data, a directory for images, one for app databases, etc) or would that not be a "Well behaved" application?  In other words, do I need to store configuration data in the Application Support directory instead?  Most of this stuff is supplied with the app but it's all subject to user modification.

jwdietrich

  • Hero Member
  • *****
  • Posts: 1232
    • formatio reticularis
Re: Mac Library path
« Reply #1 on: July 01, 2012, 04:22:26 pm »
I would recommend to use the application support folder (which is inside the library folder) rather than the library folder itself. Instead of hardcoding the location, I additionally recommend to use the FSFindFolder function of the Carbon framework.

Code: [Select]
FSFindFolder(kUserDomain, kApplicationSupportFolderType, kCreateFolder, theRef);

A platform independent implementation could be:

Code: [Select]
function AppDataFolder: String;
  { platform-independend method to search for the location of application data folder}
const
  kMaxPath = 1024;
var
  {$IFDEF DARWIN}
  theError: OSErr;
  theRef: FSRef;
  {$ENDIF}
  pathBuffer: PChar;
begin
  {$IFDEF DARWIN}
    try
      pathBuffer := Allocmem(kMaxPath);
    except on exception do exit;
    end;
    try
      Fillchar(pathBuffer^, kMaxPath, #0);
      Fillchar(theRef, Sizeof(theRef), #0);
      theError := FSFindFolder(kOnAppropriateDisk, kApplicationSupportFolderType, kCreateFolder, theRef);
      if (pathBuffer <> nil) and (theError = noErr) then
      begin
        theError := FSRefMakePath(theRef, pathBuffer, kMaxPath);
        if theError = noErr then AppDataFolder := UTF8ToAnsi(StrPas(pathBuffer)) + '/';
      end;
    finally
      Freemem(pathBuffer);
    end
  {$ELSE}
    AppDataFolder := GetUserDir;
  {$ENDIF}
end;

For sake of completeness a similar algorithm finds the correct preferences folder:

Code: [Select]
function GetPreferencesFolder: String;
  { platform-independend method to search for the location of preferences folder}
const
  kMaxPath = 1024;
var
  {$IFDEF DARWIN}
  theError: OSErr;
  theRef: FSRef;
  {$ENDIF}
  pathBuffer: PChar;
begin
  {$IFDEF DARWIN}
    try
      pathBuffer := Allocmem(kMaxPath);
    except on exception do exit;
    end;
    try
      Fillchar(pathBuffer^, kMaxPath, #0);
      Fillchar(theRef, Sizeof(theRef), #0);
      theError := FSFindFolder(kOnAppropriateDisk, kPreferencesFolderType, kDontCreateFolder, theRef);
      if (pathBuffer <> nil) and (theError = noErr) then
      begin
        theError := FSRefMakePath(theRef, pathBuffer, kMaxPath);
        if theError = noErr then GetPreferencesFolder := UTF8ToAnsi(StrPas(pathBuffer)) + '/';
      end;
    finally
      Freemem(pathBuffer);
    end
  {$ELSE}
    GetPreferencesFolder := GetAppConfigDir(false);
  {$ENDIF}
end;

function GetPreferencesFile: String;
begin
  {$IFDEF LCLCarbon}
    GetPreferencesFile := GetPreferencesFolder + SIMTHYR_GLOBAL_ID + '.xml';
  {$ELSE}
    GetPreferencesFile := GetAppConfigFile(false);
  {$ENDIF}
end;   
function GetRandomNumber: integer; // xkcd.com
begin
  GetRandomNumber := 4; // chosen by fair dice roll. Guaranteed to be random.
end;

http://www.formatio-reticularis.de

Lazarus 2.2.6 | FPC 3.2.2 | PPC, Intel, ARM | macOS, Windows, Linux

BigChimp

  • Hero Member
  • *****
  • Posts: 5740
  • Add to the wiki - it's free ;)
    • FPCUp, PaperTiger scanning and other open source projects
Re: Mac Library path
« Reply #2 on: July 01, 2012, 04:37:27 pm »
@jwdietrich: looking at it, seems like nice functions for a patch for FPC.... What do you think?
Want quicker answers to your questions? Read http://wiki.lazarus.freepascal.org/Lazarus_Faq#What_is_the_correct_way_to_ask_questions_in_the_forum.3F

Open source including papertiger OCR/PDF scanning:
https://bitbucket.org/reiniero

Lazarus trunk+FPC trunk x86, Windows x64 unless otherwise specified

jwdietrich

  • Hero Member
  • *****
  • Posts: 1232
    • formatio reticularis
Re: Mac Library path
« Reply #3 on: July 01, 2012, 05:56:39 pm »
Yes I agree, the more as the current implementation of the GetAppConfigDir function is not appropriate for Mac OS X.

As I didn't figure out how to submit a patch, please feel free to use the code for patching if you like to do so.
function GetRandomNumber: integer; // xkcd.com
begin
  GetRandomNumber := 4; // chosen by fair dice roll. Guaranteed to be random.
end;

http://www.formatio-reticularis.de

Lazarus 2.2.6 | FPC 3.2.2 | PPC, Intel, ARM | macOS, Windows, Linux

BigChimp

  • Hero Member
  • *****
  • Posts: 5740
  • Add to the wiki - it's free ;)
    • FPCUp, PaperTiger scanning and other open source projects
Re: Mac Library path
« Reply #4 on: July 01, 2012, 05:58:35 pm »
No thanks (not running on OSX that much and a lot of other stuff going on).

Surprised svn diff doesn't work on OSX...
http://wiki.lazarus.freepascal.org/Creating_A_Patch#Instructions
Want quicker answers to your questions? Read http://wiki.lazarus.freepascal.org/Lazarus_Faq#What_is_the_correct_way_to_ask_questions_in_the_forum.3F

Open source including papertiger OCR/PDF scanning:
https://bitbucket.org/reiniero

Lazarus trunk+FPC trunk x86, Windows x64 unless otherwise specified

jwdietrich

  • Hero Member
  • *****
  • Posts: 1232
    • formatio reticularis
Re: Mac Library path
« Reply #5 on: July 01, 2012, 06:06:22 pm »
Surprised svn diff doesn't work on OSX...
http://wiki.lazarus.freepascal.org/Creating_A_Patch#Instructions

Sure, I use SVN for my own projects, but I never understood the instructions for Lazarus. Now I saw that the Wiki article got better, therefore I will try to submit a patch. Thanks for your hint!
function GetRandomNumber: integer; // xkcd.com
begin
  GetRandomNumber := 4; // chosen by fair dice roll. Guaranteed to be random.
end;

http://www.formatio-reticularis.de

Lazarus 2.2.6 | FPC 3.2.2 | PPC, Intel, ARM | macOS, Windows, Linux

BigChimp

  • Hero Member
  • *****
  • Posts: 5740
  • Add to the wiki - it's free ;)
    • FPCUp, PaperTiger scanning and other open source projects
Re: Mac Library path
« Reply #6 on: July 01, 2012, 06:09:42 pm »
My pleasure - hope it works ;)
Want quicker answers to your questions? Read http://wiki.lazarus.freepascal.org/Lazarus_Faq#What_is_the_correct_way_to_ask_questions_in_the_forum.3F

Open source including papertiger OCR/PDF scanning:
https://bitbucket.org/reiniero

Lazarus trunk+FPC trunk x86, Windows x64 unless otherwise specified

WildMan

  • New Member
  • *
  • Posts: 22
Re: Mac Library path
« Reply #7 on: July 02, 2012, 07:09:04 am »
Thanks for the code snip, that works well.  I'm curious though, why do you suggest using the Application Support folder? (I'm trying to get a handle on proper Mac etiquette).  I'm was looking an a page on the Apple site:

http://developer.apple.com/library/mac/#documentation/General/Conceptual/MOSXAppProgrammingGuide/AppRuntime/AppRuntime.html

It says "The Application Support directory is where your app stores any type of file that supports the app but is not required for the app to run, such as document templates or configuration files. The files should be app-specific but should never store user data."  Of course, that same page says that user data shouldn't be stored in the Library directory either; it doesn't say anything about where user data should be stored. 

Can I go ahead and save everything in a directory within that AppDataFolder and call it good, am I over-analyzing this?  I know it's unlikly that someone else would use the same application name as me, but but what happens in the Mac environment when that does happen; does the packager program just blast all that into the same directory and hope that the two apps don't conflict?

jwdietrich

  • Hero Member
  • *****
  • Posts: 1232
    • formatio reticularis
Re: Mac Library path
« Reply #8 on: July 02, 2012, 11:26:31 am »
Why don't you use the documents folder (~/Documents)?
function GetRandomNumber: integer; // xkcd.com
begin
  GetRandomNumber := 4; // chosen by fair dice roll. Guaranteed to be random.
end;

http://www.formatio-reticularis.de

Lazarus 2.2.6 | FPC 3.2.2 | PPC, Intel, ARM | macOS, Windows, Linux

Shebuka

  • Sr. Member
  • ****
  • Posts: 427
Re: Mac Library path
« Reply #9 on: July 02, 2012, 03:35:07 pm »
It says "The Application Support directory is where your app stores any type of file that supports the app but is not required for the app to run, such as document templates or configuration files. The files should be app-specific but should never store user data."  Of course, that same page says that user data shouldn't be stored in the Library directory either; it doesn't say anything about where user data should be stored.
Because of this, i'm storing application settings (wich has user data) and log files directly in Users/your_user/Library/your_software_name

Quote
Can I go ahead and save everything in a directory within that AppDataFolder and call it good, am I over-analyzing this?  I know it's unlikly that someone else would use the same application name as me, but but what happens in the Mac environment when that does happen; does the packager program just blast all that into the same directory and hope that the two apps don't conflict?
Only your_user has read/write access to user specific Library folder, so it's protected from the fact that other users can see it.
If an application has same name, it will overwrite yours (if installed in /Applications), but even if it will copy it in another folder i bet that it's really difficult that it use same filenames as you...
« Last Edit: July 02, 2012, 03:37:05 pm by Shebuka »

IndianaJones

  • Hero Member
  • *****
  • Posts: 509
Re: Mac Library path
« Reply #10 on: July 02, 2012, 05:05:56 pm »

As Shebuka said, it is the best way to store preference files in "/Users/<username>/Library/Preferences" or some of the vendors save the files in "/Users/<username>/Library/Application Support" at least it is mentioned in some of the forums.
Also additional information about preference files are binary files. you can convert to xml with plutil to see the contents of these binary preference files.


kamischi

  • Full Member
  • ***
  • Posts: 177
Re: Mac Library path
« Reply #11 on: July 02, 2012, 05:36:40 pm »
Preferences should go into Library/Preferences/APPLICATIONNAME and Logs into Library/Logs/APPLICATIONNAME. Other files, which do not need any direct user modification, go to Library/Application Support/APPLICATIONNAME.  One also has to distinguish between shared files for all users in /Library and separate files for each user in ~/Library. The advantage of using the corresponding apple apis (preferences, logs, ...) is that you do not have to deal with it directly.

MiSchi.
« Last Edit: July 02, 2012, 05:48:31 pm by kamischi »
fpc 2.6.4, lazarus 1.4.0, Mac OS X, fink

 

TinyPortal © 2005-2018