Re: A Mac App & helper NSStatusItem - how to share preferences

2009-02-11 Thread Michael Ash
On Wed, Feb 11, 2009 at 5:55 AM, Trygve Inda  wrote:
> In my helper app I use:
>
> userDefaults =
> [[NSUserDefaults standardUserDefaults]
> persistentDomainForName:kMainAppIdent];
>
> You just need to make sure there is no chance of the helper and the host
> writing at the same time to the same file.

Actually there is no such need. The user defaults system is smart
about synchronizing simultaneous changes from multiple processes, and
will do the right thing if both of your processes should hit the file
at the same time.

Mike
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: A Mac App & helper NSStatusItem - how to share preferences

2009-02-11 Thread Trygve Inda
> Steve Cronin (steve_cro...@mac.com) on 2008-12-28 8:41 PM said:
> 
>> I have an application which will have an optional helper NSStatusItem.
>> The statusItem is a stand-alone application which can be installed as
>> a LoginItem.
>> 
>> I want this status item to be able to read the preferences file from
>> the application.
> 
> No need to drop to CFPreferences.  Let's say your 2 bundle identifiers
> are "com.cronin.mainapp" and "com.cronin.helper".
> 
> In your helper app, just do this:
> 
> NSUserDefaults* sud = [NSUserDefaults standardUserDefaults];
> [sud addSuiteNamed:@"com.cronin.mainapp"];
> 
> Sean

In my helper app I use:

userDefaults =
[[NSUserDefaults standardUserDefaults]
persistentDomainForName:kMainAppIdent];

You just need to make sure there is no chance of the helper and the host
writing at the same time to the same file.

Trygve


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: A Mac App & helper NSStatusItem - how to share preferences

2008-12-31 Thread Michael Ash
On Tue, Dec 30, 2008 at 8:18 PM, Steve Cronin  wrote:
> Michael;
>
> OK to really perhaps beat the poor horse,  is the following kosher?
>
>  (NSDictionary *) prefDictionary {
>return [(NSDictionary *)CFPreferencesCopyMultiple(NULL,  appBundleID,
>  kCFPreferencesCurrentUser,  kCFPreferencesCurrentHost) autorelease];
> }

Yep, that's fine (as long as you're not using garbage collection) and
also pretty. Well, as pretty as CF code gets, anyway.

Mike
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: A Mac App & helper NSStatusItem - how to share preferences

2008-12-31 Thread Sean McBride
Steve Cronin (steve_cro...@mac.com) on 2008-12-28 8:41 PM said:

>I have an application which will have an optional helper NSStatusItem.
>The statusItem is a stand-alone application which can be installed as
>a LoginItem.
>
>I want this status item to be able to read the preferences file from
>the application.

No need to drop to CFPreferences.  Let's say your 2 bundle identifiers
are "com.cronin.mainapp" and "com.cronin.helper".

In your helper app, just do this:

NSUserDefaults* sud = [NSUserDefaults standardUserDefaults];
[sud addSuiteNamed:@"com.cronin.mainapp"];

Sean


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: A Mac App & helper NSStatusItem - how to share preferences

2008-12-30 Thread Steve Cronin

Michael;

OK to really perhaps beat the poor horse,  is the following kosher?

 (NSDictionary *) prefDictionary {
	return [(NSDictionary *)CFPreferencesCopyMultiple(NULL,   
appBundleID,  kCFPreferencesCurrentUser,  kCFPreferencesCurrentHost)  
autorelease];

}

Steve


Michael said:
Yep, this fixes the leak. Your Copy is balanced with a Release and all  
is well.


However, just to be really nitpicky, I'll point out that it's a bit
ugly. You build a new dictionary from the old one, then throw the old
one away. Better to just keep the old one around with something like
this:

return [(id)prefs autorelease];

Or if you're in a garbage collected environment:

return NSMakeCollectable(prefs);

