Julfikar
Julfikar

Reputation: 1423

Objective C JSON parse from NSMutableArray

I have a JSON like below (getting from an URL)-

{
action :getAllJournal;
data :{
    journalList :[{
            cancelled : F;
            "cust_code" : "700-T022";
            "journal_amount" : 2216;
            "journal_code" : "JV1603/001";
            "journal_date" : "2016-03-15 00:00:00";
            "journal_id" : 1;
            outstanding : 0;
        },
                    {
            cancelled : F;
            "cust_code" : "700-0380";
            "journal_amount" : 120;
            "journal_code" : "JV1605/006";
            "journal_date" : "2016-05-31 00:00:00";
            "journal_id" : 2;
            outstanding : 120;
        },
                    {
            cancelled : F;
            "cust_code" : "700-T280";
            "journal_amount" : 57;
            "journal_code" : "JV1609/001";
            "journal_date" : "2016-09-22 00:00:00";
            "journal_id" : 3;
            outstanding : 0;
        }
    ];
};
message = "";
"message_code" = "";
result = 1;}

The code below doing is getting the JSON from URL and storing them in NSMutableArray. Until storing them into array, it's working fine but I'm bit confused with the JSON format and don't know how to get result by a key.

__block NSMutableArray *jsonArray = nil;
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
NSString *urlString = [NSString stringWithFormat:@"http://xxxxxxx/api.php?action=getAllJournal"];
NSURLRequest * request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * response, NSData * data, NSError * connectionError)
 {
     if (data)
     {
         id myJSON;
         @try {
             myJSON = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
         }
         @catch (NSException *exception) {
         }
         @finally {
         }
         jsonArray = (NSMutableArray *)myJSON;

         NSString *nsstring = [jsonArray description];
         NSLog(@"IN STRING -> %@",nsstring);

         NSData *data = [nsstring dataUsingEncoding:NSUTF8StringEncoding];
         NSError *jsonError;
         NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&jsonError];
         if(jsonObject !=nil){

             if(![[jsonObject objectForKey:@"journalList"] isEqual:@""]){

                 NSMutableArray *array=[jsonObject objectForKey:@"journalList"];

                 NSLog(@"array: %lu",(unsigned long)array.count);

                 int k = 0;
                 for(int z = 0; z<array.count;z++){

                     NSString *strfd = [NSString stringWithFormat:@"%d",k];
                     NSDictionary *dicr = jsonObject[@"journalList"][strfd];
                     k=k+1;
                     // NSLog(@"dicr: %@",dicr);
                     NSLog(@"cust_code - journal_amount   : %@ - %@",
                           [NSMutableString stringWithFormat:@"%@",[dicr objectForKey:@"cust_code"]],
                           [NSMutableString stringWithFormat:@"%@",[dicr objectForKey:@"journal_amount"]]);
                 }

             }

         }else{
             NSLog(@"Error - %@",jsonError);
         }

     }
 }];

From this, I am able to get the JSON successfully. But it's always giving me this error: Error Domain=NSCocoaErrorDomain Code=3840 "No string key for value in an object around character 6." UserInfo={NSDebugDescription=No string key for value in an object around character 6.} How can I get all values from journalList? I'm new to iOS, that's why not sure what I'm missing.

Upvotes: 1

Views: 818

Answers (6)

Larme
Larme

Reputation: 26006

id myJSON;
 @try {
     myJSON = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
 }
 @catch (NSException *exception) {
 }
 @finally {
 }
 jsonArray = (NSMutableArray *)myJSON;

 NSString *nsstring = [jsonArray description];
 NSLog(@"IN STRING -> %@",nsstring);

 NSData *data = [nsstring dataUsingEncoding:NSUTF8StringEncoding];
 NSError *jsonError;
 NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&jsonError];

I'd say: NO and NO.

I wouldn't do a @try/@catch on a NSJSONSerialization, because the real issues are on the error parameter (and they won't throw a NSException for most of the cases). Just check if (data) is quite efficient.

Then, let's say it worked, and you have myJSON. In fact, myJSON is a NSDictionary, not a NSArray, so the cast is useless and doesn't make sense.

