Search code examples
iosobjective-cios6parse-platformpfquery

Downloading images with parse causes unrecognized selector error


I am trying to download images from Parse and when I am finished downloading all images from parse my program crashes with the error:

NSNull getDataInBackgroundWithBlock:progressBlock:]: unrecognized selector sent to instance.

I have tried adding some conditions such as

if(![object objectForKey:@"goal_image"]) //If it is nil => exit

But it is still crashing. Here is my code:

        PFQuery *query = [PFQuery queryWithClassName:@"Goal"];

        [query getObjectInBackgroundWithId:[object objectId] block:^(PFObject *object, NSError *error) {

            if(!error)
            {
                PFFile * imageFile = [object objectForKey:@"goal_image"];
                if (imageFile) {

                    [imageFile getDataInBackgroundWithBlock:^(NSData *data, NSError *error2) {
                        if (!error2) {

                            NSString  *jpgPath = [NSHomeDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"Images/Goals/%@",[object objectId]]];
                            [data writeToFile:jpgPath atomically:YES];

                        }
                    } progressBlock:^(int percentDone) {
                        if (percentDone == 100) {
                            NSLog(@"Download Completed");
                        }

                    }];
                }
            }
        }];

Solution

  • tl;dr

    You should check for NSNull aside from checking for nil.

    PFFile * imageFile = object[@"goal_image"]; // note the modern Obj-C syntax
    if (imageFile && ![image isEqual:[NSNull null]]) {
        ...
    }
    

    Explanation

    NSNull is different from nil, the first one being an object.

    Since NSArray and NSDictionary only hold objects, nil cannot be stored in such containers and that's why NSNull is used, typically to represent a null value returned in the JSON response.

    Sending messages to nil fails silently, whereas sending an unrecognized selector to the NSNull singleton will result in a crash.

    Also remember that objectForKey: will return nil in case the key is not found in the dictionary.