(And you can do both if you're writing dual-mode code.)

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: A Mac App & helper NSStatusItem - how to share preferences

2008-12-30 Thread Michael Ash
On Tue, Dec 30, 2008 at 4:14 PM, Steve Cronin  wrote:
> Michael - So does the revised code below fix the leak?
>
> After a bit more studying of the documentation, I offer these revised 'more
> Cocoa-friendly' updates:
>
> The driving issue is a helper app which wants to access prefs written by the
> 'motherApp'.
>
> - (NSDictionary *) prefDictionary {
>CFStringRef appBundleID = (CFStringRef)motherAppBundleID;
>//Core Foundation 'create rule' sez I own this -> I must dispose of
> it  (because 'copy' or 'create' in CF method name)
>CFDictionaryRef prefs = CFPreferencesCopyMultiple(NULL,  appBundleID,
>  kCFPreferencesCurrentUser,  kCFPreferencesCurrentHost);
>//cast it into an auto-released Cocoa object
>NSDictionary *result = [NSDictionary
> dictionaryWithDictionary:(NSDictionary *)prefs];
>//take care of the low-level memory issue
>CFRelease(prefs);
>return result;
> }

Yep, this fixes the leak. Your Copy is balanced with a Release and all is well.

However, just to be really nitpicky, I'll point out that it's a bit
ugly. You build a new dictionary from the old one, then throw the old
one away. Better to just keep the old one around with something like
this:

return [(id)prefs autorelease];

Or if you're in a garbage collected environment:

return NSMakeCollectable(prefs);

(And you can do both if you're writing dual-mode code.)

Mike
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: A Mac App & helper NSStatusItem - how to share preferences

2008-12-30 Thread Steve Cronin

Michael - So does the revised code below fix the leak?

After a bit more studying of the documentation, I offer these revised  
'more Cocoa-friendly' updates:


The driving issue is a helper app which wants to access prefs written  
by the 'motherApp'.


- (NSDictionary *) prefDictionary {
CFStringRef appBundleID = (CFStringRef)motherAppBundleID;
	//Core Foundation 'create rule' sez I own this -> I must dispose of  
it  (because 'copy' or 'create' in CF method name)
	CFDictionaryRef prefs = CFPreferencesCopyMultiple(NULL,   
appBundleID,  kCFPreferencesCurrentUser,  kCFPreferencesCurrentHost);

//cast it into an auto-released Cocoa object
	NSDictionary *result = [NSDictionary dictionaryWithDictionary: 
(NSDictionary *)prefs];

//take care of the low-level memory issue
CFRelease(prefs);
return result;
}
It also may be worth pointing out that this dictionary only gets the  
values from the permanent store.
So any registered defaults which the user has never changed do NOT  
show up in this dictionary.


Now instead of using the low-level API to obtain individual values  
simply access key-value pairs using the NSDictionary returned above.
This avoids having to write any further code to read motherApp's  
preferences.
There are some stern words in the docs that weigh against  
indiscriminate accessing using the low-level stuff, so just get the  
dictionary and be done with it!


Now if helper MUST update a motherApp preference:
- (void) setPrefValue:(id)preferenceValue forKey:(NSString  
*)preferenceKey {

CFStringRef appBundleID = (CFStringRef)motherAppBundleID;
	CFPreferencesSetValue((CFStringRef)preferenceKey,   
(CFPropertyListRef)preferenceValue,  appBundleID,   
kCFPreferencesCurrentUser,  kCFPreferencesCurrentHost);	


	// as Jean-Daniel noted the line below is expensive and to be used  
only as required

//that being said - it ain't on the disk until its on the disk
	CFPreferencesSynchronize(appBundleID, kCFPreferencesCurrentUser,  
kCFPreferencesCurrentHost);

}

NOTE: There is a CFPreferencesSetMultiple which allows for setting a  
dictionary's worth of keys at once as well as specifying an array of  
keys to be removed.
You still have to use CSPreferencesSynchronize if you want to get it  
written


I hope this is useful.
Steve

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: A Mac App & helper NSStatusItem - how to share preferences

2008-12-30 Thread Jean-Daniel Dupas


Le 30 déc. 08 à 14:37, Michael Ash a écrit :

On Mon, Dec 29, 2008 at 4:16 AM, Steve Cronin   
wrote:

Kyle;

Thanks for that pointer!  Based on the documentation you cited I've  
now got

the reading of NSUserDefaults functioning!

In the hopes that it might be useful to someone else, I include  
these 'Cocoa

friendly' methods.
I grant that there are some improvements which could be made, I  
include them

here in the spirit of helpfulness to the community
// myBundleID is a static string defined elsewhere

//retrieves the full user defaults dictionary
- (NSDictionary *) prefDictionary {
  CFStringRef appBundleID = (CFStringRef)myBundleID;
  return (NSDictionary *)CFPreferencesCopyMultiple(NULL,   
appBundleID,

kCFPreferencesCurrentUser,  kCFPreferencesAnyHost);
}


Note that this returns a retained object and thus violates Cocoa
memory management guidelines. This is OK if the code calling it knows
this and releases it, but since it probably doesn't then this will
cause a leak every time it's called. And it's much better to fix this
up to autorelease the dictionary when returning it than to patch up
the caller to do so.

//retrieves the string Value of a key  [full implementation of all  
the

CFPropertyList types is left as an exercise for the reader)
- (NSString *) prefStringValueforKey:(NSString *)preferenceKey {
  CFStringRef appBundleID = (CFStringRef)myBundleID;
  return  
(NSString*)CFPreferencesCopyValue((CFStringRef)preferenceKey,

appBundleID,  kCFPreferencesCurrentUser,  kCFPreferencesAnyHost);
}


Rather than a full implementation of all the types, why not just a
single method which returns id?

Note that you get no real type safety here because the cast to
NSString* will succeed even if the actual value is a number,
dictionary, array, or date.


//sets the value for a key
- (void) setPrefValue:(id)preferenceValue forKey:(NSString  
*)preferenceKey {

  CFStringRef appBundleID = (CFStringRef)myBundleID;
  CFPreferencesSetValue((CFStringRef)preferenceKey,
(CFPropertyListRef)preferenceValue,  appBundleID,
kCFPreferencesCurrentUser,  kCFPreferencesAnyHost);
  CFPreferencesSynchronize(appBundleID,  
kCFPreferencesCurrentUser,

kCFPreferencesAnyHost);
}



No comment here!


Just a little comment here (from the Preferences Best Practices)

- Only synchronize when absolutely necessary

You may have a valid reason to sync at each write, but have a look at  
the "Synchronizing Preferences Across Process Boundaries" section for  
more infos.


http://developer.apple.com/documentation/CoreFoundation/Conceptual/CFPreferences/Concepts/BestPractices.html


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: A Mac App & helper NSStatusItem - how to share preferences

2008-12-30 Thread Michael Ash
On Mon, Dec 29, 2008 at 4:16 AM, Steve Cronin  wrote:
> Kyle;
>
> Thanks for that pointer!  Based on the documentation you cited I've now got
> the reading of NSUserDefaults functioning!
>
> In the hopes that it might be useful to someone else, I include these 'Cocoa
> friendly' methods.
> I grant that there are some improvements which could be made, I include them
> here in the spirit of helpfulness to the community
> // myBundleID is a static string defined elsewhere
>
> //retrieves the full user defaults dictionary
> - (NSDictionary *) prefDictionary {
>CFStringRef appBundleID = (CFStringRef)myBundleID;
>return (NSDictionary *)CFPreferencesCopyMultiple(NULL,  appBundleID,
>  kCFPreferencesCurrentUser,  kCFPreferencesAnyHost);
> }

Note that this returns a retained object and thus violates Cocoa
memory management guidelines. This is OK if the code calling it knows
this and releases it, but since it probably doesn't then this will
cause a leak every time it's called. And it's much better to fix this
up to autorelease the dictionary when returning it than to patch up
the caller to do so.

> //retrieves the string Value of a key  [full implementation of all the
> CFPropertyList types is left as an exercise for the reader)
> - (NSString *) prefStringValueforKey:(NSString *)preferenceKey {
>CFStringRef appBundleID = (CFStringRef)myBundleID;
>return (NSString*)CFPreferencesCopyValue((CFStringRef)preferenceKey,
>  appBundleID,  kCFPreferencesCurrentUser,  kCFPreferencesAnyHost);
> }

