Pregunta

I'm trying to figure out the proper data structure to save a key value of 'date' => 'value'

I'm trying to use NSMutableDictionary, as it must save each time the user enters a value and presses 'save'.

However, trying to NSLog the values of the dictionary is always null.

- (IBAction)saveWeight:(id)sender
{
    NSMutableDictionary *weightLog = [[NSMutableDictionary alloc] init];
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];

    NSString *date = @"12/12/14"; 

    [weightLog setObject:self.weightInput.text forKey:date];

    NSLog(@"neweight you entered is %@", self.weightInput.text);
    NSLog(@"weightlog is %@", weightLog);

    [userDefaults setObject:weightLog forKey:@"Weightlog"];
    [userDefaults synchronize];
}

Log Output:

diet[35744:70b] neweight you entered is 13
2014-03-01 16:25:58.712 diet[35744:70b] weightlog is {
"12/12" = 13;
}
¿Fue útil?

Solución

Of course, only the last valeur is save, as you don't load the previous value in weightLog before adding the new one ! Also one more things, you should change the key for each value.

Try to use this (the date will include year + month + day + hour + minute + second, so don't click more than 1 time per second ;-D ) :

NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];

NSMutableDictionary *weightLog = [NSMutableDictionary dictionaryWithDictionary:[userDefaults objectForKey:@"Weightlog"]];


NSString *date = [NSDateFormatter localizedStringFromDate:[NSDate date]
                                                dateStyle:NSDateFormatterShortStyle
                                                timeStyle:NSDateFormatterFullStyle];

[weightLog setObject:self.weightInput.text forKey:date];

NSLog(@"neweight you entered is %@", self.weightInput.text);
NSLog(@"weightlog is %@", weightLog);

[userDefaults setObject:weightLog forKey:@"Weightlog"];
[userDefaults synchronize];

Otros consejos

Calling:

NSMutableDictionary *weightLog = [[NSMutableDictionary alloc] init];

creates a new empty dictionary which completely ignores anything you might previously have stored in user defaults. What you should do is:

NSMutableDictionary *weightLog = [[userDefaults objectForKey:@"Weightlog"] mutableCopy];

if (weightLog == nil) {
    weightLog = [[NSMutableDictionary alloc] init];
}

now weightLog is either the existing contents in a mutable form, or a new empty mutable dictionary.

Note that if you always add the same key to the dictionary then it will replace the previous one. So, in your current code you'll still only get 1 entry in the dictionary because your key (date) is hard coded...

these other two answers above are great and point out a couple flaws/misunderstandings in your design, you are always replacing with a fresh dictionary with only one entry, yes.. and even when you fix that you will be overriding the last value every time because you are setting 'object: forKey: ' and always reusing the same key...

a mutable array of values is the more logical way to go for a dynamic, growing list.. also NSNumber can be written straight to file in a collection (i.e. NSArray, NSDictionary, NSSet ) and is a far more flexible and powerful and appropriate object type than hardcoding the value into a string. You can do arithmetic operations on NSNumber, comparisons etc but also you can convert lbs to kilograms etc for different localisations..

good luck :)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top