create loop for array to get string from json String? - ios

i need to display a Table View containing information from web service response i do no where iam doing wrong here my sample code
NSData *data = [soapResultsString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSArray *array = [json allValues];
for (int i=0; i<array.count; i++)
{
recordResults =NO;
appDelegate.rateString =[[[json valueForKey:#"plan_history"]valueForKey:#"rate"]objectAtIndex:i];
appDelegate.descriptionString=[[[json valueForKey:#"plan_history"]valueForKey:#"description"]objectAtIndex:i];
appDelegate.validityString=[[[json valueForKey:#"plan_history"]valueForKey:#"validity"]objectAtIndex:i];
appDelegate.plantypeString=[[[json valueForKey:#"plan_history"]valueForKey:#"plantype"]objectAtIndex:i];
}
i need to parse 4 values from plan_history like "rate","description","validity","plan type"
when i run my app i getting only one set of value in Table view . i.e my json string contains more than 20 records containing rate,description,validity and plan type
can u show me how to loop my json value and display all my records in Table View

You should eliminate those calls to allValues and valueForKey, as repeatedly calling those methods is very inefficient ways to tackle JSON parsing.
In one of your comments, you said that your JSON looked like:
{
"plan_history": [
{
"rate": "₹1000",
"description": "FullTalktimeTopupRs.1000FullTalktime",
"validity": "Validity: 0\r",
"plantype": "FullTalkTime"
},
{
"rate": "₹508",
"description": "FullTalktimeTopupRs.558morethanFullTalktime",
"validity": "Validity: 2\r",
"plantype": "FullTalkTime"
}
]
}
(I wonder if there was something before this plan_history entry given your allValues reference, but unless you tell us otherwise, I'll assume this is what the original JSON looked like.)
If so, to parse it you would do:
NSMutableArray *results = [NSMutableArray array];
NSError *error;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
NSArray *planHistory = json[#"plan_history"];
for (NSDictionary *planHistoryEntry in planHistory) {
NSString *rateString = planHistoryEntry[#"rate"];
NSString *description = planHistoryEntry[#"description"];
NSString *validity = planHistoryEntry[#"validity"];
NSString *planType = planHistoryEntry[#"plantype"];
// now do whatever you want with these four values.
// for example, I'd generally create a custom object I defined elsewhere for these four values and add to results, e.g.
[results addObject:[PlanHistoryEntry planHistoryEntryWithRate:rateString
description:description
validity:validity
planType:planType]];
}
// now do something with results, e.g. store it in some property in `appDelegate`, etc.
Where, PlanHistoryEntry might be defined like so:
#interface PlanHistoryEntry : NSObject
#property (nonatomic, copy) NSString *rateString;
#property (nonatomic, copy) NSString *planDescription; // note, do not use `description` for property name
#property (nonatomic, copy) NSString *validity;
#property (nonatomic, copy) NSString *planType;
+ (instancetype) planHistoryEntryWithRate:(NSString *)rateString
planDescription:(NSString *)planDescription
validity:(NSString *)validity
planType:(NSString *)planType;
#end
#implementation PlanHistoryEntry
+ (instancetype) planHistoryEntryWithRate:(NSString *)rateString
planDescription:(NSString *)planDescription
validity:(NSString *)validity
planType:(NSString *)planType
{
PlanHistoryEntry *entry = [[self alloc] init];
entry.rateString = rateString;
entry.planDescription = planDescription;
entry.validity = validity;
entry.planType = planType;
return entry;
}
#end
But I don't want you to get lost in the minutiae of this answer (because given the ambiguity of the question, I may have gotten some details wrong). The key point is that you should not be using allValues or valueForKey. Just navigate the JSON structure more directly as illustrated above.

Try this,
NSData *data = [soapResultsString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSArray *rateArray = [[json objectForKey:#"plan_history"] objectForKey:#"rate"];
NSArray * descriptionArray = [[json objectForKey:#"plan_history"] objectForKey:#"description"];
NSArray * validityArray = [[json objectForKey:#"plan_history"] objectForKey:#"validity"];
NSArray * plantypeArray = [[json objectForKey:#"plan_history"] objectForKey:#"plantype"];
and use rateArray, descriptionArray etc.

You can create a class storing your data as follows:
Something like:
planClass.h
#property(nonatomic, strong) NSString * rateString;
#property(nonatomic, strong) NSString * descriptionString;
#property(nonatomic, strong) NSString * validityString;
#property(nonatomic, strong) NSString * plantypeString;
plan.m
//#synthesize the properties of .h
Now in your .m file where you want to parse the data you can do something like:
NSData *data = [soapResultsString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSArray *array = [json allValues];
for (int i=0; i<array.count; i++)
{
planClass *pc = [[planClass alloc]init];
recordResults =NO;
pc.rateString =[[[json valueForKey:#"plan_history"]valueForKey:#"rate"]objectAtIndex:i];
pc.descriptionString=[[[json valueForKey:#"plan_history"]valueForKey:#"description"]objectAtIndex:i];
pc.validityString=[[[json valueForKey:#"plan_history"]valueForKey:#"validity"]objectAtIndex:i];
pc.plantypeString=[[[json valueForKey:#"plan_history"]valueForKey:#"plantype"]objectAtIndex:i];
[appDelegate.arrayPlan addObject:pc];
}
NSLog(#"appDelegate.arrayPlan >> %#",appDelegate.arrayPlan); // you'll get array of planClass objects
You can now access the arrayPlan declared in appDelegate as follows:
for(id *obj in arrayPlan)
{
planClass *pc = (planClass *)obj;
NSLog("rate: %#",[pc valueForKey:#"rateString"]);
NSLog("descriptionString: %#",[pc valueForKey:#"descriptionString"]);
NSLog("validityString: %#",[pc valueForKey:#"validityString"]);
NSLog("plantypeString: %#",[pc valueForKey:#"plantypeString"]);
}
Hope this helps.

you need to store that value in fatalist control means in NSMutable array like this.
NSData *data = [soapResultsString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSMutableArray *arrayHistory = [[NSMutableArray alloc]init];
NSArray *array = [json allValues];
for (int i=0; i<array.count; i++)
{
recordResults =NO;
appDelegate.rateString =[[[json valueForKey:#"plan_history"]valueForKey:#"rate"]objectAtIndex:i];
appDelegate.descriptionString=[[[json valueForKey:#"plan_history"]valueForKey:#"description"]objectAtIndex:i];
appDelegate.validityString=[[[json valueForKey:#"plan_history"]valueForKey:#"validity"]objectAtIndex:i];
appDelegate.plantypeString=[[[json valueForKey:#"plan_history"]valueForKey:#"plantype"]objectAtIndex:i];
[arrayHistory addObject:appDelegate.rateString];
[arrayHistory addObject:appDelegate.descriptionString];
[arrayHistory addObject:appDelegate.validityString];
[arrayHistory addObject:appDelegate.plantypeString];
}
Now use
arrayHistory
to load data in table view

Related

New to JSON API how to access the values in objective-c?

Below is my code to access the JSON API from Edmunds.com, this works perfectly to access the information I am just having trouble with accessing the key, value pairs.
NSURL *equipmentURL = [NSURL URLWithString: [NSString stringWithFormat:#"https://api.edmunds.com/api/vehicle/v2/styles/%#/equipment?fmt=json&api_key=%#", self.carID, apiKey]];
NSData *jsonData = [NSData dataWithContentsOfURL:equipmentURL];
NSError *error = nil;
NSDictionary *dataDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
self.engineArray = [NSMutableArray array];
NSArray *equipmentArray = [dataDictionary objectForKey:#"equipment"];
for (NSDictionary *carInfoDictionary in equipmentArray) {
NSArray *attributes = [carInfoDictionary objectForKey:#"attributes"];
NSLog(#"%#", attributes);
}
In the NSLog from the above code shows this:
2016-11-03 10:21:26.029 CarWise[25766:1896339] (
{
name = "Engine Immobilizer";
value = "engine immobilizer";
},
{
name = "Power Door Locks";
value = "hands-free entry";
},
{
name = "Anti Theft Alarm System";
value = "remote anti-theft alarm system";
}
)
My main question is how can I access the name and value for each array? Let's say I want to create a UILabel that will have the string of one of the values?
Probably this will help
// Array as per the post
NSArray *attributes = (NSArray *)[carInfoDictionary objectForKey:#"attributes"];
// Loop to iterate over the array of objects(Dictionary)
for (int i = 0; i < attributes.count; i++) {
NSDictionary * dataObject = [NSDictionary dictionaryWithDictionary:(NSDictionary *)attributes[i]];
// This is the value for key "Name"
NSString *nameData = [NSString stringWithString:[dataObject valueForKey:#"name"]];
NSLog(#"Value of key : (name) : %#", nameData);
}

How to get JSON data parse from Arrays of dictionary iOS

list = ({
clouds = 24;
speed = "4.31";
temp = {
day = "283.84";
eve = "283.84";
night = "283.84";
};
}),
Please can anyone tell me what am I doing wrong - I want to display list-->temp-->day value in table first I am trying to get data in an array which is terminating.
Here is my code am I doing any wrong
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:dataBuffer options:-1 error:nil];
NSLog(#"%#",json);
NSMutableDictionary * list = [json objectForKey:#"list"];
NSMutableArray *arrays = [[NSMutableArray alloc]initWithCapacity:0];
for (NSDictionary *lists in [list allValues]) {
[arrays addObject:[list valueForKey:#"temp"]];
}
If you want to access day then use below line,
NSString *day = [json valueForKeyPath:#"list.temp.day"];
Your list is an array, so if you want to do your things without changing much, you can replace:
NSMutableDictionary * list = [json objectForKey:#"list"];
With:
NSMutableDictionary * list = [[json objectForKey:#"list"] objectAtIndex:0];

JSON parsing using NSJSONSerialization in iOS

I am parsing a JSON in my code. But I am getting some unexpected issues while retrieving data of parsed JSON. So let me explain my problem.
I have to parse following JSON data using xcode. This is what data to be parsed looks like while I hit same URL in browser:
{
"RESPONSE":[
{"id":"20",
"username":"john",
"email":"abc#gmail.com",
"phone":"1234567890",
"location":"31.000,71.000"}],
"STATUS":"OK",
"MESSAGE":"Here will be message"
}
My code to reach up to this JSON data is as follow:
NSData *data = [NSData dataWithContentsOfURL:finalurl];
NSError *error;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
If I print object json using NSLog, i.e. NSLog(#"json: %#", [json description]); it looks like:
json: {
MESSAGE = "Here will be message";
RESPONSE =(
{
email = "abc#gmail.com";
id = 20;
location = "31.000,71.000";
phone = 1234567890;
username = john;
}
);
STATUS = OK;
}
So, here I observed two things:
Sequence of keys (or nodes) (MESSAGE, RESPONSE and STATUS) is changed as compared to web response above.
The RESPONSE is get enclosed in '(' & ')' braces.
Now if I separate out values for keys MESSAGE & STATUS and NsLog them, then they get printed as proper string.
Like msgStr:Here will be message & Status:OK
But if I separate out value for RESPONSE as a dictionary and again separating sub values of that dictionary like email and username, then I can't getting those as string.
Here is the code so far I wrote:
NSMutableDictionary *response = [json valueForKey:#"RESPONSE"];
NSString *username = [response valueForKey:#"username"];
NSString *emailId = [response valueForKey:#"email"];
If I print username and emailId, then they are not getting printed as normal string, instead it outputs as:
username:(
john
)
email:(
abc#gmail.com
)
So my question is why it's not getting as a normal string? If I tried to use this variables further then they show value enclosed within '(' & ')' braces. Is this happening because of NSJSONSerialization?
First of all in your JSON response dictionary, under the key 'RESPONSE' you have a array not a dictionary and that array contains dictionary object.
So to extract username and email ID so as below
NSMutableDictionary *response = [[[json valueForKey:#"RESPONSE"] objectAtIndex:0]mutableCopy];
NSString *username = [response valueForKey:#"username"];
NSString *emailId = [response valueForKey:#"email"];
When you see braces like that, it represents an array, not a dictionary. Your JSON also shows that by enclosing the data in brackets ('[' and ']'). So:
RESPONSE =(
{
email = "abc#gmail.com";
id = 20;
location = "31.000,71.000";
phone = 1234567890;
username = john;
}
);
RESPONSE is an Array of Dictionaries. To access the data, iterate through the array:
for (NSDictionary *responseDictionary in [JSONDictionary objectForKey:#"RESPONSE"]) {
NSString *name = [responseDictionary objectForKey:#"username"];
.....
}
or grab a dictionary at an index:
NSDictionary *responseDictionary = [[JSONDictionary objectForKey:#"RESPONSE"] objectAtIndex:0];
NSString *name = [responseDictionary objectForKey:#"username"];
Whenever in doubt, log the the class:
NSLog(#"%#", [[dictionary objectForKey:#"key"] class]);
to see what is being returned from the dictionary.
1)Sequence of keys (or nodes) (MESSAGE, RESPONSE and STATUS) is
changed as compared to web response above.
The NSLog of NSDictionary is based on the sorted keys.
2)The RESPONSE is get enclosed in '(' & ')' braces.
RESPONSE =(
{
email = "abc#gmail.com";
id = 20;
location = "31.000,71.000";
phone = 1234567890;
username = john;
}
);
The RESPONSE is a key and the value is an NSArray. The array contains one NSDictionary object with keys as email, id, location, phone and username.
NOTE: () says array. {} says dictionary.
RESPONSE contains an array not an object.
So try like this:
NSMutableArray *response = [json valueForKey:#"RESPONSE"];
NSString *username = [[response objectAtIndex:0] valueForKey:#"username"];
NSString *emailId = [[response objectAtIndex:0] valueForKey:#"email"];
NSLog(#"User=>[%#] Pwd=>[%#]",username ,emailId );
pragma mark - Checking Reachability and Parsing Datas
NSString *urlString = [NSString stringWithFormat: #"https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=11.021459,76.916332&radius=2000&types=atm&sensor=false&key=AIzaSyD7c1IID7zDCdcfpC69fC7CUqLjz50mcls"];
NSURL *url = [NSURL URLWithString: urlString];
NSData *data = [NSData dataWithContentsOfURL:url];
NSDictionary *jsonData = [NSJSONSerialization JSONObjectWithData: data options: 0 error: nil];
array = [[NSMutableArray alloc]init];
array = [[jsonData objectForKey:#"results"] mutableCopy];
[jsonTableview reloadData];}
pragma mark- UITableView Delegate
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
return array.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellid = #"cell";
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:cellid];
cell = [[UITableViewCell
alloc]initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:cellid];
cell.textLabel.text = [[array
valueForKeyPath:#"name"]objectAtIndex:indexPath.row];
cell.detailTextLabel.text = [[array
valueForKeyPath:#"vicinity"]objectAtIndex:indexPath.row];
NSURL *imgUrl = [NSURL URLWithString:[[array
valueForKey:#"icon"]objectAtIndex:indexPath.row]];
NSData *imgData = [NSData dataWithContentsOfURL:imgUrl];
cell.imageView.layer.cornerRadius =
cell.imageView.frame.size.width/2;
cell.imageView.layer.masksToBounds = YES;
cell.imageView.image = [UIImage imageWithData:imgData];
return cell;
}
#import.h
#interface JsonViewController :
UIViewController<UITableViewDelegate,UITableViewDataSource>
#property (weak, nonatomic) IBOutlet UITableView *jsonTableview;
#property (weak, nonatomic) IBOutlet UIBarButtonItem *barButton;
#property (strong,nonatomic)NSArray *array;
#property NSInteger select;
By serializing the data, u get a json object. Json object and dictionary are different a bit.
Instead of using:
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
use:
NSDictionary *json = (NSDictionary*) data;

create NSArray with NSDictionary objects from macro

What I am trying to accomplish, I've one macro defined,
#define NAME_List #"a,aaa,aac,aacaaba,abbbb"
I'm converting this to NSArray using componentsSeperatedByString: its fine giving me array of NSString objects, instead I want NSDictionary objects, something like,
[0] -> "Name" = "a"
[1] -> "Name" = "aaa"
[2] -> "Name" = "aac""
& not like,
[0] - > a
[1] - > aaa
[2] - > aac
I tried this (but I don't have any idea for NSKeyedArchiver or NSPropertyListFormat or
NSPropertyListSerialization classes)
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:arrayNames];
NSError *error = nil;
NSPropertyListFormat plistFormat;
NSDictionary *temp = [NSPropertyListSerialization propertyListWithData:data options:NSPropertyListImmutable format:&plistFormat error:&error];
Update
I can iterate through array and create dictionary object and add it to array to do this, but I don't want to do it like this!
Is there any functions available which can do this?
NSMutableArray *resultArr = [NSMutableArray array];
NSArray *arr = [NAME_LIST componentsSeperatedByString:#","];
for(NSString *str in arr) {
NSDictionary *nameDictionary = [NSDictionary dictionaryWithObject:str forKey:#"Name"];
[resultArr addObject:nameDictionary];
}
NSLog(#"%#", resultArr);

TableViewController crashes when calling a retained property?

I have a Table View Controller and during its initialisation I set an NSArray property which is then used in the cellForRowAtIndexPath method to display the data on the table.
But, when I touch a row, once I call this retained NSArray property it says EXC_BAD_ACCESS!
FYI the property is defined as shown below, and uses a custom getter function:
#property (nonatomic,retain) NSArray *dataList;
and in the .m file:
#synthesize dataList;
- (NSArray *)dataList
{
if (!dataList)
{
NSString *p = [kind lowercaseString];
NSString *s = [[NSBundle mainBundle] pathForResource:p ofType:#"txt"];
NSLog(#"%#",s);
NSData *dataRep = [NSData dataWithContentsOfFile:s];
NSPropertyListFormat format;
dataList = [NSPropertyListSerialization propertyListFromData: dataRep
mutabilityOption: NSPropertyListImmutable
format: &format
errorDescription: nil];
if (dataList.count == 0)
NSLog(#"Fetch failed!");
}
return dataList;
}
Any suggestions?
This is the problem:
dataList = [NSPropertyListSerialization propertyListFromData ...
This function does not begin with alloc, copy, or retain, therefore it returns an autoreleased object. However, you need it to be retained so that it stays around.
You have two options:
self.dataList = [NSPropertyListSerialization propertyListFromData ...
or,
dataList = [[NSPropertyListSerialization propertyListFromData ...] retain];

Resources