Hey I'm new to iPhone and I have been trying to parse the below JSON for displaying different types of Survey using my below code. I have two tables, in first table i want to display all the "Surveys_title" text value, and once user will tap on any survey title row then it should display their particular question and question ID in my second table. Like i have two questions for "Survey1" and three questions for "Survey2". Using my code, i am able to display all survey titles in my first table but i am getting problem that how to store array of objects for all the survey types individually. here, I have created one custom class "Survey". Thank you for any help you can give me.
JSON :
{
"Surveys": [
{
"Surveys_title": "Survey1",
"Questions": [
{
"event_sq_qns_id": 1,
"questions": "What is your primary job title/focus?"
},
{
"event_sq_qns_id": 2,
"questions": "Effectiveness of the speakers?"
}
]
},
{
"Surveys_title": "Survey2",
"Questions": [
{
"event_sq_qns_id": 3,
"questions": "What is this?"
},
{
"event_sq_qns_id": 4,
"questions": "Who are you?"
},
{
"event_sq_qns_id": 5,
"questions": "what is your name?"
}
]
},
{
"Surveys_title": "Survey3",
"Questions": [
{
"event_sq_qns_id": 6,
"questions": "What is your primary job?"
},
{
"event_sq_qns_id": 7,
"questions": "Effectiveness of the speakers?"
}
]
}
]
}
here is my code :
#import <Foundation/Foundation.h>
#interface Surveys : NSObject
#property (nonatomic, retain) NSString *surveys_question_id;
#property (nonatomic, retain) NSString *questions;
#end
- (void) fetchingSurveyQuestionsFromServer
{
[MBProgressHUD showHUDAddedTo:self.view animated:YES];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
NSDictionary *results;
#try {
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"survey" ofType:#"json"];
NSData *responseData = [NSData dataWithContentsOfFile:filePath];
//parse the json data
NSError *error;
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:responseData
options:kNilOptions
error:&error];
results= [json objectForKey:#"Surveys"];
}
#catch (NSException *exception) {
NSLog(#"Exception in %s %#",__FUNCTION__,exception);
}
dispatch_async (dispatch_get_main_queue (),
^{
arraySurveys = [[NSMutableArray alloc] init];
arraySurveys_type = [[NSMutableArray alloc] init];
NSString *surveys_title_name;
for (NSDictionary *dict in results) {
NSDictionary *questionDict = dict[#"Questions"];
surveys_title_name = dict[#"Surveys_title"];
NSLog(#"Questions dictionary = %#", questionDict);
NSLog(#"Survey type is = %#", surveys_title_name);
for (NSDictionary *dict1 in questionDict) {
Surveys *surveys = [[Surveys alloc] init];
surveys.surveys_question_id = [dict1 objectForKey:#"event_sq_qns_id"];
surveys.questions = [dict1 objectForKey:#"survey_questions"];
[arraySurveys addObject:surveys];
}
[arraySurveys_type addObject:surveys_title_name];
}
[MBProgressHUD hideHUDForView:self.view animated:YES];
[tblSurveys reloadData];
});
});
}
Using above code, all the questions are adding directly to the arraySurveys. please help me how can i differentiate according to the Surveys title.
Thanks.
Use like this ....
SBJSON *json = [[SBJSON alloc] init];
NSMutableDictionary *jsonObject = [json objectWithString:response ];
NSMutableArray *Surveys=[jsonObject valueForKey:#"Surveys"];
NSMutableArray * Surveys_title =[[NSMutableArray alloc]init];
NSMutableArray * Questions =[[NSMutableArray alloc]init];
for (NSDictionary *dictnory in Surveys) {
[Surveys_title addObject:[dictnory objectForKey:#"Surveys_title"]];
[Questions addObject:[dictnory objectForKey:#"Questions"]];
}
Related
I am using the Mantle framework in iOS for a simple JSON structure that looks like this:
{
"posts":
[
{
"postId": "123",
"title": "Travel plans",
"location": "Europe"
},
{
"postId": "456",
"title": "Vacation Photos",
"location": "Asia"
}
],
"updates": [
{
"friendId": "ABC123"
}
]
}
Essentially I am only interested in the "posts" key and wish to completely ignore the "updates" key. Additionally within the "posts" array I wish to completely ignore the "location" key. Here is how I set up my Mantle Models:
#interface MantlePost: MTLModel <MTLJSONSerializing>
#property (nonatomic, strong) NSString *postId;
#property (nonatomic, strong) NSString *title;
#end
#implementation MantlePost
+ (NSDictionary *)JSONKeyPathsByPropertyKey {
return #{
#"postId": #"postId",
#"title": #"title",
};
}
#end
And here is my MantlePosts model:
#interface MantlePosts: MTLModel<MTLJSONSerializing>
#property (nonatomic, strong) NSArray<MantlePost *> *posts;
#end
#implementation MantlePosts
+ (NSDictionary *)JSONKeyPathsByPropertyKey {
return #{
#"posts": #"posts"
};
}
+ (NSValueTransformer *)listOfPosts {
return [MTLJSONAdapter arrayTransformerWithModelClass:MantlePost.class];
}
#end
Finally, here is how I load my JSON up to be converted:
- (NSDictionary *)loadJSONFromFile {
NSString *jsonPath = [[NSBundle mainBundle] pathForResource:#"parse-response" ofType:#"json"];
NSError *error = nil;
NSData *jsonData = [[NSString stringWithContentsOfFile:jsonPath usedEncoding:nil error:&error] dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableLeaves error:&error];
return jsonDict;
}
NSError = nil;
NSDictionary *jsonData = [self loadJSONFromFile];
MantlePosts *posts = (MantlePosts *)[MTLJSONAdapter modelOfClass:MantlePosts.class fromJSONDictionary:jsonData error:&error];
The problem is, my descendent array of MantlePosts contains all 3 properties postId, title, and location, when I explicitly mapped only postId and title. The "updates" array is ignored which is what I wanted but I've been stuck being able to ignore certain keys in the descendent arrays. Any help on this would be appreciated.
Here is an example of what I receive when i po the response in the console.
(lldb) po posts
<MantlePosts: 0x6000000153c0> {
posts = (
{
location = Europe;
postId = 123;
title = "Travel plans";
},
{
location = Asia;
postId = 456;
title = "Vacation Photos";
}
);
}
(lldb)
I have a NSArray which is based on JSON format. I requested it from the web and saved it in the array. I am trying to use a dictionary to get the values of "categoryname" and "subscore" and store them in new arrays, but they remain empty. Do I have to convert the array back to NSData using JSON serialisation or is there a more direct way to achieve this?
NSArray detailedscore:
{
"articles": [
{
"abstract": "text",
"title": "title"
}
],
"subscore": 3,
"categoryname": "Reporting"
},
{
"articles": [
{
"abstract": "text2",
"title": "title"
}
],
"subscore": 1,
"categoryname": "Power"
}]
}
Code:
for(int i = 0; i < [self.detailedscore count]; i++)
{
NSMutableDictionary * dc = [self.detailedscore objectAtIndex:i];
NSString * score = [dc objectForKey:#"subscore"];
NSString * categoryname = [dc objectForKey:#"categoryname"];
[self.allscores addObject:subscore];
[self.allcategories addObject:categoryname];
for (NSString *yourVar in allcategories) {
NSLog (#"Your Array elements are = %#", yourVar);
}
{} ----> means dictionary, []---> array..... this is a rule I follow while assinging the return value from webservices as NSArray or NSDictionary....
Depending on your current JSON format, perhaps this might give you an idea
NSMutableArray *categoryArray = [NSMutableArray new];
for (NSDictionary *childDict in self.detailedscore)
{
[categoryArray addObject:[childDict objectForkey:#"categoryname"]];
}
If you have the array use below code
for(int i = 0; i < [self.detailedscore count]; i++)
{
NSMutableDictionary * dc = [self.detailedscore objectAtIndex:i];
NSString * score = [dc objectForKey:#"subscore"];
NSString * categoryname = [dc objectForKey:#"categoryname"];
[self.allscores score];
[self.allcategories addObject:categoryname];
for (NSString *yourVar in allcategories) {
NSLog (#"Your Array elements are = %#", yourVar);
}
The problem wasn't in the array or dictionary or the web request. I didn't allocated the NSMutableArrays so they were empty all the time. The code works fine for extracting values from the array in case anyone wants to use it.
Hope this helps.
[NSURLConnection sendAsynchronousRequest:req queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (!connectionError) {
NSDictionary *dict=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&connectionError];
NSLog(#"Dict %#",dict);
BOOL isValid = [NSJSONSerialization isValidJSONObject:dict];
if (isValid) {
[target getJSONFromresponseDictionary:dict forConnection:strTag error:connectionError];
}
else{
NSString *strResponse = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
[target getStringFromresponseDictionary:strResponse forConnection:strTag error:error];
}
i am getting the response from the server in JSON array form like below :
{
"status": "success",
"data": [
{
"auth_Secret_ticket_refresh": "NULL",
"userId": "10632",
"loginEmail": "Raushan#gmail.com",
"auth_authorizationCode": "4cb8c5e8a7f5",
"accountType": "flickr",
"auth_Token": "23104658-d2e65d5f94554652",
"userName": "betterlabpune",
"auth_subdomain": "NULL"
},
{
"auth_Secret_ticket_refresh": "NULL",
"userId": "19629",
"loginEmail": "Ipad#gmail.com",
"auth_authorizationCode": "8b909cb3e0e1",
"accountType": "flickr",
"auth_Token": "77645323118718-bac668bc2b95ad89",
"userName": "betterlabpune",
"auth_subdomain": "NULL"
}
]
}
I want to extract the value from JSON array for the 0 index, value for "userId" and "userName".
i had tried to extract values in many ways ,below is my code:
NSMutableData * _responseData = [[NSMutableData alloc]init];
[_responseData appendData:data];
NSJSONSerialization *dataAsString=(NSJSONSerialization*)[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
// dataJson=(NSDictionary*)[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"data in register reponse : %#",dataAsString);
NSJSONSerialization *json;
NSDictionary *dataJson;
NSError *error;
NSDictionary *JSONE = [NSJSONSerialization JSONObjectWithData:_responseData options:0 error:nil];
NSLog(#"JSONE : %#",JSONE);
json=[NSJSONSerialization JSONObjectWithData:_responseData
options:NSJSONReadingMutableLeaves
error:&error];
[self processData:dataJson];
dataJson=[[NSDictionary alloc]init];
dataJson=(NSDictionary *)json;
NSString * status=[dataJson objectForKey:#"status"];
NSString * message=[[dataJson objectForKey:#"data"]objectForKey:#"id"];
NSLog(#"status : %#",status);
NSLog(#"message: %#",message);
NSMutableArray *argsArray = [[NSMutableArray alloc] init];
argsArray= [dataJson valueForKeyPath:#"status"];
NSLog(#" client Id : %#", [argsArray objectAtIndex:0]);
bet every time i get null in my result.
Please help me out.
Thank you for your precious time.
try this...
if ([[dataJson valueForKey:#"status"]isEqualToString:#"success"])
{
NSMutableArray *tempArray=[NSMutableArray array];
for (NSDictionary *tempDic in [dataJson valueForKey:#"data"])
{
[tempArray addObject:[tempDic valueForKey:#"userId"]];
}
NSLog(#"%#",tempArray);
}
This question already has answers here:
MagicalRecord importFromObject: JSON with dictionary?
(2 answers)
Closed 8 years ago.
I have this JSON document:
[
{
"category": "Para los invitados",
"items": [
{
"title": "Invitaciones",
"subtitle": "Sobres, imprenta",
"items": [
"Invitaciones",
"Sobres",
"Coste envío invitaciones",
"Tarjetas de agradecimiento",
"Sobres para tarjetas de agradecimiento",
"Coste de envío tarjetas de agradecimiento"
]
},
<three elements more...>
]
},
<two elements more...>
]
How can I import this document using MagicalRecord ? Can anyone paste an example ?
Thanks!
If you have finished a Core Data Model and included Magical Record, you can parse the JSON File:
// Your Json File
NSURL *url = [NSURL URLWithString:#"YOUR_JSON"];
NSData* data = [NSData dataWithContentsOfURL: url];
NSError *error; // For later error handling
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
// Json values for "items" key
NSDictionary *items = [json valueForKey:#"items"];
// We are going through the items
for(int i = 0; i < [items count]; i++) {
// We save the title values into our CoreData Model
NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread];
NSString *title = [[items valueForKey:#"title"] objectAtIndex:i];
YOUR_MODEL_ENTITY *entity = [YOUR_MODEL_ENTITY MR_createInContext:localContext];
entity.title = title;
// We save it
[localContext MR_saveToPersistentStoreWithCompletion:^(BOOL success, NSError *error) {
if (error) {
NSLog(#"Couldn't save new title with Magical Record: %#", error);
}
}];
}
I hope that it's right, what I wrote...
Please have a look on the documentation :)
I have two classes that define Video and Cue objects. I get my data through an JSON API. The backend is written in Rails and has a one-to-many relationship between Video and Cues.
The data I get is structured like this:
{ "true":
[
{
"id" : 3,
"title" : "My Title"
[
{ "cues":
[
{
"id": 117,
"time" : "12.81",
"video_id" : 3
},
{
"id": 118,
"time" : "14.34",
"video_id" : 3
}
]
}
]
}
]
}
I have a method in Video.m that gets the JSON array, puts it in a dictionary and converts the dictionary to an array of Video objects.
+(id) getVideos {
NSURL *videoURL = [NSURL URLWithString:#"http://localhost:3000/myEndPoint"];
NSData *jsonData = [NSData dataWithContentsOfURL:videoURL];
NSError *error = nil;
NSDictionary *videoDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
NSMutableArray *videos = [NSMutableArray array];
for (NSDictionary *dict in videoDictionary[#"true"]) {
NSString *title = [dict objectForKey:#"title"];
Video *newVideo = [[Video alloc] initWithTitle:title];
[videos addObject: newVideo];
}
return videos;
}
How should I format the cues so that I can get specific cues from a Video, like in a relational sort of way if possible, if not then just the best practise. In Rails it would be video.cues. Can I do this in Objective C?
Would be perfect if I could end up having the ability to do something like:
Cue *currentCue = video.cues[0];
Add a property to your Video class: NSArray *cues. And change your init method to initWithTitle:(NSString*)title andCues:(NSArray*)cues. That way you'll be able to do exactly that: video.cues[0]