reading preferences from com.apple.mail under 10.8

  • Hello. I’m trying to read Mail’s preferences to find a suitable SMTP server so users don’t have to re-enter such configuration details. It seems to have stopped working and I can’t find a [documented] reason.

    I’ve tried

        NSUserDefaults *mailPrefs = [[NSUserDefaults alloc] init];
        NSArray *smtpList = [[mailPrefs persistentDomainForName:@"com.apple.mail"] objectForKey:@"DeliveryAccounts"];

    and

        NSArray *mailPrefs = (__bridge NSArray *)CFPreferencesCopyValue((CFStringRef)@"DeliveryAccounts", (CFStringRef)@"com.apple.mail", kCFPreferencesCurrentUser, kCFPreferencesAnyHost);

    but neither return any results on a 10.8 system. My application is not sandboxed. Mail is, but so is TextEdit and I have no problem reading its prefs.

    Any ideas? Thanks.

    --
    Rob McBroom
    <http://www.skurfer.com/>
  • On Jul 31, 2012, at 8:07 AM, Rob McBroom <mailinglist0...> wrote:

    > Hello. I’m trying to read Mail’s preferences to find a suitable SMTP server so users don’t have to re-enter such configuration details. It seems to have stopped working and I can’t find a [documented] reason.

    Probably Mail changed where it stores that pref. It might be under a different key, or it might be stored in another domain entirely.

    App defaults keys are not public, so you're relying on undocumented internal behavior of Mail, that could (and did!) change at any time.

    A more supported way to get that info might be to query Mail's scripting interface using an AppleScript or the scripting bridge API.

    —Jens
  • In Mountain Lion Mail is a sandboxed app. Therefore it now stores it's
    preferences in ~/Library/Containers/com.apple.mail/Data/Library/Preferences

    Gabriel

    On 02.08.12 07:44, "<cocoa-dev-request...>"
    <cocoa-dev-request...> wrote:

    > On Jul 31, 2012, at 8:07 AM, Rob McBroom <mailinglist0...>  wrote:
    >
    >> Hello. I¹m trying to read Mail¹s preferences to find a suitable SMTP
    >> server so users don¹t have to re-enter such configuration details. It
    >> seems to have stopped working and I can¹t find a [documented] reason.
    >
    > Probably Mail changed where it stores that pref. It might be under a
    > different key, or it might be stored in another domain entirely.
    >
    > App defaults keys are not public, so you're relying on undocumented
    > internal behavior of Mail, that could (and did!) change at any time.
    >
    > A more supported way to get that info might be to query Mail's scripting
    > interface using an AppleScript or the scripting bridge API.
    >
    > ‹Jens
  • On 01/08/2012, at 1:07 AM, Rob McBroom <mailinglist0...> wrote:

    > Mail is, but so is TextEdit and I have no problem reading its prefs.

    Are you sure you have no problem with TextEdit? It looks like when Mail moves its prefs to its container it deletes the old file, but TextEdit leaves its old one there. You may well be reading a pre-update TextEdit prefs file.

    --
    Shane Stanley <sstanley...>
    'AppleScriptObjC Explored' <www.macosxautomation.com/applescript/apps/>
  • On Aug 2, 2012, at 1:44 AM, Jens Alfke <jens...> wrote:

    > On Jul 31, 2012, at 8:07 AM, Rob McBroom <mailinglist0...> wrote:
    >
    >> Hello. I’m trying to read Mail’s preferences to find a suitable SMTP server so users don’t have to re-enter such configuration details. It seems to have stopped working and I can’t find a [documented] reason.
    >
    > Probably Mail changed where it stores that pref. It might be under a different key, or it might be stored in another domain entirely.

    It didn’t. I am able to look at the plist directly, and `defaults read com.apple.mail` works as expected. I would have thought `defaults` was using `NSUserDefaults` internally, but apparently not.

    > A more supported way to get that info might be to query Mail's scripting interface using an AppleScript or the scripting bridge API.

    Thanks, but Scripting Bridge requires Mail to be running. That’s not on option in this context.

    And I question whether Scripting Bridge is “more supported” than `NSUserDefaults`. :-)

    --
    Rob McBroom
    <http://www.skurfer.com/>
  • On Aug 2, 2012, at 3:07 AM, Shane Stanley <sstanley...> wrote:

    > On 01/08/2012, at 1:07 AM, Rob McBroom <mailinglist0...> wrote:
    >
    >> Mail is, but so is TextEdit and I have no problem reading its prefs.
    >
    > Are you sure you have no problem with TextEdit? It looks like when Mail moves its prefs to its container it deletes the old file, but TextEdit leaves its old one there. You may well be reading a pre-update TextEdit prefs file.

    I was all ready to say “Yes, I’m sure”, but the app isn’t actually reading TextEdit’s prefs. It’s asking for com.apple.TextEdit.LSSharedFileList. Reading the actual preferences doesn’t seem to work.

    So maybe you can’t read the prefs from a sandboxed application? But that isn’t documented anywhere that I can find.

    --
    Rob McBroom
    <http://www.skurfer.com/>
  • On Thu, 2 Aug 2012 08:47:27 -0400, Rob McBroom said:

    > So maybe you can’t read the prefs from a sandboxed application?

    That would seem to fit with the whole idea of a sandbox, wouldn't it?

    It would probably work if you give yourself a temporary entitlement to Mail's pref file.  I would try that as a test.  It sucks as a solution, because you'd have to hardcode a path (always a fragile thing).  I've never used App Store, but I imagine they may not allow that solution either.  So if you care about App Store, you may need to degrade your user experience, as is apparently happening a lot because of App Sandbox.  Better to ditch App Store, but I digress.

    But since you're looking for something pretty standard, like the user's SMTP server, and not some obscure Mail.app pref like font size, there may be API you can use.  After all, the UI for such things used to be in System Preferences.

    In the old days, I'd have suggested the Internet Config APIs (see InternetConfig.h).  Indeed there is a kICSMTPHost constant there.  God knows if it still works, especially in App Sandbox.  Maybe Launch Services has an API to get the smtp server?

    --
    ____________________________________________________________
    Sean McBride, B. Eng                <sean...>
    Rogue Research                        www.rogue-research.com
    Mac Software Developer              Montréal, Québec, Canada
  • On Aug 2, 2012, at 9:01 AM, Sean McBride <sean...> wrote:

    > On Thu, 2 Aug 2012 08:47:27 -0400, Rob McBroom said:
    >
    >> So maybe you can’t read the prefs from a sandboxed application?
    >
    > That would seem to fit with the whole idea of a sandbox, wouldn't it?

    The point is that *Mail* is the sandboxed app here. It's not unreasonable to expect that an un-sandboxed app could access its prefs just like defaults(1).

    I'd file an enhancement request at http://bugreport.apple.com.

    --Kyle Sluder
  • On 2 Aug 2012, at 13:47, Rob McBroom <mailinglist0...> wrote:

    > On Aug 2, 2012, at 3:07 AM, Shane Stanley <sstanley...> wrote:
    >
    >> On 01/08/2012, at 1:07 AM, Rob McBroom <mailinglist0...> wrote:
    >>
    >>> Mail is, but so is TextEdit and I have no problem reading its prefs.
    >>
    >> Are you sure you have no problem with TextEdit? It looks like when Mail moves its prefs to its container it deletes the old file, but TextEdit leaves its old one there. You may well be reading a pre-update TextEdit prefs file.
    >
    >
    > I was all ready to say “Yes, I’m sure”, but the app isn’t actually reading TextEdit’s prefs. It’s asking for com.apple.TextEdit.LSSharedFileList. Reading the actual preferences doesn’t seem to work.
    >
    > So maybe you can’t read the prefs from a sandboxed application? But that isn’t documented anywhere that I can find.

    Correct, sandboxed apps live in their own container, with their own preferences file. There is a temporary entitlement:

    com.apple.security.temporary-exception.shared-preference.read-only

    Use that as the key, and the bundle identifier of an app as the value. This will allow a sandboxed app to read another app's preferences. I don't know if the reverse applies though, having not had a need to try it.
  • On Aug 2, 2012, at 5:19 AM, Rob McBroom <mailinglist0...> wrote:

    > And I question whether Scripting Bridge is “more supported” than `NSUserDefaults`. :-)

    Those are both supported APIs, but that's irrelevant. The point is that an application's scripting API (as declared in its dictionary) is supported, whereas apps' user defaults keys are for internal use only.

    (I do know of a couple of user-defaults domains that have well-known supported keys in them — such as the ones that give the locations of the iLife media index files — but those are separate domains containing only those settings, not the internal domains of the iLife apps.)

    —Jens
  • Would it not be more in keeping with sandbox culture to ask the user for permission to read the Mail.app preferences at run time? Thereby obviating the need to maintain a supported under the hood path to the same info.  It could be a single request made once during first run.

    ~ Erik

    Sent from my iPad

    On 2012-08-02, at 12:17 PM, Jens Alfke <jens...> wrote:

    >
    > On Aug 2, 2012, at 5:19 AM, Rob McBroom <mailinglist0...> wrote:
    >
    >> And I question whether Scripting Bridge is “more supported” than `NSUserDefaults`. :-)
    >
    > Those are both supported APIs, but that's irrelevant. The point is that an application's scripting API (as declared in its dictionary) is supported, whereas apps' user defaults keys are for internal use only.
    >
    > (I do know of a couple of user-defaults domains that have well-known supported keys in them — such as the ones that give the locations of the iLife media index files — but those are separate domains containing only those settings, not the internal domains of the iLife apps.)
    >
    > —Jens
  • On Jul 31, 2012, at 10:07 AM, Rob McBroom <mailinglist0...> wrote:

    > Hello. I’m trying to read Mail’s preferences to find a suitable SMTP server so users don’t have to re-enter such configuration details. It seems to have stopped working and I can’t find a [documented] reason.
    >
    > I’ve tried
    >
    > NSUserDefaults *mailPrefs = [[NSUserDefaults alloc] init];
    > NSArray *smtpList = [[mailPrefs persistentDomainForName:@"com.apple.mail"] objectForKey:@"DeliveryAccounts"];
    >
    > and
    >
    > NSArray *mailPrefs = (__bridge NSArray *)CFPreferencesCopyValue((CFStringRef)@"DeliveryAccounts", (CFStringRef)@"com.apple.mail", kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
    >
    > but neither return any results on a 10.8 system. My application is not sandboxed. Mail is, but so is TextEdit and I have no problem reading its prefs.
    >
    > Any ideas? Thanks.

    This is obviously non-ideal, but in the absence of a better solution, you could use the /usr/bin/defaults program. I just tried it, and it appears to be able to read and write from Mail's defaults domain successfully.

    Charles
  • Sorry to revive an old thread. I've been out on vacation.

    To clarify, my application is *not* sandboxed. The application who's prefs I'm interested in (Mail) is. The question is: Should that matter? Documentation says "no". Trial and error says "yes". Since no one seems to know, I guess I'll file a bug and see what happens.

    On Aug 2, 2012, at 4:46 PM, Charles Srstka <cocoadev...> wrote:

    > This is obviously non-ideal, but in the absence of a better solution, you could use the /usr/bin/defaults program. I just tried it, and it appears to be able to read and write from Mail's defaults domain successfully.

    Yes, it does. And wouldn't you assume it uses the NSUserDefaults class for that? But apparently not.

    For now, I'm just using `dictionaryWithContentsOfFile:`, which is also non-ideal, but it works.

    --
    Rob McBroom
    <http://www.skurfer.com/>
previous month july 2012 next month
MTWTFSS
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          
Go to today