Search code examples
objective-cxcodeios7parse-platformpresentmodalviewcontroller

Parse - warnParseOperationOnMainThread() error thrown when clicking on a picture


Basically followed this tutorial here https://parse.com/tutorials/saving-images . I got to the point where when a user clicks on an image, it would take them to a new view controller and display the image in full screen. When I click on the pictures though, it takes me to a black screen and it throws the following error

Warning: A long-running Parse operation is being executed on the main thread. 
 Break on warnParseOperationOnMainThread() to debug.

I checked and it's sending the picture to the new view controller so it might have to do with the VC itself. I put a breakpoint where it asked me to and here is what the thread says

`My App`warnParseOperationOnMainThread at PFTask.m:15:
0x95fa0:  pushl  %ebp
0x95fa1:  movl   %esp, %ebp
0x95fa3:  subl   $0x8, %esp
0x95fa6:  calll  0x95fab                   ; warnParseOperationOnMainThread + 11 at PFTask.m:15
0x95fab:  popl   %eax
0x95fac:  leal   0x18771d(%eax), %eax
0x95fb2:  movl   %eax, (%esp)
0x95fb5:  calll  0x98d54                   ; symbol stub for: NSLog
0x95fba:  addl   $0x8, %esp
0x95fbd:  popl   %ebp
0x95fbe:  retl  

The 5th thread points to a method called buttonTouched in one of my classes. And it points to this specific line of code:

imageData = [theImage getData];

Here is the method:

- (void)buttonTouched:(id)sender {
    // When picture is touched, open a viewcontroller with the image
    PFObject *theObject = (PFObject *)[allImages objectAtIndex:[sender tag]];
    PFFile *theImage = [theObject objectForKey:@"imageFile"];

    NSData *imageData = [[NSData alloc] init];
    imageData = [theImage getData];
    UIImage *selectedPhoto = [UIImage imageWithData:imageData];

    PhotoDetailViewController *pdvc = [[PhotoDetailViewController alloc] init];

    pdvc.selectedImage = selectedPhoto;
    [self presentViewController:pdvc animated:YES completion:nil];
    NSLog(@"Photo controller %@", pdvc.selectedImage);
}

It's driving me nuts. Everything is almost the same as the tutorial. Or do I need to define a segue relationship to the 2 VC? I'm using a storyboard if that is relevant at all.

A good explanation on how this happened and a solution would be awesome.


Solution

  • The warning is there because you are downloading the image in the main thread. You can download it in the background and present the view once the download is complete like below.

    - (void)buttonTouched:(id)sender {
        // When picture is touched, open a viewcontroller with the image
        PFObject *theObject = (PFObject *)[allImages objectAtIndex:[sender tag]];
        PFFile *theImage = [theObject objectForKey:@"imageFile"];
        [theImage getDataInBackgroundWithBlock:^(NSData *data, NSError *error) {
            UIImage *selectedPhoto = [UIImage imageWithData:imageData];
    
            PhotoDetailViewController *pdvc = [[PhotoDetailViewController alloc] init];
    
            pdvc.selectedImage = selectedPhoto;
            [self presentViewController:pdvc animated:YES completion:nil];
            NSLog(@"Photo controller %@", pdvc.selectedImage);
        }];
    }
    

    Another way to solve this could be instead of passing UIImage you can pass PFObject to the presented view and download the picture on that view once its loaded.