Using Qt 5.11.1 via homebrew on MacOS 10.13.6, I'm using QSettings in my application. This is a working program that I'm porting from Linux and Windows now to MacOS.
The issue I'm having on MacOS is that it'll save the file to /Users/michaelleonetti/Library/Preferences/com.sonarcloud.Sonarcloud Service.plist, which it's supposed to, on first program execution.
If I delete the file sometimes it comes back. Sometimes it doesn't. If I edit the plist file with Xcode and save it, the values I write in "have" won't be there.
I can't identify a rhyme or a reason to make it work.
I've created a minimal example:
#include <QSettings>
#include <iostream>
int main( int argc, char *argv[] )
{
{ // Scope
QSettings settings( QSettings::NativeFormat, QSettings::UserScope, "My Application Company", "My Application" );
if( settings.contains( "have" ) )
std::cout << "We have: " << settings.value( "have" ).toString().toStdString() << std::endl;
else
std::cout << "You do not have" << std::endl;
settings.setValue( "version", 10 );
std::cout << "Path is: " << settings.fileName().toStdString() << std::endl;
}
return( EXIT_SUCCESS );
}
Output:
$ ./src/reproduce
You do not have
Path is: /Users/michaelleonetti/Library/Preferences/com.my-application-company.My Application.plist
File check
$ cat "/Users/michaelleonetti/Library/Preferences/com.my-application-company.My Application.plist"
cat: /Users/michaelleonetti/Library/Preferences/com.my-application-company.My Application.plist: No such file or directory
How can I get this issue solved?
I think this is due to QSettings
being implemented on top of Apple's CFPreferences
database. This is expected behavior and the "fix" is to call CFPreferencesSynchronize()
Docs:
writes all pending changes to preference data to permanent storage, and reads latest preference data from permanent storage
Luckily it appears that QT wraps this in its Mac implementation for QSettings
and you should be able to call QSettings::sync()
to do this in a platform agnostic way.
Basically you need to synchronize your settings before you will see any changes from external writes**. This is also why the file doesn't appear to always be rewritten (it should on application exit when things are automatically flushed).
Note that you will also need synchronize your settings from the external application by calling CFPreferencesSynchronize()
within that application in order to see changes made by your QT app.
It also might be interesting to know that there is a command line utility available called defaults
that you can use to perform syncronized writes from a shell script or terminal.
** This occurs naturally at certain points automatically.