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
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 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.
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.
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.
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"];
}
__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:
usingkey
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With