Reputation: 272
I am doing an HTTP call to my web server via objective-c app. The server returned json usually looks like this:
{
"name": "test",
"surname": "test",
}
but sometimes, when I am requesting a list of something, I get the JSON like this:
[
{ "name": "test" },
{ "name": "test" },
]
Now, I am handling the returned object as NSDictionary this way:
NSDictionary *results = [http doRequestWithData:@{ @"tag": @"whatever" } atUrl:@"/search"]
NSLog(@"%@", results);
I have omitted the implementation of doRequestWithData for simplicity, because the interesting part of it is that when I do an NSLog of data, I get the following:
(
{
"_id" = 5353c332339a5ea32e000008;
content = "i am the first search result";
},
{
"_id" = 5353c32b339a5ea32e000007;
content = "I am the second";
},
{
"_id" = 5353c31c339a5ea32e000006;
content = "third";
},
)
Can anyone explain how this can happen? The returned data is an NSDictionary, but from the console it seems just like an array, as I cannot see the keys!
UPDATE: I am using NSJSONSerialization in my http class to serialize the object. The docs say it may return either a dict or an array based on the data. but the problem is that I am clearly defining it as NSDictionary! Shouldn't this at least throw and error? This is what I am using in my http class to define the returned nsdictionary:
NSDictionary *responseDict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
return responseDict;
Upvotes: 0
Views: 88
Reputation: 1972
Your best bet is to do your own type checking on returned value using isKindOfClass:
.
NSData *data = ...;
NSError *__autoreleasing jsonError;
NSDictionary *dictionary = data ? [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&jsonError] : nil;
if (jsonError || ![dictionary isKindOfClass:[NSDictionary class]])
dictionary = nil;
You may want to do more handling than this, but this at least ensures you'll never access the wrong object type.
Upvotes: 0
Reputation: 130102
Unlike Java (and similar languages), there is no runtime type checking in Obj-C.
If your method returns a NSArray
and you store it into a NSDictionary
, it's not a problem for Obj-C. Until you try to call a method which is not defined for NSArray
(e.g. objectForKey:
).
Usually, such problems should be cought at compile time, however
+[NSJSONSerialization JSONObjectWithData:...]
returns an id
(it can return either NSArray
or NSDictionary
) and id
is compatible with any type.
Upvotes: 1