I'm new to iOS development and am having trouble writing an array of dictionary objects to a file.
Here's my code... and what I think it should do below:
// Step 1. Copy the plist in the App bundle and create one in the Documents directory
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"Devices.plist"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath: path])
{
NSString *bundle = [[NSBundle mainBundle] pathForResource:@"Devices" ofType:@"plist"];
[fileManager copyItemAtPath:bundle toPath: path error:&error];
}
// Step 2). Read my plist into a number of internal arrays.
NSArray *rootArray = [NSArray arrayWithContentsOfFile:path];
nameArray = [[NSMutableArray alloc] init];
MACArray = [[NSMutableArray alloc] init];
imageArray = [[NSMutableArray alloc] init];
blockArray = [[NSMutableArray alloc] init];
synchronisedArray = [[NSMutableArray alloc] init];
for (NSDictionary *itemData in rootArray)
{
[nameArray addObject:[itemData objectForKey:@"name"]];
[MACArray addObject:[itemData objectForKey:@"MAC"]];
[imageArray addObject:[itemData objectForKey:@"image"]];
[blockArray addObject:[itemData objectForKey:@"block"]];
[synchronisedArray addObject:[itemData objectForKey:@"synchronised"]];
}
// Step 3. Load my internal arrays into an array of dictionaries.
NSMutableDictionary *outData = [[NSMutableDictionary alloc] init];
NSMutableArray *outArray = [[NSMutableArray alloc] init];
for (int i = 0; i<[nameArray count]; i++)
{
[outData removeAllObjects];
[outData setValue:[nameArray objectAtIndex:i] forKey:@"name"];
[outData setValue:[MACArray objectAtIndex:i] forKey:@"MAC"];
[outData setValue:[imageArray objectAtIndex:i] forKey:@"image"];
[outData setValue:[blockArray objectAtIndex:i] forKey:@"block"];
[outData setValue:[synchronisedArray objectAtIndex:i] forKey:@"synchronised"];
[outArray addObject: outData];
NSLog(@"Last object in outArray at %i is %@", i, [outArray objectAtIndex:i]);
NSLog(@"---------------------------");
}
// Step 4). Write the array back out to the plist.
BOOL result = [outArray writeToFile: path atomically:YES];
if (result)
NSLog(@"Result YES");
else
NSLog(@"Result NO");
Explanation:
1). Read in a plist from the App bundle, and copy it to the Documents directly (so that I can write to it later).
2). Read in the newly create plist, and load it into a number of NSMutableArray objects.
... Main program code it here (omitted for this example).
3). Read the internal arrays and create NSDictionary objects, add each one to an NSMutableArray (outArray).
4). Write the outArray to the plist.
This all works fine except for the last step. When I view the plist there are 3 entries as expected... but... they are all the same. They are copies of the last entry in outArray.
Here's the NSLog output:
2014-07-27 09:19:29.533 Filter[7143:60b] Last object in outArray at 0 is {
MAC = "00:26:B0:CF:48:32";
block = 0;
image = "laptop-50";
name = Laptop;
synchronised = 1;
}
2014-07-27 09:19:29.537 Filter[7143:60b] ---------------------------
2014-07-27 09:19:29.539 Filter[7143:60b] Last object in outArray at 1 is {
MAC = "00:26:B0:CF:48:32";
block = 0;
image = "joystick-50";
name = PS3;
synchronised = 0;
}
2014-07-27 09:19:29.540 Filter[7143:60b] ---------------------------
2014-07-27 09:19:29.541 Filter[7143:60b] Last object in outArray at 2 is {
MAC = "B8:FF:61:09:BC:EE";
block = 1;
image = "ipad_copyrighted-50";
name = "Logan's iPad";
synchronised = 1;
}
2014-07-27 09:19:29.542 Filter[7143:60b] ---------------------------
2014-07-27 09:19:29.593 Filter[7143:60b] Result YES
Appreciate any help/advice... thanks.
As you are writing your existing key are overridden by new values.Replace the above code with this one
// Step 3. Load my internal arrays into an array of dictionaries.
NSMutableArray *outArray = [[NSMutableArray alloc] init];
for (int i = 0; i<[nameArray count]; i++)
{
NSMutableDictionary *outData = [[NSMutableDictionary alloc] init]; //add this line here
[outData setValue:[nameArray objectAtIndex:i] forKey:@"name"];
[outData setValue:[MACArray objectAtIndex:i] forKey:@"MAC"];
[outData setValue:[imageArray objectAtIndex:i] forKey:@"image"];
[outData setValue:[blockArray objectAtIndex:i] forKey:@"block"];
[outData setValue:[synchronisedArray objectAtIndex:i] forKey:@"synchronised"];
[outArray addObject: outData];
NSLog(@"Last object in outArray at %i is %@", i, [outArray objectAtIndex:i]);
NSLog(@"---------------------------");
}