-1

I am using the google places api to search for nearby restaurants. Each restaurant is displayed in a cell in a UITableView. The return response is in the JSON format. Of the the things the JSON contains is a decimal number that represents the rating of the restaurant. I want to display the rating in the cells. However sometimes there is no rating for the restaurant and the value is (null). So I added a check in the cellForRowAtIndexPath method that checks if the value of the rating is null or not.

if([dict valueForKey:kResponseRating] != [NSNull null])
{
    NSNumber *rating = [dict valueForKey:kResponseRating];
    [cell displayRating:rating];
}
else
{
    NSLog(@"Value of rating is null");
}

When I run the application the tableView still crashes as soon as a null value is returned and the string "Value of rating is null" is NOT printed. So its not going into the else statement even tho the value in the json is null.

Ok so I checked if the return value is of type NSString class and its not. Here is what i did in the same method:

if([[dict objectForKey:kResponseRating] isKindOfClass:[NSString class]])
{
    NSLog(@"The return response is of type NSString");
}

And it did not go into if statement.

Here is the method that calculates the rating and posts it. The method takes the rating rounds it to the nearest .5 and then displays it as stars out of 5.

-(void)displayRating:(NSNumber*)rating{

double rate = [rating doubleValue];


rate = round(rate * 2.0) / 2.0;


int counter = 0;
double compareVar = 1.0;

while(counter <= 4){

  if(rate == 0.0)
  {
      imgRating[counter] = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"starempty.png"]];
      [self.contentView addSubview:imgRating[counter]];
  }
  else
  {

    if(compareVar < rate)
    {
        imgRating[counter] = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"starfill.png"]];
        [self.contentView addSubview:imgRating[counter]];
    }
    else if(compareVar == rate)
    {
        imgRating[counter] = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"starfill.png"]];
        [self.contentView addSubview:imgRating[counter]];
    }
    else
    {
        if(compareVar - rate == 0.5)
        {
            imgRating[counter] = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"starhalffill.png"]];
            [self.contentView addSubview:imgRating[counter]];
        }
        else
        {
            imgRating[counter] = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"starempty.png"]];
            [self.contentView addSubview:imgRating[counter]];
        }

   }

    counter++;
    compareVar = compareVar + 1.0;

  }
}

   NSLog(@"This is rate: %f", rate);
}

Is a line of code in this method causing a crash?

Harsh.C
  • 83
  • 8
  • that if else condition works? i mean that check NSNull is works or not? – Nitin Gohel Apr 11 '16 at 13:42
  • I do not think so. It always goes into if statement even if the value is null. Also one thing the json returns a null with brackets around it, like (null). – Harsh.C Apr 11 '16 at 13:43
  • 4
    Show the complete crash log and stop using `valueForKey:`. – trojanfoe Apr 11 '16 at 13:44
  • 1
    to fetch information from dictionary use objectForKey – Yatendra Apr 11 '16 at 13:45
  • where did u put this code ? and what is the crash reason ? – Teja Nandamuri Apr 11 '16 at 13:45
  • yah that's the prob the null value is not a null class its s string object so you need to proper this conditin that have to check the value is empty. – Nitin Gohel Apr 11 '16 at 13:46
  • Where can I see the crash it is not in the debugger area in the bottom. Nitin Gohel so the value is a number but its not a NSNumber, its a string? The code is in the cellForRowAtIndexPath method. – Harsh.C Apr 11 '16 at 13:50
  • See here for setting exception breakpoint. http://stackoverflow.com/a/17802723/294949. It is unlikely that the valueForKey comparison with null is the location of the crash. – danh Apr 11 '16 at 13:57
  • Okay I added an exception breakpoint, the app crashes but no message is displayed, and there is no line highlighted to see line which caused crash. – Harsh.C Apr 11 '16 at 14:03
  • Then no one can help you as you haven't provided enough information. – trojanfoe Apr 11 '16 at 14:06
  • Okay let me post method that shows rating as well. – Harsh.C Apr 11 '16 at 14:10
  • Listen to trojanfoe and everyone else who tells you not to use valueForKey: unless you really, really know what you are doing. And temporary variables are your friend during debugging sessions. – gnasher729 Apr 11 '16 at 15:04
  • Okay using objectForKey from now on. – Harsh.C Apr 11 '16 at 15:11

