read from .plist file - ios

Got a little problem. I have a .plist file which contain next data
So i cant understand, how i need read first array, than in array read dictionary. Or maybe need rewrite file and change Root key to type dictionary, and read like this:
NSString *errorDesc = nil;
NSPropertyListFormat format;
NSString *plistPath;
NSString *rootPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES) objectAtIndex:0];
plistPath = [rootPath stringByAppendingPathComponent:#"Data.plist"];
if (![[NSFileManager defaultManager] fileExistsAtPath:plistPath]) {
plistPath = [[NSBundle mainBundle] pathForResource:#"Data" ofType:#"plist"];
}
NSData *plistXML = [[NSFileManager defaultManager] contentsAtPath:plistPath];
NSDictionary *temp = (NSDictionary *)[NSPropertyListSerialization
propertyListFromData:plistXML
mutabilityOption:NSPropertyListMutableContainersAndLeaves
format:&format
errorDescription:&errorDesc];
if (!temp) {
NSLog(#"Error reading plist: %#, format: %d", errorDesc, format);
}
self.personName = [temp objectForKey:#"Name"];
self.phoneNumbers = [NSMutableArray arrayWithArray:[temp objectForKey:#"Phones"]];

You can do it by the following code:
NSString *plistPath = [[NSBundle mainBundle] pathForResource:#"Data" ofType:#"plist"];
NSArray *dataArray = [NSArray arrayWithContentsOfFile:plistPath];
This array will contain all the dictionaries, you can get them like:
NSDictionary *dict = [dataArray objectAtIndex:0];

SString *plistFile = [[NSBundle mainBundle] pathForResource:#"Data" ofType:#"plist"];
NSArray *array = [NSArray arrayWithContentsOfFile:plistFile];
for(NSDictionary *dictionary in array) {
NSLog(#"%#", dictionary);
}
NSDictionary *item0 = array[0];
NSString *imageName = item[0][#"name"];

Related

how to add multiple arrays in plist file programmatically in iPhone

I want to create plist file with multiple array and array as Root type.I can add multiple array in dictionary but I want to add all array in one array programmatically.How is it possible to create plist file programmatically and write array data into it.Please guide me and give some sample links.Thanks.
Here is my code to add array in dictionary :
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"Demo.plist"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath: path])
{
NSString *bundle = [[NSBundle mainBundle] pathForResource:#"Demo" ofType:#"plist"];
[fileManager copyItemAtPath:bundle toPath: path error:&error];
}
firstArray = [[NSMutableArray alloc] initWithObjects:#"15-5-123",#"15-5-12",nil];
secondArray = [[NSMutableArray alloc] initWithObjects:#"TestFiling",#"TestFiling",nil];
thirdArray = [[NSMutableArray alloc] initWithObjects:#"15132561",#"15135601", nil];
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
[dictionary setObject:firstArray forKey:#"firstArray"];
[dictionary setObject:secondArray forKey:#"secondArray"];
[dictionary setObject:thirdArray forKey:#"thirdArray"];
[dictionary writeToFile:path atomically:NO];
NSDictionary *dictionary1;
dictionary1 = [NSDictionary dictionaryWithContentsOfFile:path];
NSLog(#"dictionary1 %#",dictionary1);
this code is working fine for dictionary but i want to add arrays in array.
The first section of your code is fine, you just need to switch the second part to using an array:
NSMutableArray *array = [[NSMutableDictionary alloc] init];
[array addObject:firstArray];
[array addObject:secondArray];
[array addObject:thirdArray];
[array writeToFile:path atomically:NO];
NSArray *array1 = [NSArray arrayWithContentsOfFile:path];
NSLog(#"array1 %#", array1);

How To Read Images From NSMainBundle in iOS

I have the structure like the following in my Xcode project.
I need to read all the images from project and need to store it in array.
I have used the following code from some other StackOverflow posts, but it's not working.
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"Images"ofType:#""];
NSDirectoryEnumerator *direnum;
direnum = [fileManager enumeratorAtPath: filePath];
imageFolder = [NSMutableArray new];
for(NSString *filename in direnum){
if([[filename pathExtension] isEqualToString:#"png"]){
[imageFolder addObject:filename];
}
}
NSLog(#"Files in the folder %#",imageFolder);
I would appreciate, if any one help me to complete this.
it's simple to get all the images into a array
NSBundle *imageBundle=[NSBundle bundleWithPath: myBundlePath];
NSArray *allImageURLs=[imageBundle URLsForResourcesWithExtension:#"png" subdirectory:nil];
- (NSArray *)pathsForResourcesOfType:(NSString *)extension inDirectory:(NSString *)subpath will get you the array you want.
NSArray *imagesArray = [[NSBundle mainBundle] pathsForResourcesOfType:#"png" inDirectory:#"Images"];
You can try below
NSArray *pathArray = [[NSBundle mainBundle] pathsForResourcesOfType:#"png" inDirectory:nil];
[pathArray enumerateObjectsUsingBlock:^(NSString *pathString, NSUInteger idx, BOOL *stop) {
UIImage *yourImage = [[UIImage alloc] initWithContentsOfFile:pathString];
}];
Please use this code, hope it will work.
NSString *dirPath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:#"images"];
NSError * error;
NSArray * images = [[NSFileManager defaultManager]
contentsOfDirectoryAtPath:dirPath error:&error];

Generate plist with NSMutableDictionary

I have an issue to generate plist file from NSMutableDictionnary. It seems to doesn't work. i have watched many example on Stackoverflow. I generate Dictionary from a plist but not plist from Dictionary.
Here is my code :
NSArray *keys = [NSArray arrayWithObjects:#"id", #"name", nil];
NSArray *object = [NSArray arrayWithObjects:#"Value id", #"Value name", nil];
NSMutableDictionary *projectData = [NSDictionary dictionaryWithObject:object forKey:keys];
NSFileManager* fileManager = [NSFileManager defaultManager];
for (id key in projectData)
{
NSLog(#"projectData = key : %#, value : %#", key, [projectData objectForKey:key]);
}
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *plistPath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:#"data.plist"];
NSLog(#"%#", plistPath);
//write
[projectData writeToFile:plistPath atomically:YES];
NSMutableDictionary *newDictionnary;
//read
if ((plistPath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:#"data.plist"])) {
if ([fileManager isWritableFileAtPath:plistPath]) {
[projectData writeToFile:plistPath atomically:YES];
newDictionnary = [NSMutableDictionary dictionaryWithContentsOfFile:plistPath];
//NSLog(#"%#", plistPath);
}
}
else {
NSLog(#"File not found");
}
for (id key in newDictionnary)
{
NSLog(#"New dictionnary = key : %#, value : %#", key, [newDictionnary objectForKey:key]);
}
Thanks for help :)
One note: your paths variable is never used.
You cannot write to your bundle directory directly. You have to write either to the documents folder, the caches folder or the temp folder.
Replace [[NSBundle mainBundle] bundlePath] with paths[0].

NSArray or NSDictionary from plist file

In a method I need to read a NSArray or NSDictionary from a plist file.
Here is my problem : How can I create a NSArray OR a NSDictionary from a plist file when I don't know if it's an array or dictionary in it ?
I know I can make :
NSArray *myArray = [NSArray arrayWithContentsOfFile:filePath];
or
NSDictionary *myDico = [NSDictionary dictionaryWithContentsOfFile:filePath];
But I don't know if filePath contains a NSArray or a NSDictionary. I would like something like :
id myObject = [... ...WithContentOfFile:filePath];
Can somebody help me and give me the best way to do this ?
Here's how
NSData *data = [NSData dataWithContentsOfFile:filePath];
id obj = [NSPropertyListSerialization propertyListWithData:data options:NSPropertyListImmutable format:NULL error:nil];
if([obj isKindOfClass:[NSDictionary class]]) {
//cast obj to NSDictionary
}
else if([obj isKindOfClass:[NSArray class]]) {
//cast obj to NSArray
}
You can use isKindOfClass method to detect which class is that.
You will have to load .plist file using:
NSString *rootPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
plistPath = [rootPath stringByAppendingPathComponent:#"Data.plist"];
if (![[NSFileManager defaultManager] fileExistsAtPath:plistPath]) {
plistPath = [[NSBundle mainBundle] pathForResource:#"Data" ofType:#"plist"];
}
NSData *plistXML = [[NSFileManager defaultManager] contentsAtPath:plistPath];
id objectFromPlist = [NSPropertyListSerialization
propertyListWithData:plistXML
options:0
format:&format
errorDescription:&errorDesc];
And you can check here:
if([objectFromPlist isKindOfClass:[NSArray class]])
{
NSArray* plistArray = (NSArray*) classFromPlist;
}

writeToFile:atomically: not saving new plist data

I am using writeToFile:atomically: to update the value of a key in my plist by 1 every time the app is launched. I put this code in viewDidLoad, which reads the string value of the key, gets the numeric value of that string, increases it by 1, converts it back to a string, and writes that as the new string for that key, but when I read it again it seems to have not updated. I can't figure out what I'm doing wrong. I don't need a special framework for writeToFile:atomically:, do I?
Here is the code:
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"DaysLaunched.plist"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath: path])
{
NSString *bundle = [[NSBundle mainBundle] pathForResource:#"DaysLaunched" ofType:#"plist"];
[fileManager copyItemAtPath:bundle toPath:path error:&error];
}
NSMutableDictionary *plistDict = [[NSMutableDictionary alloc] initWithContentsOfFile: path];
NSMutableDictionary *data1 = [[NSMutableDictionary alloc] initWithContentsOfFile: path];
NSString *currentNumberOfDays = [NSString stringWithFormat:#"%#",[plistDict objectForKey:#"numberOfDays"]];
NSLog(#"currentNumberOfDays = %#", currentNumberOfDays); //0
int days = [currentNumberOfDays intValue];
days ++;
currentNumberOfDays = [NSString stringWithFormat:#"%d", days];
[data1 setObject:[NSString stringWithFormat:#"numberOfDays"] forKey:currentNumberOfDays];
NSLog(#"currentNumberOfDays = %#", currentNumberOfDays); //1
[data1 writeToFile: path atomically:YES];
currentNumberOfDays = [NSString stringWithFormat:#"%#",[plistDict objectForKey:#"numberOfDays"]];
NSLog(#"currentNumberOfDays = %#", currentNumberOfDays); //0 ??????? writeToFile isn't working?
And here is a screenshot of "DaysLaunched.plist" in my 'Supporting Files' folder, (I've also verified that the plist file name is spelled exactly the same way I spelled it in my code, via Copy-Paste)
The original plist file is also in my 'Copy Bundle Resources' in targets.
Try
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"DaysLaunched.plist"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath: path])
{
NSString *bundle = [[NSBundle mainBundle] pathForResource:#"DaysLaunched"
ofType:#"plist"];
[fileManager copyItemAtPath:bundle toPath:path error:&error];
}
NSMutableDictionary *plistDict = [NSMutableDictionary dictionaryWithContentsOfFile:path];
NSInteger days = [plistDict[#"numberOfDays"] integerValue];
plistDict[#"numberOfDays"] = [#(++days) stringValue];
[plistDict writeToFile: path atomically:YES];
You have made a mistake while setting your data.
You should do:
[data1 setObject:currentNumberOfDays forKey:#"numberOfDays"];
instead of:
[data1 setObject:[NSString stringWithFormat:#"numberOfDays"] forKey:currentNumberOfDays];

Resources