Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

BollywooD

macrumors 6502
Original poster
Apr 27, 2005
372
46
Hamburg
I am building a plugin, and have saved some strings to userdefaults (from a NSTableView) like so:

Code:
NSArray * myArray = [self myArrayController];
[[MyPreferences userDefaults] setObject: myArray forKey:aKey];
[[MyPreferences userDefaults] synchronize];

which works great.

I would like to reload the strings back into my ArrayController on launching my app. I tried the following function, but It doesnt work?

Code:
- (void) awakeFromNib
{
NSArray * myArray = [[MyPreferences userDefaults] objectForKey:aKey];
[myArrayController setContent:myArray];
}


I also have another question: I would like to update my defaults each time the table is altered. is there an NSNotification I can use to monitor when the NSTableView is altered?

thanks, in advance
 

kainjow

Moderator emeritus
Jun 15, 2000
7,958
7
This is probably the same underlining bug as in the other thread with loading the tab state. Can you post your custom preferences class? Most likely the bug is in there.
 

BollywooD

macrumors 6502
Original poster
Apr 27, 2005
372
46
Hamburg
This is probably the same underlining bug as in the other thread with loading the tab state. Can you post your custom preferences class? Most likely the bug is in there.

heres the class, SCPreferences:
Code:
@implementation SCPreferences

+ sharedPreferences {
	static BOOL	preferencesAdded = NO;
	id preferences = [super sharedPreferences];
	
	if (preferences != nil && !preferencesAdded) {
		[preferences addPreferenceNamed:@"Cookies" owner:[SCPreferencesModule sharedInstance]];
		preferencesAdded = YES;
	}
	
	return preferences;
}

+ (void) setupUserDefaults
{
	NSUserDefaults * ud = [[BundleUserDefaults alloc] initWithPersistentDomainName:SCPreferencesDomainNameKey];
	
	[[NSUserDefaultsController sharedUserDefaultsController] _setDefaults:ud];
	
	NSDictionary * appDefaults = [NSDictionary dictionaryWithObjectsAndKeys:
								  [NSNumber numberWithInt:SCCookieAcceptPolicySafariBehavior], SCPreferencesCookieAcceptPolicy,
								  nil];
	[ud registerDefaults:appDefaults];
	//	[[NSUserDefaultsController sharedUserDefaultsController] setInitialValues:appDefaults];
	
	[ud release];
}


+ (NSUserDefaults *) userDefaults
{
	return [[NSUserDefaultsController sharedUserDefaultsController] defaults];
}

@end
 

BollywooD

macrumors 6502
Original poster
Apr 27, 2005
372
46
Hamburg
OK, I got the tabstate saving/reloading by:
calling the function elsewhere in the code ... I dont think the tabView had initialized, when i was calling the function.

I have tried moving the ArrayController setContent function elsewhere, but all it does, is crash the plugin?
:confused:
 

kainjow

Moderator emeritus
Jun 15, 2000
7,958
7
I would do one of two things: use the normal [NSUserDefaults standardUserDefaults] and just give your preference keys a prefix unique to your app (e.g. SC__SomeValue) so that you don't conflict with Safari, or rewrite your class to use the CFPreferences API which can read/write from different domains without using private methods.
 

BollywooD

macrumors 6502
Original poster
Apr 27, 2005
372
46
Hamburg
I figured out the problem....

Duh....

I was storing the array as NSStrings, and trying to read back into the ArrayController, as strings. as soon as i changed it back to saving as an array of NSDictionary items - everything worked as expected.

for simplicity though, I would like to keep the array, stored, as an array of NSStrings.
which leads me to my next question, how do I convert an array of NSStrings, into an array of NSDictionary items?

i have found this method:
propertyListFromStringsFileFormat

but are not exactly sure how to convert an entire array?
:confused:
 

kainjow

Moderator emeritus
Jun 15, 2000
7,958
7
Well you will have to decide what 'key' is for each item, but something like this:
Code:
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
for (NSString *str in array)
    [dict setObject:str forKey:key];
 

BollywooD

macrumors 6502
Original poster
Apr 27, 2005
372
46
Hamburg
Well you will have to decide what 'key' is for each item, but something like this:
Code:
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
for (NSString *str in array)
    [dict setObject:str forKey:key];

this converts fine, but I can only save multiple instances of the last entered domain?

heres the code im using:
Code:
- (NSArray *) convertStringsToDictionary
{	
	NSArray * blacklist = [[SCPreferences userDefaults] objectForKey:SCPreferencesKey];
	NSMutableDictionary *dict = [NSMutableDictionary dictionary];
	NSMutableArray * blacklistDomains = [NSMutableArray array];
	NSEnumerator * enumerator = [blacklist objectEnumerator];
	id node;
	while ((node = [enumerator nextObject]))
	{
		for (NSString *str in blacklist)
			[dict setObject:str forKey:@"blacklist"];
		[blacklistDomains addObject:dict];
	}
	return blacklistDomains;
}
 

kainjow

Moderator emeritus
Jun 15, 2000
7,958
7
Not sure what you're trying to do there, but you're looping through the entire array every time you loop through it with the enumerator. Either use the enumerator, or use the for loop, but not both.

The for loop is basically a better version of the enumerator and only is available in 10.5+, so you should use that whenever you can instead of the enumerator because it's faster and requires less code. But know that they both do the same thing, just different implementations.
 

BollywooD

macrumors 6502
Original poster
Apr 27, 2005
372
46
Hamburg
:eek:
I am now using the following code.
if for example i have 4 strings, in my array, this code returns an array of 4 dictionary items (but the last entered string - 4X)?

am i doing something wrong?

Code:
- (NSArray *) convertStringsToDictionary
{	
	NSArray * blacklist = [[SCPreferences userDefaults] objectForKey:SCPreferencesBlacklistDomainsKey];
	NSMutableDictionary *dict = [NSMutableDictionary dictionary];
	NSMutableArray * blacklistDomains = [NSMutableArray array];
	for (NSString *str in blacklist)
	{
		[dict setObject:str forKey:@"blacklist"];
		[blacklistDomains addObject:dict];
	}
	return blacklistDomains;
}
 

kainjow

Moderator emeritus
Jun 15, 2000
7,958
7
Your code is adding the same dictionary multiple times into the array, and each time is overwriting the previous blacklist object.

Are you trying to create an array of dictionaries, with each dictionary containing one key/value pair? If so, maybe this is what you want:

Code:
- (NSArray *) convertStringsToDictionary
{	
	NSArray * blacklist = [[SCPreferences userDefaults] objectForKey:SCPreferencesBlacklistDomainsKey];
	NSMutableArray * blacklistDomains = [NSMutableArray array];
	for (NSString *str in blacklist)
	{
		NSDictionary *dict = [NSDictionary dictionaryWithObject:str forKey:@"blacklist"];
		[blacklistDomains addObject:dict];
	}
	return blacklistDomains;
}
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.