Ajil O. Ajil O. - 1 month ago 6
Objective-C Question

Assigning values to class instance from json output

I am working on a code to create an app where a set of questions and it's options and answer are being fetched by json parsing. I'm doing all this in the viewDidLoad method.

This is the code so far. The parsing code is working fine.

- (void)viewDidLoad {
[super viewDidLoad];
question *quest = [[question alloc] init];
//Parsing code

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:@"http://***/****/fetch.php"]];
[request setHTTPMethod:@"POST"];
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
[[session dataTaskWithRequest:request completionHandler:^(NSData *data , NSURLResponse *response , NSError *error){
NSError *err = nil;
id jsonData = [NSJSONSerialization JSONObjectWithData:data options:0 error:&err];
if (err) {
[self alertMessage:(@"%@", err)];
}
else {

//Unclear from here


NSLog(@"%@", jsonData[@"data"]);
allData = jsonData[@"data"];
NSLog(@"%lu",(unsigned long)allData.count);
int count = allData.count;
int i = 0;
while (i < count){
question *que;
NSString *q,*a,*o1,*o2,*o3,*o4;
a = [allData valueForKey:@"answer"];
q = [allData valueForKey:@"question"];
o1 = [allData valueForKey:@"option1"];
o2 = [allData valueForKey:@"option2"];
o3 = [allData valueForKey:@"option3"];
o4 = [allData valueForKey:@"option4"];

//NSLog(@"%@", [allData valueForKey:@"question"]);
[que setValue:q forKey:@"question"];
[que setValue:a forKey:@"answer"];
[que setValue:o1 forKey:@"option1"];
[que setValue:o2 forKey:@"option2"];
[que setValue:o3 forKey:@"option3"];
[que setValue:o4 forKey:@"option4"];
i++;

NSLog(@"%@",[que valueForKey:@"question"]);
}

}
}] resume];


}

Here's how the output of the
NSLog(@"%@", jsonData[@"data"]);
code looks like in the console.

{
answer = sometext;
id = 7;
option1 = sometext;
option2 = sometext;
option3 = sometext;
option4 = sometext;
question = "sometext";
},
{
answer = sometext;
id = 9;
option1 = sometext;
option2 = sometext;
option3 = sometext;
option4 = sometext;
question = "sometext";
}
)


As far as I understand this json data is an array of dictionary(?)

The next step I'm doing is I have created a "questions" class. I am not sure if I did it right but here's the code for that:

#import "question.h"
@implementation question {
NSString *q;
NSString *a;
NSString *o1;
NSString *o2;
NSString *o3;
NSString *o4;
}
@end


In the while loop in the
viewDidLoad
method i'm trying to create am instance of
question
class called
que
which I'm trying to populate as shown in the code.
But the line
NSLog(@"%@",[que valueForKey:@"question"]);
gives
null
in the console.

I'm sure it has got to be something wrong with the method I'm using.

The second problem is that I'm creating an array of
question
called
quest
which I'm declaring right after
viewDidLoad
. But then I wouldn't be able to use it in any other code blocks like the click event of a button. If I try to use the
question *quest = [[question alloc] init];
line above
viewDidLoad
it gives an error :

initialiser element is not a compile-time constant


I know that this is not the ideal way to code but I'm still a beginner here and am just confused with all these new concepts. I have developed the same app in Swift but Objective C feels too hard.
Any help would be appreciated.

Answer

To get what you wanted first of all you have to create an NSMutableArray which will store instance of Question Class, and you have to declare it as a Global Array like this

@interface MyClass ()  {
    NSMutableArray * arrQuestion;
}

Now, in question.h, you have to declare the @property for all the variables like this, also the question class will be derived from NSObject as you are creating it as a Model class

@interface question : NSObject
@property (nonatomic, strong) NSString *strQuestion;
@property (nonatomic, strong) NSString * strAnswer;
@property (nonatomic, strong) NSString * strOptionA;
@property (nonatomic, strong) NSString * strOptionB;
@property (nonatomic, strong) NSString * strOptionC;
@property (nonatomic, strong) NSString * strOptionD;  
@end

Now in the while loop you have to create new instance of your Question class and have to assign the value in it like this

arrQuestion = [NSMutableArray new];
while (i < count){
      question *quest = [[question alloc] init];
      quest.strQuestion = [[[jsonData objectForKey:@"data"]objectAtIndex:i] objectForKey:@"question"];
      quest.strAnswer = [[[jsonData objectForKey:@"data"]objectAtIndex:i] objectForKey:@"answer"];
      quest.strOptionA = [[[jsonData objectForKey:@"data"]objectAtIndex:i] objectForKey:@"option1"];
      quest.strOptionB = [[[jsonData objectForKey:@"data"]objectAtIndex:i] objectForKey:@"option2"];
      quest.strOptionC = [[[jsonData objectForKey:@"data"]objectAtIndex:i] objectForKey:@"option3"];
      quest.strOptionD = [[[jsonData objectForKey:@"data"]objectAtIndex:i] objectForKey:@"option4"];
      i++;
      [arrQuestion addObject:quest];
}

Now from arrQuestion you can access the values like this

question *quest = [arrQuestion objectAtIndex:0]; //For Example value at 0 index
NSLog(@"Value of first question - %@", quest. strQuestion);