Add Additional Keys and Values Within PropertyList Using iOS - ios

I need to add below mentioned keys and values (Image Red Marked Values) Into propertylist.
Needed Structure (need to add Red marked keys and values at same position)
Now my plist:
My Exact Scenario Below
I have created plist and Into the plist I am getting the storage
data from JSON parser.
I have one standard mediatory storage structure based on that Its
storing (I have added above Image two)
Now I need to add two boolean keys and values by
manual, Into the plist. Where and which position all the information
I have marked and mentioned by above Image one.
JSON parse to store data Into plist for that I have used below code
Below code I am using:
NSDictionary *JSON = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves | NSJSONReadingMutableContainers error:&error];
NSDictionary *response = JSON[#"response"];
NSArray *keys = [response allKeys];
NSMutableArray *objects = [NSMutableArray new];
for (NSString *key in keys) {
NSMutableDictionary *object = response[key];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"subject = %#",object[#"subject"]];
NSArray *objectsWithSameSubject = [objects filteredArrayUsingPredicate:predicate];
NSInteger subjects = [object[#"subject"] integerValue];
if (subjects > 0) {
NSMutableArray *Objects_Subjectcount = [NSMutableArray new];
[object setObject:Objects_Subjectcount forKey:#"Objects_Subjectcount"];
for (NSInteger i = 0; i < subjects; i++) {
[Objects_Subjectcount addObject:object];// object or anything you need
}
}
[objects addObject:object];
}
NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = paths.firstObject;
NSString *plistPath = [documentsPath stringByAppendingPathComponent:#"File.plist"];
NSError *writeError = nil;
NSDictionary *finalDict = #{#"Objects": objects};
NSData *plistData = [NSPropertyListSerialization dataWithPropertyList:finalDict format:NSPropertyListXMLFormat_v1_0 options:NSPropertyListImmutable error:&writeError];
if(plistData){
[plistData writeToFile:plistPath atomically:YES];
}
else {
NSLog(#"Error in saveData: %#", error);
}

Assume your existing plist is created by this code:
NSDictionary *dic = #{#"Planet":#"Earth",
#"Earth":#{#"1":#"Asia",
#"2":#"Africa"}
};
[dic writeToFile:path atomically:YES];
Then you need to insert a new key-value pair inside Earth.
//read
NSDictionary *readDict = [NSDictionary dictionaryWithContentsOfFile:path];
//create a mutable dict to edit it
NSMutableDictionary *mDict = [readDict mutableCopy];
//read the key-value for earth, and we are gonna edit it
NSMutableDictionary *earthDict = mDict[#"Earth"];
//set new object, it can be anything, string, array, dictionary etc
[earthDict setObject:#{#"myName":#"Anoop"}
forKey:#"new"];
//write it back to same file
[mDict writeToFile:path atomically:YES];
Now the plist looks like this:

Related

Need To Add New Keys and Values Into Plist Using Objective C? [duplicate]

This question already has answers here:
How To Add New Keys and Values Into Plist Using Objective C?
(1 answer)
Save NSDictionary to plist
(3 answers)
Closed 7 years ago.
I have created JSON data store Into Plist. Now the problem is after JSON data storage, I need to add two set of keys into every array of dictionary items like below Image_2.The key name isParent - Boolean YES and isChild - Boolean YES with levels like mentioned below Image_2.
Now I have below structure of plsit datas Its perfectly working by below code.
I need to add two keys for outside of object subjectcount and inside of objectsubjectcount red marked datas.
NSDictionary *JSON = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves | NSJSONReadingMutableContainers error:&error];
NSDictionary *response = JSON[#"response"];
NSArray *keys = [response allKeys];
NSMutableArray *objects = [NSMutableArray new];
for (NSString *key in keys) {
NSMutableDictionary *object = response[key];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"subject = %#",object[#"subject"]];
NSArray *objectsWithSameSubject = [objects filteredArrayUsingPredicate:predicate];
NSInteger subjects = [object[#"subject"] integerValue];
if (subjects > 0) {
NSMutableArray *Objects_Subjectcount = [NSMutableArray new];
[object setObject:Objects_Subjectcount forKey:#"Objects_Subjectcount"];
for (NSInteger i = 0; i < subjects; i++) {
[Objects_Subjectcount addObject:object];// object or anything you need
}
}
[objects addObject:object];
}
NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = paths.firstObject;
NSString *plistPath = [documentsPath stringByAppendingPathComponent:#"File.plist"];
NSError *writeError = nil;
NSDictionary *finalDict = #{#"Objects": objects};
NSData *plistData = [NSPropertyListSerialization dataWithPropertyList:finalDict format:NSPropertyListXMLFormat_v1_0 options:NSPropertyListImmutable error:&writeError];
if(plistData){
[plistData writeToFile:plistPath atomically:YES];
}
else {
NSLog(#"Error in saveData: %#", error);
}
NOTE : all the datas store by JSON but after storage need to add additional values by manually! Thats I am trying
NSData *plistData = [NSPropertyListSerialization dataWithPropertyList:finalDict format:NSPropertyListXMLFormat_v1_0 options:NSPropertyListMutable error:&writeError];
Retrieve data from plist like this.
NSMutableDictionary *plistDic = [[NSMutableDictionary alloc] initWithContentsOfFile:plistPath];
Now suppose you want to update first array of dictionary then
NSMutableArray *array = [[NSMutableArray alloc]init:[plistDic objectAtIndex:0]]
You can do for loop if you want to change all array data...Right i am just using first object data..
NSMutableDictionary *dict = [[NSMutableDictionary alloc]init:[array objectAtIncex:0]];
[dict addObject:"yourdata" forKey:"yourkey"];
[array replaceObject:dict atIndex:0];
[plistDic replaceObjectAtIndex:0 withObject:array];
And last
[plistDic writeToFile:plistPath atomically:YES];
The object from response[key] is immutable so it can't be modified as below:
[object setObject:Objects_Subjectcount forKey:#"Objects_Subjectcount"];
Making it mutable as below, it can be modified by any method add/remove/set.
NSMutableDictionary *object = [response[key] mutableCopy];
Hope using below modified block, you would see required changes.
NSDictionary *JSON = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves | NSJSONReadingMutableContainers error:&error];
NSDictionary *response = JSON[#"response"];
NSArray *keys = [response allKeys];
NSMutableArray *objects = [NSMutableArray new];
for (NSString *key in keys) {
NSMutableDictionary *object = [response[key] mutableCopy];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"subject = %#",object[#"subject"]];
NSArray *objectsWithSameSubject = [objects filteredArrayUsingPredicate:predicate];
NSInteger subjects = [object[#"subject"] integerValue];
if (subjects > 0) {
[object setObject:#"" forKey:#"level"];
[object setObject:#(YES) forKey:#"isParent"];
NSMutableArray *Objects_Subjectcount = [NSMutableArray new];
for (NSInteger i = 0; i < subjects; i++) {
[Objects_Subjectcount addObject:#{#"level":#(0), #"isChild":#(YES)}];
}
[object setObject:Objects_Subjectcount forKey:#"Objects_Subjectcount"];
}
[objects addObject:object];
}
NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = paths.firstObject;
NSString *plistPath = [documentsPath stringByAppendingPathComponent:#"File.plist"];
NSError *writeError = nil;
NSDictionary *finalDict = #{#"Objects": objects};
NSData *plistData = [NSPropertyListSerialization dataWithPropertyList:finalDict format:NSPropertyListXMLFormat_v1_0 options:NSPropertyListImmutable error:&writeError];
if(plistData){
[plistData writeToFile:plistPath atomically:YES];
}
else {
NSLog(#"Error in saveData: %#", error);
}

How to Read Plist Data Using Objective C?

I have stored JSON data Into within Plist. Whenever I want to see my stored data I am taking path details and find into my machine then only I can see. I need to read data after storage using objective C.
NSDictionary *JSON = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves | NSJSONReadingMutableContainers error:&error];
NSDictionary *response = JSON[#"response"];
NSArray *keys = [response allKeys];
NSMutableArray *objects = [NSMutableArray new];
for (NSString *key in keys) {
NSMutableDictionary *object = response[key];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"subject = %#",object[#"subject"]];
NSArray *objectsWithSameSubject = [objects filteredArrayUsingPredicate:predicate];
NSInteger subjects = [object[#"subject"] integerValue];
if (subjects > 0) {
NSMutableArray *Objects_Subjectcount = [NSMutableArray new];
[object setObject:Objects_Subjectcount forKey:#"Objects_Subjectcount"];
for (NSInteger i = 0; i < subjects; i++) {
[Objects_Subjectcount addObject:object];// object or anything you need
}
}
[objects addObject:object];
}
NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = paths.firstObject;
NSString *plistPath = [documentsPath stringByAppendingPathComponent:#"File.plist"];
NSError *writeError = nil;
NSDictionary *finalDict = #{#"Objects": objects};
NSData *plistData = [NSPropertyListSerialization dataWithPropertyList:finalDict format:NSPropertyListXMLFormat_v1_0 options:NSPropertyListImmutable error:&writeError];
if(plistData){
[plistData writeToFile:plistPath atomically:YES];
}
else {
NSLog(#"Error in saveData: %#", error);
}
Once you have the right path to the plist file, you can read it by:
NSMutableDictionary *plistDic = [[NSMutableDictionary alloc] initWithContentsOfFile: path];
int value = [[plistDic objectForKey:#”value”] intValue]; //to get a int value for value for example
and to write to plist:
[plistDic setObject:[NSNumber numberWithInt:2] forKey:#”value”];
[plistDic writeToFile: path atomically:YES];
Try this:
NSError *error = nil;
NSData * tempData = [[NSData alloc] initWithContentsOfFile:#"File.plist"];
NSPropertyListFormat plistFormat = nil;
NSDictionary *temp = [NSPropertyListSerialization propertyListWithData:tempData options:NSPropertyListImmutable format:NSPropertyListXMLFormat_v1_0 error:&error];
Note :
when you read data using NSPropertyListSerialization you dont have to pass NSPropertyListFormat . you either pass nil or pass the address for NSPropertyListFormat.
Hope this will help.

Using NSArray and NSDictionary to access a JSON object without a root element

Here's an example of my data:
[
{
code: "DRK",
exchange: "BTC",
last_price: "0.01790000",
yesterday_price: "0.01625007",
top_bid: "0.01790000",
top_ask: "0.01833999"
}
]
I'm trying to retrieve the value for last_price by loading the contents of my NSDictionary into an Array.
NSURL *darkURL = [NSURL URLWithString:#"https://api.mintpal.com/v1/market/stats/DRK/BTC"];
NSData *darkData = [NSData dataWithContentsOfURL:darkURL];
NSError *error = nil;
NSDictionary *darkDict = [NSJSONSerialization JSONObjectWithData:darkData options:0 error:&error];
self.darkPosts = [NSMutableArray array];
NSArray *darkPostArray = [darkDict objectForKey:#""];
for (NSDictionary *darkDict in darkPostArray) {...
But my json doesn't have a root element, so what do I do?
Additionally, when using the suggested answer, the output is ("...
- (void)viewDidLoad{
[super viewDidLoad];
NSURL *darkURL = [NSURL URLWithString:#"https://api.mintpal.com/v1/market/stats/DRK/BTC"];
NSData *darkData = [NSData dataWithContentsOfURL:darkURL];
NSError *error = nil;
NSDictionary *darkDict = [NSJSONSerialization JSONObjectWithData:darkData options:0 error:&error];
NSString *lastP = [darkDict valueForKey:#"last_price"];
self.dark_label.text = [NSString stringWithFormat: #"%#", lastP];
}
It looks like you are wanting to iterate over your results. The root element is an array not a dictionary so you can just start iterating
NSError *error = nil;
NSArray *items = [NSJSONSerialization JSONObjectWithData:darkData
options:kNilOptions
error:&error];
if (!items) {
NSLog(#"JSONSerialization error %#", error.localizedDescription);
}
for (NSDictionary *item in items) {
NSLog(#"last_price => %#", item[#"last_price"]);
}
If you literally just want to collect an array of the last_price's then you can so this
NSArray *lastPrices = [items valueForKey:#"last_price"];
Convert the JSON to an NSArray with NSJSONSerialization. Then access the value:
NSData *darkData = [#"[{\"code\":\"DRK\",\"exchange\": \"BTC\",\"last_price\": \"0.01790000\",\"yesterday_price\": \"0.01625007\",\"top_bid\": \"0.01790000\"}, {\"top_ask\": \"0.01833999\"}]" dataUsingEncoding:NSUTF8StringEncoding];
NSArray *array = [NSJSONSerialization JSONObjectWithData:darkData
options:0
error:&error];
NSString *value = array[0][#"last_price"];
NSLog(#"value: %#", value);
NSLog output:
value: 0.01790000
If you are having trouble post the code you have written to get some help.
-- updated for new OP code:
The web service returns a JSON array or dictionaries not a JSON dictionary. First you have to index into the array and then index into the dictionary.
NSURL *darkURL = [NSURL URLWithString:#"https://api.mintpal.com/v1/market/stats/DRK/BTC"];
NSData *darkData = [NSData dataWithContentsOfURL:darkURL];
NSError *error = nil;
NSArray *darkArray = [NSJSONSerialization JSONObjectWithData:darkData options:0 error:&error];
NSDictionary *darkDict = darkArray[0];
NSString *lastP = [darkDict valueForKey:#"last_price"];
NSLog(#"lastP: %#", lastP);
NSLog output:
lastP: 0.01970000
Note that the two lines:
NSDictionary *darkDict = darkArray[0];
NSString *lastP = [darkDict valueForKey:#"last_price"];
can be replaced with the single line using array indexing:
NSString *lastP = darkArray[0][#"last_price"];
Where the "[0]" gets the first array element which is a NSDictionary and the "[#"last_price"]" gets the names item from the dictionary.

Parsing Json in iOS without keys common

My JSON String is :
[
{'Local':'webaddress'},
{'QA':'webaddress1'}
]
My Code is :
NSMutableDictionary *dataDictonary = [NSJSONSerialization
JSONObjectWithData:responseData
options:0
error:nil];
NSArray *keys = [dataDictonary allKeys];
NSArray *values = [dataDictonary allValues];
int i=0;
NSLog(#"",[keys count]);
NSLog(#"",[values count]);
int i=0;
for ( NSString *items in keys )
{
NSLog(#"----");
NSLog(#"Name: %#", items);
NSLog(#"Address: %#", values[i++]);
NSLog(#"----");
}
Here i get size as nothing blank in NSlog and can't Parse this value don't don't why. Please help..
Your JSON is an Array with Objects inside so you need to convert it to a NSArray:
NSString *json_string = #"[{\"Local\": \"webaddress\" }, {\"QA\": \"webaddress1\" }]";
NSError *error;
NSArray *JSON =
[NSJSONSerialization JSONObjectWithData: [json_string dataUsingEncoding:NSUTF8StringEncoding]
options: NSJSONReadingMutableContainers
error: &error];
NSLog(#"Local: %#", JSON[0][#"Local"]); // output is: Local: webaddress
UPDATE
// itherate through array
for(NSDictionary *dictionary in JSON)
{
//now you can iterate throug each dicitonary
NSEnumerator *enumerator = [dictionary keyEnumerator];
id key;
while((key = [enumerator nextObject])){
NSLog(#"key=%# value=%#", key, [dictionary objectForKey:key]);
}
}
Log looks like this:
key=Local value=webaddress
key=QA value=webaddress1

Check if an array of NSDictionary contains a NSDictionary

In my app I've to check if in an array of NSDictionary there are another NSDictionary. In other words, I made a JSON file and I store it in Documents.
Now I'm parsing this JSON to insert a new entry, before I insert this entry in my JSON I need to check if the entry it's already stored in my file. I parsed JSON so:
// First I read the JSON file from the folder Documents
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"data.json"];
NSString *content = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:NULL];
NSData *data = [content dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *dictContent = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
// Json parsing
NSMutableArray *array = [[NSMutableArray alloc]init];
NSMutableArray *arrayOfDictData = [[NSMutableArray alloc]init];
if (dictContent) {
NSDictionary *sites = [dictContent objectForKey:#"sites"];
NSArray *site = [sites objectForKey:#"site"];
array = [site mutableCopy];
}
Then I've another NSDictionary (dictForJson) in which I inserted the data parsed from the HTML site, so now I need to check if the data in the dictionary dictForJson are still in the JSON file.
How I can check that?
The dictForJson has this structure:
dictForJson = #{#"name": htmlTitle,
#"src": path,
#"expiryDate": expireDate};
the NSArray site has this structure:
site: (
{
expiryDate = "29 Ago 2013";
name = Sito4;
src = "/Users/redoddity/Library/Application Support/iPhone Simulator/6.1/Applications/2D9EBE71-4365-448D-8AD2-A08749B8DBC1/Documents/Sito4.html";
}
)
Have you any idea?
I tried with [array containsObject:dictForJson], but the NSDictionary isn't ordered so when I use this method sometimes returns 0 and other times returns 1
Maybe it's useful I build my JSON with the following code:
- (void)JsonCreateOrEdit {
NSDictionary *dictSites = [[NSDictionary alloc]init];
NSDictionary *dictSite = [[NSDictionary alloc]init];
NSMutableArray *site = [[NSMutableArray alloc]init];
NSDictionary *dictForJson = [[NSDictionary alloc]init];
dictForJson = #{#"name": htmlTitle,
#"src": path,
#"expiryDate": expireDate};
NSString* documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filePath = [documentsPath stringByAppendingPathComponent:#"data.json"];
BOOL fileExist = [[NSFileManager defaultManager] fileExistsAtPath:filePath];
if (!fileExist) {
[site addObject:dictForJson];
dictSite = #{#"site": site};
dictSites = #{#"sites": dictSite};
// Creo il file Json
NSLog(#"Il file non esiste");
SBJsonWriter *writer = [[SBJsonWriter alloc]init];
NSString *jsonCommand = [writer stringWithObject:dictSites];
[CreateFile createFileIn:documentsPath with:#"data.json" andData:jsonCommand]; // This is a class method I made to create the file
else {
// Here there are the instructions to update the file data.json
NSLog(#"Il file esiste");
// Leggo il file json
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"data.json"];
NSString *content = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:NULL];
NSData *data = [content dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *dictContent = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
// Faccio il parsing del json
NSMutableArray *array = [[NSMutableArray alloc]init];
NSMutableArray *arrayOfDictData = [[NSMutableArray alloc]init];
if (dictContent) {
NSDictionary *sites = [dictContent objectForKey:#"sites"];
NSArray *site = [sites objectForKey:#"site"];
array = [site mutableCopy];
// Here I must check if in the array site there are the same information I'm trying to insert
}
}
NSPredicate *aPredicate = [NSPredicate predicateWithFormat:#"%K LIKE[c] %#", #"name", #"htmlTitle"];
NSArray *theFilteredArray = [mainArrayOfDictionry filteredArrayUsingPredicate:aPredicate];
if ([theFilteredArray count]){
NSLog(#"Dictionay Exists");
}else{
NSLog(#"Dictionay does not Exists");
}
In the first statement the first parameter is the "Key" and the second parameter is the actual value of the dictionay.
I am Assuming following :
NSDictionary *dictForJson = #{#"name": htmlTitle,
#"src": path,
#"expiryDate": expireDate};
NSArray *mainArrayOfDictionry = (
"dictForJson" : #{#"name": htmlTitle,
#"src": path,
#"expiryDate": expireDate};
),
(),
(),
(),
.
.
.
)
*Hope this will help you.*Array
I did it! :)
I made so:
{
// Aggiorno il file
NSLog(#"Il file esiste");
// Leggo il file json
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"data.json"];
NSString *content = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:NULL];
NSData *data = [content dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *dictContent = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
// Faccio il parsing del json
NSMutableArray *array = [[NSMutableArray alloc]init];
NSMutableArray *arrayOfDictData = [[NSMutableArray alloc]init];
if (dictContent) {
NSDictionary *sites = [dictContent objectForKey:#"sites"];
NSArray *site = [sites objectForKey:#"site"];
NSDictionary *dict = [site objectAtIndex:0];
NSLog(#"dictForJson = %#\ndict = %#", dictForJson, dict);
NSString *name = [dict objectForKey:#"name"];
NSLog(#"name: %#", name);
array = [site mutableCopy];
}
And it works! Thank you for the time!

Resources