Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What means __NSSingleObjectArrayI in Objective C? when I try to read a Json

I have this code Json format:

{
    "weather": [{
        "description": "clear sky",
        "icon": "01n"
    }],
    "base": "stations",
    "main": {
        "temp": 285.514
    },
    "clouds": {
        "all": 0
    },
    "dt": 1485792967,
    "id": 1907296
}

And I want to retrive icon string (01n)

And use this code:

@property(nonatomic,strong) NSString *cityImageName;

self.cityImageName = [[dataJson valueForKey:@"weather"] valueForKey:@"icon"];

And later when I check the variable print:

<__NSSingleObjectArrayI 0x604000009890>(
01n
)

Finally how can I get the string directly? not like a __NSSingleObjectArrayI

like image 958
Fabio Avatar asked Oct 25 '17 18:10

Fabio


People also ask

How to declare an array in Objective-C?

To declare an array in Objective-C, a programmer specifies the type of the elements and the number of elements required by an array as follows − This is called a single-dimensional array. The arraySize must be an integer constant greater than zero and type can be any valid Objective-C data type.

What does NS mean in Objective-C?

What is ns in objective-c? The original code for the Cocoa frameworks came from the NeXTSTEP libraries Foundation and AppKit (those names are still used by Apple's Cocoa frameworks), and the NextStep engineers chose to prefix their symbols with NS What does the "@" symbol mean in Objective-C? It's a way to introduce an "objective-c" literal.

What is the use of NSString and NSNumber in Objective C?

It’s common in Objective-C to use Cocoa or Cocoa Touch classes to represent values. The NSString class is used for strings of characters, the NSNumber class for different types of numbers such as integer or floating point, and the NSValue class for other values such as C structures.

How does the Objective-C language work?

In addition to the compiler, the Objective-C language uses a runtime system to enable its dynamic and object-oriented features. Although you don’t usually need to worry about how Objective-C “works,” it’s possible to interact directly with this runtime system, as described by Objective-C Runtime Programming Guide and Objective-C Runtime Reference.


2 Answers

You got caught in the Key-Value Coding Trap.

valueForKey has a special behavior. Applied to an array it returns always an array of all values for the given key.

Never use valueForKey unless you intend to use KVC. The recommended syntax is objectForKey or – preferable – key subscription and in case of the array index subscription.

In this case you want to get the value for key icon of the first item in the array for key weather.

self.cityImageName = dataJson[@"weather"][0][@"icon"];

However I would add a check if the array is not empty to avoid an out-of-range exception

NSArray *weather = dataJson[@"weather"];
if (weather && weather.count > 0) {
    self.cityImageName = weather[0][@"icon"];
}
like image 98
vadian Avatar answered Nov 15 '22 07:11

vadian


__NSSingleObjectArrayI is one of the implementations of the NSArray class cluster. It's not really important to this question other than knowing that it's an array.

The reason you're getting an array (of one element) instead of a string is because the JSON you're working with contains an array with one dictionary inside of it:

"weather": [{
    "description": "clear sky",
    "icon": "01n"
}],

Note: the square brackets surrounding the curly brackets.

So, when you call [dataJson valueForKey:@"weather"] you get back the object that represent this part of the JSON:

[ { "description": "clear sky", "icon": "01n" } ]

Which is in this case has been decoded as an NSArray containing one NSDictionary with two keys.

When you then call valueForKey: on that array it

Returns an array containing the results of invoking valueForKey: using key on each of the array's objects.

In other words, because [dataJson valueForKey:@"weather"] is an array of one dictionary, [[dataJson valueForKey:@"weather"] valueForKey:@"icon"] is an array of only the value for the "icon" key in that dictionary.

If the JSON you're working with always has this format, then you can get the firstObject from the array to get a hold of the first string (or nil if the array was empty).

like image 40
David Rönnqvist Avatar answered Nov 15 '22 07:11

David Rönnqvist