2 Answers2

1

Try the below check

if(![dict objectForKey:kResponseRating] || [dict objectForKey:kResponseRating] == [NSNull null]) { 
    NSLog(@"Either the key doesn't exist or the value is null"); 
}
else {
    // Covert and set the rating here!
}
Vasanth
  • 420
  • 6
  • 17
  • 2
    An entry in a dictionary is highly unlikely to be equal to [NSNull class]. It might be equal to [NSNull null], but not [NSNull class]. And for [NSNull null] you don't need to compare with isEqual: , just use ==. Most likely this works because there is actually no value for the key. The code isn't going to recognise null in the JSON document. – gnasher729 Apr 11 '16 at 15:07
  • @gnasher729 that was one of those copy paste error. Thanks for pointing that out. – Vasanth Apr 11 '16 at 15:26
  • Completely unnecessary, just validate using `isKindOfClass:` instead of `isEqual` to `[NSNull Class]` – dmlebron Apr 14 '16 at 15:58
0

This should do it.

if ([[dictionary valueForKey:@"key"] isKindOfClass:[NSNull class]] || ![dict valueForKey:@"key"]){
   // Key doesn't exist or equals <null>
}
else{
// Key exist
}

And I'm pretty sure there are plenty of answers to this question on stack overflow. You should try looking if there is an answers to your question before creating a new one.

Anyway, I hope this helps

dmlebron
  • 861
  • 6
  • 16
  • In case of "key" doesn't exist in the dictionary this code will execute the else block. Try this scenario, `{"key1": "value 1"}` and you are searching for "key" It will say the value is not null, which is not true. – Vasanth Apr 14 '16 at 15:27
  • if the key doesn't exist in the dictionary, it will return null -> which is `[NSNull Class]`. Go ahead and try it... And before down voting you should first verify if it works, because obviously you don't know what you are talking about. – dmlebron Apr 14 '16 at 15:39
  • debug this code: NSDictionary *dict = @{@"key1" : @"value 1"}; if ([[dict valueForKey:@"key1"] isKindOfClass:[NSNull class]]) { //This means that the value inside the dictionary is NSLog(@"KEY EXIST"); } else{ //the value is not NSLog(@"DO NOT EXIST"); } after that, remove the downvote. – dmlebron Apr 14 '16 at 15:55
  • You misunderstood me, try to debug this code: `NSDictionary *dictionary = @{@"key1": @"Value 1"}; if ([[dictionary objectForKey:@"key"] isKindOfClass:[NSNull class]]) { NSLog(@"This is null"); } else { NSLog(@"This is not null"); }`. After that tell me if the solution works. – Vasanth Apr 14 '16 at 16:07
  • I copied/pasted the second option (key1) which enters the else, please, go ahead and run the same code you just sent. I tested it a few minutes ago (again) and it works. Let me know how it goes, and remember to remove the downvote after – dmlebron Apr 14 '16 at 16:20
  • Here is the proof that your code doesn't work, ![http://postimg.org/image/5s4781h3x](http://postimg.org/image/5s4781h3x) – Vasanth Apr 14 '16 at 16:35
  • and, you were right, I was missing `![dict valueForKey:@"key"]`. Please, verify edited answer. – dmlebron Apr 14 '16 at 16:43
  • Now you kind of copied my answer and down voted my answer, Interesting!! – Vasanth Apr 14 '16 at 18:02
  • I don't think this two are exactly the same: `(![dict objectForKey:kResponseRating] || [[dict objectForKey:kResponseRating] isEqual:[NSNull null]])` and `([[dictionary valueForKey:@"key"] isKindOfClass:[NSNull class]] || ![dict valueForKey:@"key"])`. Do you? Also, I will gladly remove the downvote, but I can't until you edit the answer. – dmlebron Apr 14 '16 at 18:23
  • Prove my solution doesn't work and I will change it. – Vasanth Apr 14 '16 at 19:05
  • When I say "I can't" is because stack overflow doesn't allow me to until you edit the answer. Make a minor edit and I will remove the downvote – dmlebron Apr 14 '16 at 19:20
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/109191/discussion-between-vasanth-and-dava). – Vasanth Apr 14 '16 at 19:44