Retrieving values from json using objective-c
Asked Answered
W

3

5

I am currently trying to work with json and objective-c however having a bit of difficulty. The following is the json that is being returned

{
    sethostname =     (
    {
        msgs = "Updating Apache configuration\nUpdating cPanel license...Done. Update succeeded.\nBuilding global cache for cpanel...Done";
        status = 1;
        statusmsg = "Hostname Changed to: a.host.name.com";
        warns =             (
        );
    });
}

I am able to check that the response is coming back and the key is sethostname however no matter what I try I cannot get for example the value of status or statusmsg. Can anyone point me in the right location. The following is basic code I am using to check that sethostname is returned.

NSError *myError = nil;
NSDictionary *res = [NSJSONSerialization JSONObjectWithData:response options:NSJSONReadingMutableLeaves error:&myError];
NSLog([res description]);
NSArray *arr;
arr = [res allKeys];
if ([arr containsObject:@"sethostname"])
{
    NSLog(@"worked");
}
Writhen answered 20/8, 2011 at 21:49 Comment(2)
What happens when you run this code? What if you just log res?Sarrusophone
when I run this code worked is displayed in the output however no matter what I try I cannot retrieve the value of status or any of the other sub keys.Writhen
U
11

When in doubt, write down the structure of your JSON data. For example:

{
    sethostname =     (
    {
        msgs = "Updating Apache configuration\nUpdating cPanel license...Done. Update succeeded.\nBuilding global cache for cpanel...Done";
        status = 1;
        statusmsg = "Hostname Changed to: a.host.name.com";
        warns =             (
        );
    });
}

(which is in NeXTSTEP property list format, actually) means that you have a top-level dictionary. This top-level dictionary contains a key called sethostname whose value is an array. This array is comprised of dictionaries, each dictionary having a set of keys: msgs, status, statusmsg, warns. msgs has a string value, status has a number value, statusmsg has a string value,warns` has an array value:

dictionary (top-level)
    sethostname (array of dictionaries)
        dictionary (array element)
            msgs (string)
            status (number)
            statusmsg (string)
            warns (array)
                ??? (array element)

Having understood this structure, your code should look like:

NSError *myError = nil;
NSDictionary *res = [NSJSONSerialization JSONObjectWithData:response options:NSJSONReadingMutableLeaves error:&myError];

if (!res) { // JSON parser failed }

// dictionary (top-level)
if (![res isKindOfClass:[NSDictionary class]]) {
    // JSON parser hasn't returned a dictionary
}

// sethostname (array of dictionaries)
NSArray *setHostNames = [res objectForKey:@"sethostname"];

// dictionary (array element)
for (NSDictionary *setHostName in setHostNames) {
    // status (number)
    NSNumber *status = [setHostName objectForKey:@"status"];

    // statusmsg (string)
    NSString *statusmsg = [setHostName objectForKey:@"statusmsg"];

    …
}
Unaffected answered 21/8, 2011 at 1:39 Comment(1)
Forgot to thank you for this reply. This answer pointed me in exactly the right direction and gave good methods for deciphering my results.Writhen
J
1

Why not use the simplest JSON method - [myString jsonValue];

It's part of this JSON framework for objective-c

Justiciable answered 20/8, 2011 at 21:55 Comment(2)
Hi Alex. what package is jsonValue a part of I am using the NSJSONSerialization which is a part of the foundation framework.Writhen
Ahh ok Alex, a different package. I had actually looked at using this before however I am using automatic reference counting and these packages have not been updated for this as of yet. That particular package did have a released version that worked but this was retracted as soon as he realised it did not work with reference counting turned off.Writhen
P
0

I don't think if ([arr containsObject:@"sethostname"]) is going to work, because the results array is not going to contain that exact object. It might contain an object with the same content, but it won't be the SAME object.

As jtbandes wrote, you need to log the actually output. NSLog both res and arr and see what you have.

Psychologist answered 20/8, 2011 at 21:59 Comment(3)
Hi Flyingdiver the keys from the original json are put into the array and the if statement checks if an object with the same value is in the array the if statement passes. I have checked this bit is working and it does appear to be (hence the nslog)Writhen
So, what do res and arr actually contain (NSLog output, please)?Psychologist
it looks like a part of the problem I was having is that I was wrong in what I thought they did contain. Bavarious Has cleared this up a bitWrithen

© 2022 - 2024 — McMap. All rights reserved.