When [camera takePicture]
is called before the camera is ready, it spits out this message:
UIImagePickerController: ignoring request to take pictu
What @Alladinian said was most helpful, this answer is supplemental to that. I recommend using his AVCaptureSessionDidStartRunningNotification technique as that tells you when the camera is ready initially (but this is called only once.) I am also concerned with if the device is ready for subsequent pictures as well. I haven't found the best solution, because I don't see any call backs for the device that don't refer to the camera's session. But this callback function seems to be good enough:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
Note the camera most likely will be ready before that callback is called, and you can cram in one or two photos, but it seems that the camera will definitely be ready by the time the callback is called. This should keep you from getting the following error between multiple camera shots.
UIImagePickerController: ignoring request to take picture; image is already being captured or camera not yet ready.
To be honest I haven't tried it and the documentation is somewhat ambiguous, but what about [UIImagePickerController isCameraDeviceAvailable:...]
?
EDIT: As I just learned, this is not the solution for your problem. Sorry, I thought it might be worth a try...
As per the documentation for UIImagePickerController. The takePicture() method is ready again when
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
is called. If your interested in blocking pictures during this time period just disable the button interface (button.userInterfaceEnabled = false) until the call returns with media. I solved this very problem using the imagePickerController.
Here is a Swift Version :
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.cameraIsReady), name: AVCaptureSessionDidStartRunningNotification, object: nil)
func cameraIsReady(notification :NSNotification ) {
print("Camera is ready...")
}
This makes sure to start capturing video as soon as camera is ready
imgpicker = [[UIImagePickerController alloc] init];
[self presentViewController:imgpicker animated:YES completion:^(void){
while(![imgpicker startVideoCapture]);
}];
As @djromero said there is a solution by using AVFoundation
(but not instead of UIImagePickerController
. You just use AVFoundation
to get a notification back).
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(cameraIsReady:)
name:AVCaptureSessionDidStartRunningNotification object:nil];
And then, once the camera is ready you got your notification:
- (void)cameraIsReady:(NSNotification *)notification
{
NSLog(@"Camera is ready...");
// Whatever
}
I have just tested it by calling takePicture
after UIImagePickerController
presentation (where I got the 'camera is not ready' message) and right inside my notification callback, where it worked like a charm.
Side-note:
[camera isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]
always returns Yes
because it only checks that there is a camera device available. As a matter of fact, Apple recommends that you always must check that this returns Yes
and that you have a non nil delegate (to provide a way to dismiss
the picker through the standard interface) before you try to initialize and present the controller.