views:

141

answers:

4

I have a simple iPhone application.
I display a UIImagePicker, and let the user select an image.
I then execute some code on the image, and want this code to execute after the UIImagePicker has been dismissed.

EDIT: updated code, problem remains:

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    NSData* data = UIImagePNGRepresentation([info objectForKey:@"UIImagePickerControllerOriginalImage"]);
    [[picker parentViewController] dismissModalViewControllerAnimated:TRUE];
    [self executeSomeCode: data];
}

However, when I run the code, it hangs on the UIImagePicker to run my code, and then the UIImagePicker is visually dismissed after said code has executed.

Any ideas?

A: 

http://developer.apple.com/iphone/library/documentation/uikit/reference/UIImagePickerControllerDelegate_Protocol/UIImagePickerControllerDelegate/UIImagePickerControllerDelegate.html

I believe your call was deprecated in iOS3

You might try

(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info

and the get the data from the image before dismissing the viewController

NSData *data = UIImageJPEGRepresentation( [info objectForKey:@"UIImagePickerControllerOriginalImage"] , 1.0);
[self dismissModalViewControllerAnimated:TRUE];
[self executeSomeCode:img];
Aaron Saunders
and then execute my code after the dismiss call?
Origamiguy
i believe you are losing the data when you dismiss the controller, if you get the image data first, then I believe the problems with go away.I get the data, manipulate it.. and then dismiss the view
Aaron Saunders
No, he's not losing the data, the problem he's having is that he wants the imagepicker's modal view to be dismissed before the code executes. He's probably doing a visual animation with the image that he wants the user to see. He should be using the proper delegate methods as you point out though.
thelaws
Okay, well I've implemented it as Aaron suggested, and from a user perspective I'm seeing no difference. The UIImagePicker still hangs until executeSomeCode is finished. executeSomeCode does, however, work fine - the image data being lost wasn't a problem at all.thelaws is right in saying it's a visual thing.
Origamiguy
+1  A: 

I realize this isn't the most graceful of answers. I've had similar problems before (trying to do visual things in viewDidAppear that wasn't working). I found that by calling performSelector:withObject:afterDelay: caused my visual effects to be seen.

So in your case it would be:

[self performSelector:@selector(executeSomeCode:) withObject:data afterDelay:0];

I have no idea if this will work for you (or why it worked for me).

thelaws
A: 

I don't think you are hanging where you think you are. UIImagePNGRepresentation takes quite some time to perform as far as I know (UIJPEGRepresentation is much faster, if you don't mind not being lossless). You could pass the dictionary into your method and obtain the NSData you need in there.

Your second problem is that your code is synchronous, no matter how soon you tell your controller to dismiss, it will wait your long code to run. To schedule your heavy code on the next run loop iteration and let the controller be dismissed, use a 0ms delay to perform it.

I would change your code to this:

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
[[picker parentViewController] dismissModalViewControllerAnimated:YES];
[self performSelector:@selector(executeSomeCode:) withObject:info afterDelay:0.0f];
}
nobre
A: 

It shouldn't be necessary to use a background method, but you can try this approach:

- (void)_processImage:(UIImage*)image 
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    // convert to PNG data here, etc.
    // this is background, remember to manipulate UI in main thread
    // Example: [self.anImageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:NO];
    [pool release];
}

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    [[picker parentViewController] dismissModalViewControllerAnimated:YES];
    UIImage *picked = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
    [self performSelectorInBackground:@selector(_processImage:) withObject:[[picked retain] autorelease]];
}
madmw