Recent

Author Topic: Finding correct preferences folder under Cocoa  (Read 1784 times)

jwdietrich

  • Hero Member
  • *****
  • Posts: 1036
    • formatio reticularis
Finding correct preferences folder under Cocoa
« on: October 01, 2019, 12:51:28 am »
What is the best practice of finding the preferences folder with Cocoa widgetset?

The usual method to use GetAppConfigDir (and corresponding GetAppConfigFile) are incompatible with Apple's user interface guidelines. They deliver an invisible directory with name ".config" in the home folder, which is, BTW, an inelegant location (since the folder is invisible). The correct way would be to return the folder "Preferences" in the user's library folder.

There is a working solution for Carbon provided at https://wiki.freepascal.org/Multiplatform_Programming_Guide#Proper_macOS_file_locations, but what is the correct way for Cocoa?
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.0.6 | FPC 3.0.4 | PPC, Intel, ARM | macOS, Windows, Linux

dbannon

  • Hero Member
  • *****
  • Posts: 788
    • tomboy-ng, a rewrite of the classic Tomboy
Re: Finding correct preferences folder under Cocoa
« Reply #1 on: October 01, 2019, 09:10:31 am »
jwdietrich, while I agree that ~/.config seems quite un-Mac like, the alternative seems to be in the application bundle. While thats tidy and nice and modular, if the user upgrades to a new version of your app, you better have a plan to migrate the preferences from the old, about to be deleted folder to the new one !

I decided to use the ~/.config approach because my app is cross platform, Windows, Linux and Mac. Mac is, sort of Unix and multiuser and the right place for config files is in the user's home directory. Lazarus keeps its config files there (although not in .config). A number of other apps I looked at do too.

Davo
Lazarus 2, Linux (and reluctantly Win10, OSX)
My Project - https://github.com/tomboy-notes/tomboy-ng

Thaddy

  • Hero Member
  • *****
  • Posts: 9293
Re: Finding correct preferences folder under Cocoa
« Reply #2 on: October 01, 2019, 09:16:16 am »
Hidden directories for user preferences are a long standing feature of Unix like platforms (and windows!).
Can you be more specific why that would clash with the design guidelines? I can't find it...

And even on OSX you can force the file browser to make them visible if so required.
user preferences are usually stored in a custom format specific to an application, so should be hidden from view and only editable from the application itself.
I think that is conformant. It is about persistence, not about outside editability.
« Last Edit: October 01, 2019, 09:24:34 am by Thaddy »
also related to equus asinus.

jwdietrich

  • Hero Member
  • *****
  • Posts: 1036
    • formatio reticularis
Re: Finding correct preferences folder under Cocoa
« Reply #3 on: October 01, 2019, 09:36:19 am »
jwdietrich, while I agree that ~/.config seems quite un-Mac like, the alternative seems to be in the application bundle. While thats tidy and nice and modular, if the user upgrades to a new version of your app, you better have a plan to migrate the preferences from the old, about to be deleted folder to the new one !

No, preferences aren't to be stored in the application bundle. The correct path is in one of the preferences folders (either within ~/Library/ for user-specific preferences or within /Library/ for global preferences). Of course it is possible to pass ~/Library/Preferences/ to the app, but by this way the directory is read-only on newer versions of macOS (and, since locations may change over time, it would be preferable to have a more abstract representation to prepare for potential redefinitions in future versions of macOS).
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.0.6 | FPC 3.0.4 | PPC, Intel, ARM | macOS, Windows, Linux

Thaddy

  • Hero Member
  • *****
  • Posts: 9293
Re: Finding correct preferences folder under Cocoa
« Reply #4 on: October 01, 2019, 09:49:46 am »
@jwdietrich

The hidden parts are per user overrides. Why is this not acceptable:
Code: Bash  [Select]
  1. $ cd ~/.lazarus
to store user preferences? Such directories are not read-only, merely hidden.
also related to equus asinus.

jwdietrich

  • Hero Member
  • *****
  • Posts: 1036
    • formatio reticularis
Re: Finding correct preferences folder under Cocoa
« Reply #5 on: October 01, 2019, 11:13:09 am »
@jwdietrich

The hidden parts are per user overrides. Why is this not acceptable:
Code: Bash  [Select]
  1. $ cd ~/.lazarus