Next issue: Your are using -description (okay, if you want to debug), but you CAN'T use it to reconstruct AGAIN a JSON. It's not a valid JSON, it's the way the compiler "print" an object, it adds ";", etc. If your print [nsstring dataUsingEncoding:NSUTF8StringEncoding] and data you'll see that they aren't the same. For a more readable: NSString *dataJSONStr = [[NSString alloc] initWithData:data encoding: NSUTF8StringEncoding];, it's clearly not the same structure as your nsstring.

Then, you are redoing the JSON serialization? Why ?

So:

NSError *errorJSON = nil;
NSDictionary *myJSON = [NSJSONSerialization JSONObjectWithData:data options:0 error:&errorJSON];
if (errorJSON)
{
    NSLog(@"Oops error JSON: %@", errorJSON);
}
NSDictionary *data = myJSON[@"data"];
NSArray *journalList = data[@"journalList"]
for (NSDictionary *aJournalDict in journalList)
{
    NSUInteger amount = [aJournalDict[@"journal_amount"] integerValue];
    NSString *code = aJournalDict[@"journal_code"];
}

Upvotes: 3

Julfikar
Julfikar

Reputation: 1423

Thanks @Larme and @Amset for the help. I was doing wrong the in the NSMutableArray part. The correct version of this code is in the below:

[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
NSString *urlString = [NSString stringWithFormat:@"http://xxxxxxx/api.php?action=getAllJournal"];
NSURLRequest * request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * response, NSData * data, NSError * connectionError)
 {
     if (data)
     {
         id myJSON;
         @try {
             myJSON = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
         }
         @catch (NSException *exception) {
         }
         @finally {
         }

         NSArray *journalList = myJSON[@"data"][@"journalList"];
         for (NSDictionary *journal in journalList) {
             NSLog(@"%@ %@", journal[@"journal_date"], journal[@"journal_amount"]);
         }
     }
 }];

Upvotes: 0

Aditya Srivastava
Aditya Srivastava

Reputation: 2650

Looks like your JSON is invalid. You can see whether your JSON is correct or not using http://jsonviewer.stack.hu/ and moreover format it. Meanwhile your code is not using "data" key to fetch "journalList" array.

Code : -

NSDictionary *dic = [jsonObject valueForKey:@"data"];

NSMutableArray *arr = [dic objectForKey:@"journalList"];

for (int index=0 ; index < arr.count ; index++){

NSDictionary *obj = [arr objectAtIndex:index];

// Now use object for key from this obj to get particular key 

}

Upvotes: 0

Amset
Amset

Reputation: 86

There is a dictionary named "data" you're not fetching, represented by {}.

NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&jsonError];

if (!jsonError) {

    // Fetch the journalList
    NSArray *journalList = json[@"data"][@"journalList"];

    // iterate over every entry and output the wanted values
    for (NSDictionary *journal in journalList) {
        NSLog(@"%@ %@", journal[@"cust_code"], journal[@"journal_amount"]);
    }
}

json[@"key"] is a short form of [json objectForKey:@"key"] I find easier to read.

Upvotes: 1

Nirmalsinh Rathod
Nirmalsinh Rathod

Reputation: 5186

You need to fetch journalList from data.

Try below code:

This is demo code to create array like you:

NSMutableDictionary *jsonObject = [NSMutableDictionary new];
jsonObject[@"action"]= @"";
jsonObject[@"message"]= @"";
jsonObject[@"message_code"]= @"";
jsonObject[@"result"]= @"1";
NSMutableArray *ary1 = [NSMutableArray new];
for(int i=0;i<5;i++)
{
    NSMutableDictionary *dd = [NSMutableDictionary new];
    dd[@"cancelled"]= @"F";
    dd[@"cust_code"]= @"F";
    [ary1 addObject:dd];
}


NSMutableDictionary *dicjournal = [NSMutableDictionary new];
[dicjournal setObject:ary1 forKey:@"journalList"];
[jsonObject setObject:dicjournal forKey:@"data"];

This is main Logic:

NSMutableArray *journalList = [NSMutableArray new];
NSMutableDictionary *dic = [jsonObject valueForKey:@"data"];
journalList = [[dic objectForKey:@"journalList"] mutableCopy];

Upvotes: 0

mag_zbc
mag_zbc

Reputation: 6982

That is not a valid JSON. Entries should be separated by comma ,, not semicolon ;

Upvotes: 0

Related Questions