Rather than a full implementation of all the types, why not just a
single method which returns id?

Note that you get no real type safety here because the cast to
NSString* will succeed even if the actual value is a number,
dictionary, array, or date.

> //sets the value for a key
> - (void) setPrefValue:(id)preferenceValue forKey:(NSString *)preferenceKey {
>CFStringRef appBundleID = (CFStringRef)myBundleID;
>CFPreferencesSetValue((CFStringRef)preferenceKey,
>  (CFPropertyListRef)preferenceValue,  appBundleID,
>  kCFPreferencesCurrentUser,  kCFPreferencesAnyHost);
>CFPreferencesSynchronize(appBundleID, kCFPreferencesCurrentUser,
> kCFPreferencesAnyHost);
> }

No comment here!

Mike
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: A Mac App & helper NSStatusItem - how to share preferences

2008-12-29 Thread Steve Cronin

Kyle;

Thanks for that pointer!  Based on the documentation you cited I've  
now got the reading of NSUserDefaults functioning!


In the hopes that it might be useful to someone else, I include these  
'Cocoa friendly' methods.
I grant that there are some improvements which could be made, I  
include them here in the spirit of helpfulness to the community

// myBundleID is a static string defined elsewhere

//retrieves the full user defaults dictionary
- (NSDictionary *) prefDictionary {
CFStringRef appBundleID = (CFStringRef)myBundleID;
	return (NSDictionary *)CFPreferencesCopyMultiple(NULL,  appBundleID,   
kCFPreferencesCurrentUser,  kCFPreferencesAnyHost);

}

