I'm struggling to see why this code is not working. I have many other views using different JSON services. All working normally. However, this one is simply not. I retrieve the values back from the service as I expect however when trying to loop over it (see below code) the Array is Nil. Clearly something simple I have missed but I have been looking at this issue far to long.
Abstract View of JSON service;
{
"0": {
"altitude": "14500",
"latitude": "41.41555",
"longitude": "-73.09605",
"realname": "David KGNV"
},
"1": {
"altitude": "61",
"latitude": "33.67506",
"longitude": "-117.86739",
"realname": "Mark CT"
},
"10": {
"altitude": "38161",
"latitude": "40.51570",
"longitude": "-93.25554",
"realname": "Bob CYYZ"
},
"100": {
"altitude": "33953",
"latitude": "52.35600",
"longitude": "5.30384",
"realname": "Jim LIRQ"
}
}
Abstract view of the JSON call;
*Note the NSArray *currentMapArray valueKeyPath is set to "" as I need all elements within the JSON result.
NSError *_errorJson = nil;
jsonArray = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
if (_errorJson != nil) {
NSLog(#"Error %#", [_errorJson localizedDescription]);
} else {
//Do something with returned array
dispatch_async(dispatch_get_main_queue(), ^{
NSDictionary *mapJson = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
//Loop through the JSON array
NSArray *currentMapArray = [mapJson valueForKeyPath:#""];
//set up array and json call
mapArray = [[NSMutableArray alloc]init];
for (int i = 0; i< currentMapArray.count; i++)
{
//create our object
NSString *nAltitude = [[currentMapArray objectAtIndex:i] objectForKey:#"altitude"];
NSString *nRealname = [[currentMapArray objectAtIndex:i] objectForKey:#"realname"];
NSString *nLatitude = [[currentMapArray objectAtIndex:i] objectForKey:#"latitude"];
NSString *nLongitude = [[currentMapArray objectAtIndex:i] objectForKey:#"longitude"];
[mapArray addObject:[[LiveVatsimMap alloc]initWithaltitude:nAltitude andrealname:nRealname andlatitude:nLatitude andlongitude:nLongitude]];
}
The results of currentMapArray is NIL resulting the NSString not being filled out appropriately.
for (int i = 0; i< currentMapArray.count; i++)
Of course when I hard code the value of JSON node i.e. 10 into the ValueKeyPath then it provides the correct data results and populates accordingly.
Any ideas? Be nice...I'm only new at this objective c stuff.
Your JSON doesn't have an array - it is a dictionary of dictionaries.
You can iterate over it using
NSArray *keys=[jsonArray allKeys];
for (NSString *key in keys) {
NSDictionary *elementDictionary=jsonArray[key];
NSString *nAltitude = elementDictionary[#"altitude"];
NSString *nRealname = elementDictionary[#"realname"];
NSString *nLatitude = elementDictionary[#"latitude"];
NSString *nLongitude = elementDictionary[#"longitude"];
[mapArray addObject:[[LiveVatsimMap alloc]initWithaltitude:nAltitude andrealname:nRealname andlatitude:nLatitude andlongitude:nLongitude]];
}
Related
I have below JSON Format:
{
"Get_your_story_answer": [
{
"st_id": "19",
"story_title": "Newone",
"user_fb_id": "1649424812005217",
"winner_fb_id": "1685417121693688",
"winner_fb_id2": "",
"winner_fb_id3": "",
"story": "\ud83d\ude33\ud83d\ude25\ud83d\ude14\ud83d\ude0c",
"status": "1",
"s_created_date": "2016-01-18 23:06:05",
"reply_answer": [
{
"l_id": "42",
"story_id": "19",
"user_fb_id": "1649424812005217",
"selected_user_fb_id": "1685417121693688",
"answer": "hahaha",
"l_rating": "0",
"status": "1",
"l_created_date": "2016-01-18 23:10:51",
"l_new_created_date": "2016-01-19 11:40:51",
"winner": "1",
"answer_user_id": "3",
"answer_fb_id": "1685417121693688",
"answer_user_name": "Kin Patty"
},
{
"l_id": "43",
"story_id": "19",
"user_fb_id": "1649424812005217",
"selected_user_fb_id": "1498304680499454",
"answer": "",
"l_rating": "0",
"status": "1",
"l_created_date": "2016-01-18 23:06:05",
"l_new_created_date": "2016-01-19 11:36:05",
"winner": "0",
"answer_user_id": "10",
"answer_fb_id": "1498304680499454",
"answer_user_name": "John Kingman"
}
]
}
],
"status": "1",
"msg": "Get data"
}
Now I have to get Winner id
for Example "winner_fb_id" from [Get_your_story_answer] and compare it with [reply_answer].
If [reply_answer] contain "winner_fb_id" then I have to take only that name as winner .
Like in my Example , "Kin Patty"
I have tried this ,
//_getwind is mutable array
_getwinnerid =[NSMutableArray new];
_getwinnerid=[[_dataDictionary valueForKey:#"Get_your_story_answer"]valueForKey:#"winner_fb_id"];
Here is _getwinnerid output
<__NSArrayI 0x7ffb5a57c7b0>(
1685417121693688
NSArray *replaydata=[[_dataDictionary valueForKey:#"Get_your_story_answer"]valueForKey:#"reply_answer"];
Here is Replay Data Result
if (![replaydata containsObject:_getwinnerid]) {
NSLog(#"data");
}
Note:- Winner Id will be multiple. so, I have to compare 2 or more winner id and then take name from replay data response. And then I have to set name of winner in UITableview.
The value of Get_your_story_answer is an array, the requested data is in the first item of the array
NSDictionary *getYourStoryAnswer = _dataDictionary[#"Get_your_story_answer"][0];
Now get the winner ID and the array of answers
NSString *winnerID = getYourStoryAnswer[#"winner_fb_id"];
NSArray *answers = getYourStoryAnswer[#"reply_answer"];
Then enumerate the answers array (there are other solutions using blocks etc.)
for (NSDictionary *answer in answers) {
if ([answer[#"answer_fb_id"] isEqualToString: winnerID]) {
NSLog(#"%#", answer[#"answer_user_name"]);
break;
}
}
PS: Never use valueForKey to get one value for a key from a collection type unless you really need (and mean) the KVC method. The designated method is objectForKey or key subscription like above. valueForKey applied to an array returns always an array which is normally not intended.
for this you need to get total winner count from server.
like this.
int winnerCount = 3; //[Get_your_story_answer valueForKey:#"winner_count"];
Hopefully you have a fixed pattern key for winners like winner_fb_id, winner_fb_id1, winner_fb_id2 etc.
This will give you the desired result of winners name in array.
id response; // your response here
NSArray *array = [response objectForKey:#"Get_your_story_answer"];
NSDictionary *Get_your_story_answer = array[0];
NSMutableArray *winnersArray = [[NSMutableArray alloc] init];
int winnerCount = 3; //[Get_your_story_answer valueForKey:#"winner_count"];
for (int i = 0; i< winnerCount; i++) {
NSString *winnerId = nil;
if(i != 0){
winnerId = [Get_your_story_answer valueForKey:[NSString stringWithFormat:#"winner_fb_id%d",i]];
}
else{
winnerId= [Get_your_story_answer valueForKey:[NSString stringWithFormat:#"winner_fb_id"]];
}
if(winnerId)
{
[winnersArray addObject:winnerId];
}
}
__block NSMutableArray *resultArray = [[NSMutableArray alloc] init];
NSArray *replyAnswers = [Get_your_story_answer objectForKey:#"reply_answer"];
[replyAnswers enumerateObjectsUsingBlock: ^(id obj, NSUInteger idx, BOOL *stop) {
NSString *answer_fb_id = [obj valueForKey:#"answer_fb_id"];
[winnersArray enumerateObjectsUsingBlock: ^(NSString * winnerId, NSUInteger idx, BOOL *stop) {
if([winnerId isEqualToString:answer_fb_id]){
// get name of winner
[resultArray addObject:[obj valueForKey:#"answer_user_name"]];
}
}];
}];
// Your name of wiiners are in resultArray.
I have filtered array using the answer as said by larme Thank you.
NSError *errorJSON = nil;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&errorJSON];
if (!errorJSON)
{
NSDictionary *storyAnwser = [json[#"Get_your_story_answer"] firstObject];
NSArray *allAnswersKeys = [storyAnwser allKeys];
NSArray *allWinnersKeys = [allAnswersKeys filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(NSString * _Nonnull evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) {
return [evaluatedObject hasPrefix:#"winner_fb_id"];
}]];
NSLog(#"AllWinnersKeys: %#", allWinnersKeys);
NSArray *allWinnersIds = [storyAnwser objectsForKeys:allWinnersKeys notFoundMarker:[NSNull null]];
NSLog(#"AllWinnersIds: %#", allWinnersIds);
NSArray *allAnswers = storyAnwser[#"reply_answer"];
NSLog(#"AllAnswers: %#", allAnswers);
NSArray *allWinners = [allAnswers filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"answer_fb_id IN %#", allWinnersIds]];
NSLog(#"allWinners: %#", allWinners);
NSArray *allWinersNames = [allWinners valueForKey:#"answer_user_name"];
NSLog(#"AllWinnersNames: %#", allWinersNames);
}
else
{
NSLog(#"Error JSON: %#", errorJSON);
}
I am trying to parse the following json into my iOS code.
{
"test": [
{
"id": "21",
"lat": "53.343377977116916",
"long": "-6.2587738037109375",
"address": "R138, Dublin, Ireland",
"name": "td56",
"distance": "0.5246239738790947"
},
{
"id": "11",
"lat": "53.343377977116916",
"long": "-6.245641708374023",
"address": "68-130 Pearse Street, Dublin, Ireland",
"name": "test1",
"distance": "0.632357483022306"
}
]
}
I am able to view the full json in my logs with the following code:
NSURL *blogURL = [NSURL URLWithString:#"URLHERE"];
NSData *jsonData = [NSData dataWithContentsOfURL:blogURL];
NSError *error = nil;
NSDictionary *dataDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
NSDictionary *test = [dataDictionary objectForKey:#"test"];
NSLog(#"%#",dataDictionary);
if I change data dictionary to test in the log, I can display after the test root in my json , but if I try setup arrays to view, let's say the ID, the entire app will crash.
Could someone direct me in the right way to, let's say, display all the names in the NSLog? Each method I've tried has resulted in the application crashing.
Test is an array:
NSArray *test = [dataDictionary objectForKey:#"test"];
NSLog(#"test =%#", test);
for(NSDictionary *coordinates in test){
NSLog(#"id = %#", coordinates[#"id"]);
NSLog(#"lat = %#", coordinates[#"lat"]);
NSLog(#"long = %#", coordinates[#"long"]);
}
NSArray *array = [dataDictionary valueForKey:#"test"];
for(int i = 0; i < array.count; i++){
NSLog(#"%#", [array[i] valueForKey:#"name"]);
}
like that u can get NSLog whatever key you want
for id
NSLog(#"%#", [array[i] valueForKey:#"id"]);
for lat
NSLog(#"%#", [array[i] valueForKey:#"lat"]);
and so on.....
Happy coding
I'm new to ios development. Now I get a JSON file from server.
I use NSDictionary to get objects. When I debug, I could get "name", "address" values.
But I don't know how can I get all "dish" elements from "recommendation" Object? In java development, I know recommendation is an object, and "dish" is an array element. But I don't know what happen in ios.
{
"results": [
{
"name": "ollise",
"address": "columbia university",
"geo": [
{
"coordinates": 40
},
{
"coordinates": 70
}
],
"logo": "http:\/\/a0.twimg.com\/profile_images\/3159758591\/1548f0b16181c0ea890c71b3a55653f7_normal.jpeg",
"recommendation": [
{
"dish": "dish1"
},
{
"dish": "dish2"
}
],
}
]
}
By the way, in JSON, I store URL of an image in "logo", but I cannot get the value when debugging. Should I use some special format?
[Restaurant setname:[Dict objectForKey:#"name"]] // I could get name
[Restaurant setlogo:[Dict objectForKey:#"logo"]] // I can get nothing!
This is the way to do it
NSDictionary *response = [NSJSONSerialization JSONObjectWithData:yourData options:NSJSONReadingMutableLeaves error:nil];
NSDictionary *results = [[response objectForKey:#"results"] objectAtIndex:0];
NSString *name = [response objectForKey:#"name"];
//... get other objects
NSArray *recommendation = [results objectForKey:#"recommendation"];
NSDictionary *recommendation1 = [recommendation objectAtIndex:0];
NSDictionary *recommendation2 = [recommendation objectAtIndex:1];
NSString *dish = [recommendation1 objectForKey#"dish"];
NSString *dish1 = [recommendation2 objectForKey#"dish"];
[Restaurant setname:name];
NSString *logo = [results objectForKey:#"logo"];
[Restaurant setlogo:logo];
The results is the same dictionary as the one in the JSON. Treat anything with braces ({}) as an NSDictionary and brackets ([]) as an NSArray. dish is not an array element, it is a key in a dictionary that is an array element.
I have a simple json format with an array within an array, but I can't figure out how to get the inner array. How do I grab the "Commute" tag as an NSArray or a NSDictionary?
Here is my json:
{
"Language": "EN",
"Place": [
{
"City": "Stockholm",
"Name": "Slussen",
"Commute": [
"Subway",
"Bus"
]
},
{
"City": "Gothenburg",
"Name": "Central station",
"Commute": [
"Train",
"Bus"
]
}
]
}
Here is my code:
NSString *textPath = [[NSBundle mainBundle] pathForResource:#"Places" ofType:#"json"];
NSError *error;
NSString *content = [NSString stringWithContentsOfFile:textPath encoding:NSUTF8StringEncoding error:&error]; //error checking omitted
NSData *jsonData = [content dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:jsonData
options:kNilOptions
error:&error];
NSArray* AllPlaces = [json objectForKey:#"Place"];
for(int n = 0; n < [AllPlaces count]; n++)
{
PlaceItem* item = [[PlaceItem alloc]init];
NSDictionary* place = [AllPlaces objectAtIndex:n];
item.City = [place objectForKey:#"City"];
item.Name = [place objectForKey:#"Name"];
NSDictionary* commutes = [json objectForKey:#"Commute"];
[self.placeArray addObject:(item)];
}
Your code should be:
NSArray* commutes = [place objectForKey:#"Commute"];
Thwt would give back an array holding "Subway" and "Bus".
I think the problem is the access to json, it should be place instead:
NSArray* commutes = [place objectForKey:#"Commute"];
NSArray *commutes = [place objectForKey:#"Commute"];
This will give you an NSArray with "Subway" and "Bus".
You can considerably shrink you code using KVC Collection Operators:
NSArray *commutes = [json valueForKeyPath:#"Place.#distinctUnionOfArrays.Commute"];
If you want all repeated commutes use #unionOfArrays modifier.
I'm trying to get values from nsdata class and doesn't work.
here is my JSON data.
{
"count": 3,
"item": [{
"id": "1",
"latitude": "37.556811",
"longitude": "126.922015",
"imgUrl": "http://175.211.62.15/sample_res/1.jpg",
"found": false
}, {
"id": "3",
"latitude": "37.556203",
"longitude": "126.922629",
"imgUrl": "http://175.211.62.15/sample_res/3.jpg",
"found": false
}, {
"id": "2",
"latitude": "37.556985",
"longitude": "126.92286",
"imgUrl": "http://175.211.62.15/sample_res/2.jpg",
"found": false
}]
}
and here is my code
-(NSDictionary *)getDataFromItemList
{
NSData *dataBody = [[NSData alloc] initWithBytes:buffer length:sizeof(buffer)];
NSDictionary *iTem = [[NSDictionary alloc]init];
iTem = [NSJSONSerialization JSONObjectWithData:dataBody options:NSJSONReadingMutableContainers error:nil];
NSLog(#"id = %#",[iTem objectForKey:#"id"]);
//for Test
output = [[NSString alloc] initWithBytes:buffer length:rangeHeader.length encoding:NSUTF8StringEncoding];
NSLog(#"%#",output);
return iTem;
}
how can I access every value in the JSON? Please help me.
look like this ..
NSString *jsonString = #"your json";
NSData *JSONdata = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSError *jsonError = nil;
if (JSONdata != nil) {
//this you need to know json root is NSDictionary or NSArray , you smaple is NSDictionary
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:JSONdata options:0 error:&jsonError];
if (jsonError == nil) {
//every need check value is null or not , json null like ( "count": null )
if (dic == (NSDictionary *)[NSNull null]) {
return nil;
}
//every property you must know , what type is
if ([dic objectForKey:#"count"] != [NSNull null]) {
[self setCount:[[dic objectForKey:#"count"] integerValue]];
}
if ([dic objectForKey:#"item"] != [NSNull null]) {
NSArray *itemArray = [dic objectForKey:#"item"]; // check null if need
for (NSDictionary *itemDic in itemArray){
NSString *_id = [dic objectForKey:#"id"]; // check null if need
NSNumber *found = (NSNumber *)[dic objectForKey:#"found"];
//.....
//.... just Dictionary get key value
}
}
}
}
I did it by using the framework : http://stig.github.com/json-framework/
It is very powerfull and can do incredible stuff !
Here how I use it to extract an item name from an HTTP request :
(where result is the JSO string)
NSString *result = request.responseString;
jsonArray = (NSArray*)[result JSONValue]; /* Convert the response into an array */
NSDictionary *jsonDict = [jsonArray objectAtIndex:0];
/* grabs information and display them in the labels*/
name = [jsonDict objectForKey:#"wine_name"];
Hope this will be helpfull
Looking at your JSON, you are not querying the right object in the object hierarchy. The top object, which you extract correctly, is an NSDictionary. To get at the items array, and the single items, you have to do this.
NSArray *items = [iTem objectForKey:#"item"];
NSArray *filteredArray = [items filteredArrayUsingPredicate:
[NSPredicate predicateWithFormat:#"id = %d", 2];
if (filteredArray.count) NSDictionary *item2 = [filteredArray objectAtIndex:0];
Try JSONKit for this. Is is extremely simple to use.
Note sure if this is still relevant, but in iOS 5, apple added reasonable support for JSON. Check out this blog for a small Tutorial
There is no need to import any JSON framework. (+1 if this answer is relevant)