Parse a NSDictionary - ios

I have a NSDictionary looks like this:
data = {
start = {
name = "abc";
age = "123";
id = AA838DDE;
};
};
how can I parser the dictionary to get individual name, age, and id? Thanks.

NSString *name = dictionary[#"data"][#"start"][#"name"];

I add an other answer because I hate the new Objective-C syntax (sorry #Raphael Olivieira)
NSString *name = [[[[dictionary objectForKey:#"data"] objectForKey:#"start"] objectAtIndex:0] objectForKey:#"name"];
NSLog(#"%#", name);
Longer than the previous answer but you know what you do and you don't code in C.
BTW, using the other syntax :
NSString *name = dictionary[#"data"][#"start"][0][#"name"];
NSLog(#"%#", name);

why don't you simply try:
int arrCount = [[[dictionaryObject valueForKey:#"data"] objectForKey:#"start"] count];
for(int i = 0 ; i < arrCount ; i++)
{
NSString *strName = [[[[dictionaryObject objectForKey:#"data"]
objectForKey:#"start"]
objectAtIndex:i]
objectForKey:#"name"];
NSString *strAge = [[[[dictionaryObject objectForKey:#"data"]
objectForKey:#"start"]
objectAtIndex:i]
objectForKey:#"age"];
NSString *strID = [[[[dictionaryObject objectForKey:#"data"]
objectForKey:#"start"]
objectAtIndex:i]
objectForKey:#"id"];
NSLog(#"%# - %# - %#", strName, strAge, strID);
}

Related

iOS: Creating structured NSArray in given format

hello all i am working on a project in which i have to create an array in this format:
{
"1": {
"Child_Gender": "",
"Child_DOB": "",
"Child_tobbacoUse": ""
},
"2": {
"Child_Gender": "",
"Child_DOB": "",
"Child_tobbacoUse": ""
},
but the array i create gives this format
(
{
"Child_DOB" = "";
"Child_Gender" = "";
"Child_tobbacoUse" = "";
},
{
"Child_DOB" = "";
"Child_Gender" = "";
"Child_tobbacoUse" = "";
}
)
i am using the following code:
for (int i = 0; i < arrayChildModel.count; i++)
{
ChildModel *model = [arrayChildModel objectAtIndex:i];
NSString *keyOrder = [NSString stringWithFormat:#"Children_Gender[%d]",i];
NSString *keyQuantity = [NSString stringWithFormat:#"Children_BirthDate[%d]",i];
NSString *keyTobacco = [NSString stringWithFormat:#"Children_HasTobaccoUsage[%d]",i];
//NSString *keyNotes = [NSString stringWithFormat:#"row[%d][description]",i];
childDateOfBirthStr = model.ChildBirthDate ;
childGenderStr = model.ChildGender ;
childTobaccoStr = model.ChildTobaccoUsage;
NSString *string1 = [NSString stringWithFormat:#"%#=%#&",keyOrder,childGenderStr];
NSString *string2 = [NSString stringWithFormat:#"%#=%#",keyQuantity,childDateOfBirthStr];
NSString *string3 = [NSString stringWithFormat:#"%#=%#",keyTobacco,childTobaccoStr];
[stringParams appendString:string1];
[stringParams appendString:string2];
[stringParams appendString:string3];
NSDictionary * ChildDict;
NSArray * ApplicantKeys = [[NSArray alloc]initWithObjects:#"Child_Gender",#"Child_DOB",#"Child_tobbacoUse", nil];
NSArray * ApplicantObjects = [[NSArray alloc]initWithObjects:childGenderStr,childDateOfBirthStr,childTobaccoStr, nil];
ChildDict = [NSDictionary dictionaryWithObjects:ApplicantObjects forKeys:ApplicantKeys];
NSLog(#"Dictionary is %#",ChildDict);
[CompleteArray addObject:ChildDict];
}
NSLog(#"Final Array is %#",CompleteArray);
please help me to convert the output array to the required formatted array
Create one dictionary outer for loop
NSMutableDictionary *dict =[[NSMutableDictionary alloc]init];
add this line before NSLog(#"Dictionary is %#",ChildDict);
[dict setObject:ChildDict forKey:[NSString stringWithFormat:#"%ld",i+1]];
[CompleteArray addObject:dict];
Please check following solution it will give you as expected output.
NSMutableDictionary *resultDic = [NSMutableDictionary new];
for (int i = 0; i < arrayChildModel.count; i++)
{
ChildModel *model = [arrayChildModel objectAtIndex:i];
NSString *keyOrder = [NSString stringWithFormat:#"Children_Gender[%d]",i];
NSString *keyQuantity = [NSString stringWithFormat:#"Children_BirthDate[%d]",i];
NSString *keyTobacco = [NSString stringWithFormat:#"Children_HasTobaccoUsage[%d]",i];
//NSString *keyNotes = [NSString stringWithFormat:#"row[%d][description]",i];
childDateOfBirthStr = model.ChildBirthDate ;
childGenderStr = model.ChildGender ;
childTobaccoStr = model.ChildTobaccoUsage;
NSString *string1 = [NSString stringWithFormat:#"%#=%#&",keyOrder,childGenderStr];
NSString *string2 = [NSString stringWithFormat:#"%#=%#",keyQuantity,childDateOfBirthStr];
NSString *string3 = [NSString stringWithFormat:#"%#=%#",keyTobacco,childTobaccoStr];
[stringParams appendString:string1];
[stringParams appendString:string2];
[stringParams appendString:string3];
NSDictionary * ChildDict = [NSDictionary dictionaryWithObjectsAndKeys:childGenderStr,#"Child_Gender",childDateOfBirthStr,#"Child_DOB",childTobaccoStr,#"Child_tobbacoUse", nil];
NSLog(#"Dictionary is %#",ChildDict);
NSString *resultDicKey = [NSString stringWithFormat:#"%d",i+1];
[resultDic setValue:ChildDict forKey:resultDicKey];
}
NSLog(#"Result dic %#",resultDic);

NSMutableArray have restriction in adding object?

I am using NSMutableArray for adding objects.But its add only first 10 objects.
I have code for sharing
for (int j = 0; j<[feedData count]; j++)
{
[sharingItems addObject:[self whatsappdata:[feedData objectAtIndex:j]]];
}
This method return NSString type text.
Please provide me valid solution for this.
Thanks in Advance
-(NSString *)whatsappdata:(NSDictionary *)cellData1
{
NSString *brandName = [NSString stringWithFormat:#"%#", [cellData1 objectForKey:#"brand_name"]];
NSString *modelName = [NSString stringWithFormat:#"%#", [cellData1 objectForKey:#"brand_model_name"]];
NSString *version = [NSString stringWithFormat:#"%#", [cellData1 objectForKey:#"version_name"]];
if ([version isEqualToString: #"<null>"])
{
version = #"";
}
NSString *year = [NSString stringWithFormat:#"%#", [cellData1 objectForKey:#"model_year"]];
if (year == nil || [year isEqualToString:#"0"])
{
year = #"";
}
NSString *inventoryValue = [NSString stringWithFormat:#"%#",[cellData1 objectForKey:#"inventory_type"]];
NSInteger value = [inventoryValue intValue];
NSString *inventoryName;
NSString *msg;
if(value == 1)
{
inventoryName = [NSString stringWithFormat:#"%#", #"Stock"];
i++;
NSString *text2 = [NSString stringWithFormat:#"%d.%# %# %#- %# Single Owner\n",i, brandName, modelName, version, year];
msg = [NSString stringWithFormat:#"%#",text2];
msg= [msg stringByReplacingOccurrencesOfString:#"\n" withString:#"<br/>"];
}
else
{
inventoryName = [NSString stringWithFormat:#"%#", #"Required"];
msg = #"";
}
return msg;
//end data
}
Most probably "fetch limit" has set for 'NSFetchRequest' inside your code.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setFetchLimit:10];//such code you need to find and remove/change fetch limit
you need to allocate memory to array before adding elements
sharingItems = [[NSMutableArray alloc]init];

Loading text from .txt file iOS

I've been trying to convert a Quiz app that was based for Mac OS to iOS because I liked the idea of loading all questions from a single .txt file.
I'm still pretty new in the Objective-C language as I've used C# before.
The questions and answers are loaded via this function:
- (void)loadQuestionsAndAnswersArray {
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"Quiz1" ofType:#"txt"];
NSString *textFileString = [NSString stringWithContentsOfFile:filePath encoding:NSStringEncodingConversionAllowLossy error:NULL];
NSArray *seperatedQA = [textFileString componentsSeparatedByString:#"\n\n"];
for (NSString *QA in seperatedQA) {
NSString *questionString = [[[QA componentsSeparatedByString:#"\n"] objectAtIndex:0] stringByReplacingOccurrencesOfString:#"Q:" withString:#""];
NSMutableArray *answers = [[QA componentsSeparatedByString:#"A:"] mutableCopy];
[answers removeObjectAtIndex:0];
int correctAnswerLoc = 0;
for (int i = 0; i < answers.count; i++) {
NSString *answer = [answers objectAtIndex:i];
NSString *editedAnswer = [answer stringByReplacingOccurrencesOfString:#"\n" withString:#""];
editedAnswer = [editedAnswer stringByTrimmingCharactersInSet:
[NSCharacterSet whitespaceAndNewlineCharacterSet]];
[answers removeObjectAtIndex:i];
[answers insertObject:editedAnswer atIndex:i];
answer = editedAnswer;
if ([answer rangeOfString:#"[CORRECT]"].location != NSNotFound) {
correctAnswerLoc = [answers indexOfObject:answer];
NSString *editedAnswer = [answer stringByReplacingOccurrencesOfString:#"[CORRECT]" withString:#""];
[answers removeObjectAtIndex:i];
[answers insertObject:editedAnswer atIndex:i];
}
}
NSLog(#"answers = %#", answers);
NSDictionary *QADictionary = [NSDictionary dictionaryWithObjectsAndKeys:questionString, #"question", answers, #"answers", [NSNumber numberWithInt:correctAnswerLoc], #"correctAnswerLocation", nil];
[questionsAndAnswers addObject:QADictionary];
}
resultsArray = [[NSMutableArray alloc] initWithCapacity:[questionsAndAnswers count]];
}
The app then has a text field for the question and then 3 buttons, one for each answer. And when a new questions appears it changes the text within the text field and the title of the buttons.
This code works like a charm on the Mac App but on the iOS version it's like it can't find the txt file, the buttons etc is left blank.
I've been sitting on this for a week or so about now and that's the reason for this post.
The iOS app is based on this Github Mac app: https://github.com/SquaredTiki/Quizzer
If you want to have a look at how I've tried to convert the app here's a link to that to:
https://www.dropbox.com/s/1jqz9ue97p3v2h1/iTrafikk.zip?dl=0
And of course I'm not asking you to solve the whole issue for me, maybe just push me in the right direction if possible :)
I checked your project. And it seems that you are not calling loadQuestionsAndAnswersArray anywhere in your code. Also you are not initializing the questionsAndAnswers anywhere in the project.
Change your code like:
- (void)viewDidLoad
{
[super viewDidLoad];
[self loadQuestionsAndAnswersArray];
}
- (void)loadQuestionsAndAnswersArray
{
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"Quiz1" ofType:#"txt"];
NSString *textFileString = [NSString stringWithContentsOfFile:filePath encoding:NSStringEncodingConversionAllowLossy error:NULL];
NSArray *seperatedQA = [textFileString componentsSeparatedByString:#"\n\n"];
for (NSString *QA in seperatedQA)
{
NSString *questionString = [[[QA componentsSeparatedByString:#"\n"] objectAtIndex:0] stringByReplacingOccurrencesOfString:#"Q:" withString:#""];
NSMutableArray *answers = [[QA componentsSeparatedByString:#"A:"] mutableCopy];
[answers removeObjectAtIndex:0];
int correctAnswerLoc = 0;
for (int i = 0; i < answers.count; i++)
{
NSString *answer = [answers objectAtIndex:i];
NSString *editedAnswer = [answer stringByReplacingOccurrencesOfString:#"\n" withString:#""];
editedAnswer = [editedAnswer stringByTrimmingCharactersInSet:
[NSCharacterSet whitespaceAndNewlineCharacterSet]];
[answers removeObjectAtIndex:i];
[answers insertObject:editedAnswer atIndex:i];
answer = editedAnswer;
if ([answer rangeOfString:#"[CORRECT]"].location != NSNotFound)
{
correctAnswerLoc = [answers indexOfObject:answer];
NSString *editedAnswer = [answer stringByReplacingOccurrencesOfString:#"[CORRECT]" withString:#""];
[answers removeObjectAtIndex:i];
[answers insertObject:editedAnswer atIndex:i];
}
}
NSLog(#"answers = %#", answers);
NSDictionary *QADictionary = [NSDictionary dictionaryWithObjectsAndKeys:questionString, #"question", answers, #"answers", [NSNumber numberWithInt:correctAnswerLoc], #"correctAnswerLocation", nil];
if (!questionsAndAnswers)
{
questionsAndAnswers = [[NSMutableArray alloc] init];
}
[questionsAndAnswers addObject:QADictionary];
}
resultsArray = [[NSMutableArray alloc] initWithCapacity:[questionsAndAnswers count]];
[self loadQuestionsAndAnswersIntoInterface];
}

Can't extract needed information from NSDictionary

I parse a XML file, and after parsing get a NSDictionary object (XMLDictionary named). I'm parsing this:
<result><node><id>27</id><name>Name 1</name><type>0</type><price>0</price><img>/upload/iblock/1a1/1a138b2d4da6e42398beeb21acc8e84f.png</img></node><node><id>28</id><name>Name 2</name><type>0</type><price>0</price><img>/upload/iblock/b72/b724d1550f93987a73b04974b5f7390e.png</img></node></result>
After that i'm trying this (titleArr - NSArray):
_titleArr = [[[[_xmlDictionary objectForKey:#"result"] objectForKey:#"node"] objectForKey:#"name"] valueForKey:#"text"];
In Run-time I get this error in the above line: "Thread 1: signal SIGABRT". How can i fix this problem?
NSError* parseError = nil;
_xmlDictionary = [XMLReader dictionaryForXMLString:myXMLString error:&parseError];
if (parseError != nil) {
NSLog(#"Error on XML parse: %#", parseError);
}
NSLog(#"The full dictionary is %#", _xmlDictionary);
NSDictionary* result = [_xmlDictionary objectForKey:#"result"];
NSLog(#"'result' = %#", result);
NSDictionary* node = [result objectForKey:#"node"];
NSLog(#"'node' = %#", node);
NSString* name = [node objectForKey:#"name"];
NSLog(#"'name' = %#", name);
At the very least, if it fails, the error will be isolated to a single operation. And the NSLogs will show you the values after each step.
Try this:
NSArray *arrResult = [_xmlDictionary objectForKey:#"result"];
for(int i = 0; i < [arrResult count]; i++)
{
NSArray *arrNode = [arrResult objectAtIndex:i] valueForKey:#"node"];
NSString *sName = [arrNode valueForKey:#"Name"];
NSLog(#"Name : %#",sName);
}
Edited Answer
NSArray *arrResult = [_xmlDictionary valueForKey:#"result"];
for (int i = 0; i < [arrResult count]; i++) {
NSDictionary *dicNode = [[arrResult objectAtIndex:i] valueForKey:#"Node"];
NSString *sName = [dicNode valueForKey:#"Name"];
NSLog(#"Name : %#",sName);
}

Collect string values and add into array

I am writing an app where I want to collect names and phone numbers from a list and add them into an array. How do I do this? I could retrieve first name and last name, but I don't get how to add a phone number in the below code as it is in a different for loop. It might look simple but I am stuck as I am new.
for (i = 0; i < [list count]; i++)
{
NSString *firstName = (__bridge_transfer NSString *)ABRecordCopyValue(contactPerson, kABPersonFirstNameProperty);
NSString *lastName = (__bridge_transfer NSString *)ABRecordCopyValue(contactPerson, kABPersonLastNameProperty);
NSMutableArray *name = [NSMutableArray array];
if(firstName != nil)
[name addObject:firstName];
if(lastName != nil)
[name addObject:lastName];*/
[self displaynames:name];
ABMultiValueRef mobile=ABRecordCopyValue(contactPerson, kABPersonPhoneProperty);
for (int k=0;k<ABMultiValueGetCount(mobile); k++)
{
NSString *mobileNo = (__bridge_transfer NSString *)ABMultiValueCopyValueAtIndex(mobile, k);
NSLog(#"mobile number: %#",mobileNo);
}
}
- (void)displaynames:(NSMutableArray*)names
{
for (NSMutableArray* name in names)
{
NSLog(#"MyResult:%# %#",[names objectAtIndex:0],[names objectAtIndex:1]);
}
}
So in the above code I am able to get the first name and last name from the list and add them into the array, similarly how do I get mobile phone number and add into the same array and get the result in the displayNames: function as it is another for loop. Can someone please edit the code and tell me what changes I have to make in the above code. Also in the result everything is being displayed twice why so?
NSMutableArray *contactList=[[NSMutableArray alloc] init];
for (int i=0; i<4; i++) {
NSMutableDictionary *contactInfo=[[NSMutableDictionary alloc] init];
for (int i = 0; i < [list count]; i++)
{
NSString *firstName = (__bridge_transfer NSString *)ABRecordCopyValue(contactPerson, kABPersonFirstNameProperty);
NSString *lastName = (__bridge_transfer NSString *)ABRecordCopyValue(contactPerson, kABPersonLastNameProperty);
if (![firstName isEqualToString:#""]) {
[contactInfo setValue:firstName forKey:#"firstName"];
}
if (![lastName isEqualToString:#""]) {
[contactInfo setValue:lastName forKey:#"lastName"];
}
NSMutableArray *mobileNoArray=[[NSMutableArray alloc] initWithCapacity:ABMultiValueGetCount(mobile)];
ABMultiValueRef mobile=ABRecordCopyValue(contactPerson, kABPersonPhoneProperty);
for (int k=0;k<ABMultiValueGetCount(mobile); k++)
{
NSString *mobileNo = (__bridge_transfer NSString *)ABMultiValueCopyValueAtIndex(mobile, k);
[mobileNoArray addObject:mobileNo];
}
if (mobileNoArray.count!=0) {
[contactInfo setObject:mobileNoArray forKey:#"mobileNo"]
}
}
[contactList addObject:contactInfo];
NSLog(#"contact info == %#",contactInfo);
}
NSLog(#"contact list array is %#",contactList);
So, instead using Array you have to use Dictionary to store FirstName, LastName and MobileNo with keyvalue Pair. If you have multiple user than use Array as upper layer, means add your user dictionary into array and when ever you want a user write the code:
for(NSDictionary *userDic in yourArray)
{
NSString *fName = [userDic valueForKey:#"FirstName"];
...
}
This is one of the way...
You can try to add the user info in a dictionary or create a model user object and store in the array. So all the information stays encapsulated in a single object.
self.users = [NSMutableArray array];
for (i = 0; i < [list count]; i++)
{
NSString *firstName = ...
NSString *lastName = ...
NSString *mobileNumber = ...
NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
if(firstName)
userInfo[#"FirstName"] = firstName;
if(lastName)
userInfo[#"LastName"] = lastName;
if(mobileNumber)
userInfo[#"MobileNumber"] = mobileNumber;
[self.users addObject:userInfo];
}
You can enumerate using
[self.users enumerateObjectsUsingBlock:^(NSDictionary * userInfo, NSUInteger idx, BOOL *stop) {
NSString *firstName = userInfo[#"FirstName"];
NSString *mobileNumber = userInfo[#"MobileNumber"];
}];
Searching for a single user for a name
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"FirstName == %#",#"aUserName"];
NSDictionary *userInfo = [[self.users filteredArrayUsingPredicate:predicate]lastObject];
Try the following steps:
NSMutableArray *firstNames;
NSMutableArray *LastNames;
NSMutableArray *Mobile_numbers;
NSMutableArray *type_array;
NSMutableArray *firstandlast;
........
-(void)get_arr
{
ABAddressBookRef addressBook = ABAddressBookCreate();
NSArray *arrayOfPeople = (__bridge_transfer NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
NSUInteger index = 0;
firstNames = [[NSMutableArray alloc] init];
Mobile_numbers = [[NSMutableArray alloc] init];
type_array=[[NSMutableArray alloc]init ];
LastNames=[[NSMutableArray alloc]init ];
NSMutableArray *firstandlast;
#try
{
for(index = 0; index<=([arrayOfPeople count]-1); index++)
{
ABRecordRef currentPerson = (__bridge ABRecordRef)[arrayOfPeople objectAtIndex:index];
NSString *type;
ABMultiValueRef phones = (ABMultiValueRef)ABRecordCopyValue(currentPerson, kABPersonPhoneProperty);
for (int i=0; i < ABMultiValueGetCount(phones); i++)
{
//NSString *phone = (NSString *)ABMultiValueCopyValueAtIndex(phones, i);
////NSLog(#"%#", phone);
mobileLabel = (NSString*)ABMultiValueCopyLabelAtIndex(phones, i);
//NSLog(#"MOG:%#",mobileLabel);
if([mobileLabel isEqualToString:#"_$!<Mobile>!$_"]||[mobileLabel isEqualToString:#"_$!<Main>!$_"])
{
//NSLog(#"mobile:");
type=#"mobile";
}
else if ([mobileLabel isEqualToString:#"_$!<Work>!$_"])
{
//NSLog(#"Work:");
type=#"Work";
}
else if ([mobileLabel isEqualToString:#"_$!<Home>!$_"])
{
//NSLog(#"Home:");
type=#"Home";
}
else if ([mobileLabel isEqualToString:#"_$!<Other>!$_"] )
{
//NSLog(#"Other:");
type=#"Other";
}
mobile = (NSString*)ABMultiValueCopyValueAtIndex(phones, i);
//NSLog(#"GG:%#",mobile);
mobile = [mobile stringByReplacingOccurrencesOfString:#"-"
withString:#""];
mobile = [mobile stringByReplacingOccurrencesOfString:#"("
withString:#""];
mobile = [mobile stringByReplacingOccurrencesOfString:#")"
withString:#""];
mobile = [mobile stringByReplacingOccurrencesOfString:#" "
withString:#""];
[Mobile_numbers addObject:mobile];
[type_array addObject:type];
NSString *currentFirstName = (__bridge_transfer NSString *)ABRecordCopyValue(currentPerson, kABPersonFirstNameProperty);
////NSLog(#"NAME:%#",currentFirstName);
if ([currentFirstName length]!=0)
{
//NSLog(#"NAME:%#",currentFirstName);
[firstNames addObject:currentFirstName];
}
else
{
//NSLog(#"NAME:DUMMY");
currentFirstName=#"";
[firstNames addObject:currentFirstName];
}
NSString *currentLast = (__bridge_transfer NSString *)ABRecordCopyValue(currentPerson, kABPersonLastNameProperty);
////NSLog(#"NAME:%#",currentFirstName);
if ([currentLast length]!=0)
{
//NSLog(#"NAME:%#",currentLast);
[LastNames addObject:currentLast];
}
else
{
//NSLog(#"NAME:DUMMY");
currentLast=#"";
[LastNames addObject:currentLast];
}
NSString *temp_f_l=[NSString stringWithFormat:#"%# %#",currentFirstName,currentLast];
[firstandlast addObject:temp_f_l];
}
NSLog(#"MOB:%#",Mobile_numbers);
NSLog(#"TYPE:%#",type_array);
NSLog(#"FN:%#",firstNames);
NSLog(#"FN:%#",LastNames);
NSLog(#"FN&LN:%#",firstandlast);
}
}
#catch (NSException *exception)
{
//NSLog(#"CATCH");
}
}
In my Application. I am using this code to store Addressbook contents to Array. I hope it help for you.

Resources