//retrieves the string Value of a key  [full implementation of all the  
CFPropertyList types is left as an exercise for the reader)

- (NSString *) prefStringValueforKey:(NSString *)preferenceKey {
CFStringRef appBundleID = (CFStringRef)myBundleID;
	return (NSString*)CFPreferencesCopyValue((CFStringRef)preferenceKey,   
appBundleID,  kCFPreferencesCurrentUser,  kCFPreferencesAnyHost);	

}

//sets the value for a key
- (void) setPrefValue:(id)preferenceValue forKey:(NSString  
*)preferenceKey {

CFStringRef appBundleID = (CFStringRef)myBundleID;
	CFPreferencesSetValue((CFStringRef)preferenceKey,   
(CFPropertyListRef)preferenceValue,  appBundleID,   
kCFPreferencesCurrentUser,  kCFPreferencesAnyHost);	
	CFPreferencesSynchronize(appBundleID, kCFPreferencesCurrentUser,  
kCFPreferencesAnyHost);

}


Steve

On Dec 28, 2008, at 8:17 PM, Kyle Sluder wrote:

On Sun, Dec 28, 2008 at 8:41 PM, Steve Cronin   
wrote:
This not a managed environment nor is this issue related to users  
or hosts,

so it doesn't seem that CFPreferences is called for (or even helps!)


In fact, CFPreferences is exactly what you need.  Apple has some
sample code describing how to do exactly what you want:
http://developer.apple.com/documentation/CoreFOundation/Conceptual/CFPreferences/Tasks/UsingLowAPI.html#/ 
/apple_ref/doc/uid/20001170


--Kyle Sluder


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: A Mac App & helper NSStatusItem - how to share preferences

2008-12-28 Thread Kyle Sluder
On Sun, Dec 28, 2008 at 8:41 PM, Steve Cronin  wrote:
> This not a managed environment nor is this issue related to users or hosts,
> so it doesn't seem that CFPreferences is called for (or even helps!)

In fact, CFPreferences is exactly what you need.  Apple has some
sample code describing how to do exactly what you want:
http://developer.apple.com/documentation/CoreFOundation/Conceptual/CFPreferences/Tasks/UsingLowAPI.html#//apple_ref/doc/uid/20001170

--Kyle Sluder
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


A Mac App & helper NSStatusItem - how to share preferences

2008-12-28 Thread Steve Cronin

Folks;

I have an application which will have an optional helper NSStatusItem.
The statusItem is a stand-alone application which can be installed as  
a LoginItem.


I want this status item to be able to read the preferences file from  
the application.
The user sets a number of preferences in the normal app which  
influence both how the app and the status item should behave.


I'm under the clear impression that I should not use the same  
bundleIdentifer for the application and the statusItem.

They could both be running at the same time...
Yet the bundleIdentifier seems to be the key to the file that  
[NSUserDefaults sharedDefaults] opens..


This not a managed environment nor is this issue related to users or  
hosts, so it doesn't seem that CFPreferences is called for (or even  
helps!)


How can I get the statusItem to read the application's preferences?

Thanks!
Steve

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com