to store user preferences? Such directories are not read-only, merely hidden.

Well, if there isn't another solution I will have to use this option. At least it works. I hope that it will pass App Store checking.
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.0.6 | FPC 3.0.4 | PPC, Intel, ARM | macOS, Windows, Linux

Thaddy

  • Hero Member
  • *****
  • Posts: 9293
Re: Finding correct preferences folder under Cocoa
« Reply #6 on: October 01, 2019, 11:27:45 am »
Yes it will, but you can double check with Apple developer support which is part of your license.
Make sure about asking just about the proper place for persistent user settings storage. (Since Lazarus itself is not the issue, and they are not really familiar, except one or two)
Response is actually pretty quick. And the answer will be close to the same. But check! (I have 2 tokens left, just in case you ran out of free support)
« Last Edit: October 01, 2019, 11:47:59 am by Thaddy »
also related to equus asinus.

VTwin

  • Hero Member
  • *****
  • Posts: 793
  • Former Turbo Pascal 3 user
Re: Finding correct preferences folder under Cocoa
« Reply #7 on: October 01, 2019, 09:32:33 pm »
This is what I have been using:

Code: Pascal  [Select]
  1. function GetApplicationSupportDir(global: boolean = false): string;
  2. var
  3.   t: string;
  4. begin
  5.   {$IFDEF DARWIN}
  6.   t := ExcludeTrailingPathDelimiter(LazUTF8.SysToUTF8(GetUserDir));
  7.   result := t + '/Library/Application Support/' +  LazUTF8.SysToUTF8(ApplicationName);
  8.   {$ELSE}
  9.   result := GetAppConfigDirUTF8(global);
  10.   {$ENDIF}
  11. end;  

This has worked so far for Carbon and Cocoa, but I'd be happy to have a definitive solution.
“Talk is cheap. Show me the code.” -Linus Torvalds

macOS 10.13.6: Lazarus 2.0.7 fixes svn 62300 (64 bit Cocoa)
Ubuntu 18.04.3: Lazarus 2.0.6 (64 bit on VBox)
Windows 7 Pro SP1: Lazarus 2.0.6 (64 bit on VBox)
fpc 3.0.4

trev

  • Sr. Member
  • ****
  • Posts: 255
  • Former Delphi 7 and Delphi 10.2 User
o Lazarus v2.1.0 r61775, FPC v3.3.1 r42640, macOS 10.14.6 (with sup update), Xcode 10.3
o Lazarus v2.1.0 r61574, FPC v3.3.1 r42318, FreeBSD 12.0 (Parallels VM)
o Lazarus v2.1.0 r61574, FPC v3.0.4, Ubuntu 18.04 (Parallels VM)

VTwin

  • Hero Member
  • *****
  • Posts: 793
  • Former Turbo Pascal 3 user
Re: Finding correct preferences folder under Cocoa
« Reply #9 on: October 15, 2019, 05:16:51 pm »
This is what I use:

https://wiki.lazarus.freepascal.org/Multiplatform_Programming_Guide#Proper_macOS_file_locations

Thanks. I had been using code obtained elsewhere some time ago, and missed this. Hopefully this works on all macOS versions in common use.

I'd prefer to just use ".config", but that is a macOS  "violation".
“Talk is cheap. Show me the code.” -Linus Torvalds

macOS 10.13.6: Lazarus 2.0.7 fixes svn 62300 (64 bit Cocoa)
Ubuntu 18.04.3: Lazarus 2.0.6 (64 bit on VBox)
Windows 7 Pro SP1: Lazarus 2.0.6 (64 bit on VBox)
fpc 3.0.4

jwdietrich

  • Hero Member
  • *****
  • Posts: 1036
    • formatio reticularis
Re: Finding correct preferences folder under Cocoa
« Reply #10 on: October 15, 2019, 07:11:05 pm »
This is what I use:

https://wiki.lazarus.freepascal.org/Multiplatform_Programming_Guide#Proper_macOS_file_locations

As already stated in the first post, this works with Carbon only. Cocoa needs a different approach.
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.0.6 | FPC 3.0.4 | PPC, Intel, ARM | macOS, Windows, Linux

trev

  • Sr. Member
  • ****
  • Posts: 255
  • Former Delphi 7 and Delphi 10.2 User
