Create a new plist from the existing plist? - ios

I have a plist like in the below first image ,thats my main plist and in that the field "bid" is unique . i have the value of bid (for example bid=90) then i need to search the value in all entries of my main (first image)plist and create a new plist& retrieve the corresponding values(bid,description,category,rating) belongs to that plist .How can i do this?
EDIT
if i have multiple values with me like bid =88 and another bid=90 then i have to create a new plist from the main plist (as shown in first image) then the result should be like image 3

NSString *path = [[NSBundle mainBundle] pathForResource:#"mainPlistFile" ofType:#"plist"];
//path has path for main plist.
NSDictionary *dictionary=[NSDictionary dictionaryWithContentOfFile: path];
NSArray *listbook = [dictionary objectForKey:#"listbook"];
for (NSDictionary *item in listbook) {
if ([[item objectForKey:#"bid"] isEqualToString yourNSStringWithBidToSearch]) {
//now item is the desired dictionary, you can get values by using objectForKey
//or write it to a file like below.
[item writeToFile:pathToSaveNewPlist automatically:NO];
break;
}
}
Remember you will have to first create the NSString pathToSaveNewPlist and yourNSStringWithBidToSearch, I'll leave that to you.
So you edited the question :
Lets assume you have an NSArray bidsToSearch which has NSStrings of the bid values to be searched :
NSMutableArray *targetListbook = [[NSMutableArrray alloc] init]];
NSDictionary *dictionary=[NSDictionary dictionaryWithContentOfFile:[[NSBundle mainBundle] pathForResource:#"mainPlistFile" ofType:#"plist"]];
for (NSDictionary *item in [dictionary objectForKey:#"listbook"])
if ([bidsToSearch containsObject:[item objectForKey:#"bid"]])
[targetListbook addObject:item];
[#{listbook:targetListbook} writeToFile:pathToSaveNewPlist automatically:NO];

You can use NSPropertyListSerialization class to serialize and deserialize property lists.
EDIT: below is some pseudo code for how to do it.
NSData* data = [NSData dataWithContentsOfFile:plistFile]; // read file
id plist = [NSPropertyListSerialization propertyListWithData:data ...]; // deserialize
// do your work
data = [NSPropertyListSerialization dataWithPropertyList:plist2 ...]; // serialize
[data writeToFile:plistFile2 ...]; // write to file

Related

iOS - extracting data from a plist not working

This is a routine exercise. I have done it a number of times in my current project and it has worked fine. I copied the code line for line, same initializations. My plist data goes into a dictionary but then it does not go into its respective arrays in their initializations. I have a method called initArraysPlist
-(void)initArraysPlist{
NSString *path1 = [[NSBundle mainBundle] pathForResource:#"trainerProfile" ofType:#"plist"];
// Load the file content and read the data into arrays
NSDictionary *dict1 = [[NSDictionary alloc] initWithContentsOfFile:path1];
trainerNames = [dict1 objectForKey:#"Names"];
trainerIcons = [dict1 objectForKey:#"Icons"];
trainerFactSheet= [dict1 objectForKey:#"Fact Sheet"];
trainerFocus = [dict1 objectForKey:#"Focus"];
trainerContactInfo= [dict1 objectForKey:#"Contact Info"];
}
Ive done this a few times and it currently works in my code. all the values are correct. Ive checked it many times. when
Please read the comments for the each line.
NSString *path1 = [[NSBundle mainBundle] pathForResource:#"trainerProfile" ofType:#"plist"]; // **check if your plist is actually added in Bundle.If its there move to second line , if not then add plist in bundle.**
NSDictionary *dict1 = [[NSDictionary alloc] initWithContentsOfFile:path1];// **if plist is added in bundle , then check if you are getting value for dict1 . If no then you might be making some mistake in plist structure.**
For more clarifications please post your plist if possible.
Please try this code it may be helpful to you
// Read plist from bundle and get Root Dictionary out of it
NSDictionary *dictRoot = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"data" ofType:#"plist"]];
// Your dictionary contains an array of dictionary
// Now pull an Array out of it.
NSArray *arrayList = [NSArray arrayWithArray:[dictRoot objectForKey:#"catlist"]];
// Now a loop through Array to fetch single Item from catList which is Dictionary
[arrayList enumerateObjectsUsingBlock:^(id obj, NSUInteger index, BOOL *stop) {
// Fetch Single Item
// Here obj will return a dictionary
NSLog(#"Category name : %#",[obj valueForKey:#"category_name"]);
NSLog(#"Category id : %#",[obj valueForKey:#"cid"]);
}];

Lazy load plist dictionary element(s)

The usual method for loading data from a dictionary contained in a plist is as below:
NSString *path = [[NSBundle mainBundle] pathForResource:#"Data" ofType:#"plist"];
NSDictionary *data= [NSDictionary dictionaryWithContentsOfFile:path];
Is there a way to import only the element(s) specified in a key / set of keys, like:
NSDictionary *data= [NSDictionary dictionaryWithContentsOfFile:path forKey:key];
The idea is to perform lazy loading of dictionary contents by key.
So based on my comment above, you could add a class method to the NSDictionary via a category. You could do something like (not tested BTW).
+ (NSDictionary *)dictionaryWithContentsOfFile:(NSString *)path forKeys:(NSArray *)keys
{
NSMutableDictionary *newDictionary = nil;
NSDictionary *dictionary = [NSDictionary dictionaryWithContentsOfFile:path];
if (dictionary) {
newDictionary = [NSMutableDictionary dictionary];
for (id key in dictionary.allKeys) {
if ([keys containsObject:key]) {
newDictionary[key] = dictionary[key];
}
}
}
return [newDictionary copy];
}
If you did this, you'd see your spike in memory, but it should subside once dictionary is freed.
Alternatively, take a look at YAJL (https://github.com/lloyd/yajl). I've used this when dealing with very large JSON files. This was mainly the stream it in chunks. It is event driven, so you should be able to stream it in and detect the keys you want (hopefully).
please try the below method.
- (void)viewDidLoad
{
NSMutableArray *arry;
arry = [[NSMutableArray alloc]initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"Catalog" ofType:#"plist"];
NSDictionary *dic = [menuArray objectAtIndex:indexPath.row];
lblName.text = [dic objectForKey:#"MenuName"];
}

How to update the existing .plist?

How to update the existing plist with info? I have simple dictionary with strings. Here is my save method:
#define DOCUMENTS [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]
- (IBAction)saveData:(id)sender {
NSMutableDictionary *data = [NSMutableDictionarydictionaryWithObjects:#[self.textFieldOne.text, self.textFieldTwo.text, self.textFieldThree.text] forKeys:#[#"Key1", #"Key2", #"Key3"]];
NSError *error = nil;
NSData *dataToPlist = [NSPropertyListSerialization dataWithPropertyList:data format:NSPropertyListXMLFormat_v1_0 options:0 error:&error];
NSString *path = [DOCUMENTS stringByAppendingPathComponent:#"userData.plist"];
[dataToPlist writeToFile:path atomically:YES];
}
So, it's OK when I call this method from Class 1, but when I want to update this plist with other info from Class 2 – it overwrites old info with new info. What I should do to update the existing plist with new info from other classes?
You need to load the existing plist into an NSDictionary or NSArray (as appropriate), then update the data with the additional data, and finally write out the updated data to the plist file.
Basically the existing one you have to read into dictionary using dictionarywithcontentsfile method and then on the basis of your requirement use setobjecwt method into dictionary and then write to plist. So that old value will be retain there and you can updates new as well.

Creating dictionary from plist and am getting back null

I have a plist file in my project that looks like this :
and im doing this
NSURL *file = [[NSBundle mainBundle] URLForResource:#"test" withExtension:#"plist"]; //Lets get the file location
NSDictionary *plistContent = [NSDictionary dictionaryWithContentsOfURL:file];
NSLog(#"dic::%#", plistContent);
NSArray *arrayRead = [plistContent allKeys];
NSLog(#"test::%#", arrayRead);
Everything I seem to do returns (null) in my logs. Any ideas why?
Your plist root is an array, not a dictionary. Use:
NSArray *plistContent = [NSArray arrayWithContentsOfURL:file];
Of course you now have an array of dictionaries. You can't simply ask for allKeys anymore.

iPhone programming, loading plist data, access it

I have a plist in the following form:
Root (array)---> item 1 (dictionary) ----> Sch (string)
---> Name (string)
----> price (number)
----> item 2 (dictionary)----> .....same as item 1
How can I access each row (item1 to ...) and the its child (Sch, Name etc.)? One at a time?
I use:
NSString *path = [[NSBundle mainBundle] bundlePath];
NSString *finalPath = [path stringByAppendingPathComponent:#"Data.plist"];
NSDictionary *plistData = [[NSDictionary dictionaryWithContentsOfFile:finalPath] retain];
to load the file. How should I go about accessing each child?
What I am trying to do is, I have a NSString *message, what I want to do is to search the whole plist for matching string and display the whole item 1. Any suggestion?
When you initialize a collection from a plist, the type is the root level object. Therefore you would not initialize a dictionary but an array like so:
NSArray *plistData = [[NSArray arrayWithContentsOfFile:finalPath] retain];
Then you would access it like this:
NSString *sch;
NSString *name;
NSString *price;
for (NSDictionary *aDict in plistData) {
sch = [aDict objectAtKey:"Sch"];
name = [aDict objectAtKey:"Name"];
price = [aDict objectAtKey:"price"];
//.. do whatever
}
Here is a link to a discussion that provided a very good example of how to access your data and which type of storage schemes would be more beneficial under certain circumstances. #TechZen's solution is on target, I just thought this question would add an additional resource. Hope this helps!

Resources