Re: Finding correct preferences folder under Cocoa
« Reply #11 on: October 16, 2019, 09:01:06 am »
This is what I use:

https://wiki.lazarus.freepascal.org/Multiplatform_Programming_Guide#Proper_macOS_file_locations

As already stated in the first post, this works with Carbon only. Cocoa needs a different approach.

No! I am using it successfully in a Cocoa-only application which runs on Catalina. Honest!
« Last Edit: October 16, 2019, 09:07:29 am by trev »
o Lazarus v2.1.0 r61775, FPC v3.3.1 r42640, macOS 10.14.6 (with sup update), Xcode 10.3
o Lazarus v2.1.0 r61574, FPC v3.3.1 r42318, FreeBSD 12.0 (Parallels VM)
o Lazarus v2.1.0 r61574, FPC v3.0.4, Ubuntu 18.04 (Parallels VM)

VTwin

  • Hero Member
  • *****
  • Posts: 793
  • Former Turbo Pascal 3 user
Re: Finding correct preferences folder under Cocoa
« Reply #12 on: October 16, 2019, 11:34:53 pm »
According to this archive:

https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/MacOSXDirectories/MacOSXDirectories.html

it was ok to directly access ~/Library/Application Support/

I'm still curious to hear an official Apple statement as to any recent changes. I'm still on High Sierra, where it works.
« Last Edit: October 16, 2019, 11:36:34 pm by VTwin »
“Talk is cheap. Show me the code.” -Linus Torvalds

macOS 10.13.6: Lazarus 2.0.7 fixes svn 62300 (64 bit Cocoa)
Ubuntu 18.04.3: Lazarus 2.0.6 (64 bit on VBox)
Windows 7 Pro SP1: Lazarus 2.0.6 (64 bit on VBox)
fpc 3.0.4

trev

  • Sr. Member
  • ****
  • Posts: 255
  • Former Delphi 7 and Delphi 10.2 User
Re: Finding correct preferences folder under Cocoa
« Reply #13 on: October 17, 2019, 02:12:27 am »
According to this archive:

https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/MacOSXDirectories/MacOSXDirectories.html

it was ok to directly access ~/Library/Application Support/

I'm still curious to hear an official Apple statement as to any recent changes. I'm still on High Sierra, where it works.

Specifically with respect to Preferences:   

Quote
This directory contains app-specific preference files. You should not create files in this directory yourself. Instead, use the NSUserDefaults class or CFPreferences API to get and set preference values for your app.
From: https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html#//apple_ref

which is covered on the Wiki at https://wiki.lazarus.freepascal.org/Mac_Preferences_Read_and_Write
o Lazarus v2.1.0 r61775, FPC v3.3.1 r42640, macOS 10.14.6 (with sup update), Xcode 10.3
o Lazarus v2.1.0 r61574, FPC v3.3.1 r42318, FreeBSD 12.0 (Parallels VM)
o Lazarus v2.1.0 r61574, FPC v3.0.4, Ubuntu 18.04 (Parallels VM)

trev

  • Sr. Member
  • ****
  • Posts: 255
  • Former Delphi 7 and Delphi 10.2 User
Re: Finding correct preferences folder under Cocoa
« Reply #14 on: October 17, 2019, 09:45:43 am »
I just found this while implementing preferences in my application:

Quote
Preference File Locations and Debugging

Preferences files are stored in the system’s or user’s preferences directories. On OS X versions 10.0 to 10.4 these are in /Library/Preferences and in /Library/Preferences in the user’s home directory respectively. When debugging an application, it may sometimes be useful to inspect these files to determine that preferences have been saved correctly, however you should never hardcode these paths into an application. If you do need to access the directory programmatically you should use the NSSearchPathForDirectoriesInDomains API, although there should typically be no reason to do so.

Source: https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFPreferences/Concepts/BestPractices.html#//apple_ref/doc/uid/TP30001219-DontLinkElementID_4
o Lazarus v2.1.0 r61775, FPC v3.3.1 r42640, macOS 10.14.6 (with sup update), Xcode 10.3
o Lazarus v2.1.0 r61574, FPC v3.3.1 r42318, FreeBSD 12.0 (Parallels VM)
o Lazarus v2.1.0 r61574, FPC v3.0.4, Ubuntu 18.04 (Parallels VM)