Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS 7 UIImagePickerController Camera No Image

Tags:

ios

ios7

For some reason the first time I open the UIImagePickerController in camera mode on my app it comes up blank. I have to close and reopen that view to get the camera feed to start working. I'm using the standard code that works in iOS 6 perfectly for camera capture. From the sample below I'm firing the capturePhoto: method. Anyone else running into this jenkiness with the iOS 7 camera? I checked the Apple dev forums but its near impossible to find answers there.

- (IBAction)capturePhoto:(id)sender {
    [self doImagePickerForType:UIImagePickerControllerSourceTypeCamera];
}

- (void)doImagePickerForType:(UIImagePickerControllerSourceType)type {
    if (!_imagePicker) {
        _imagePicker = [[UIImagePickerController alloc] init];
        _imagePicker.mediaTypes = @[(NSString*)kUTTypeImage];
        _imagePicker.delegate = self;
    }
    _imagePicker.sourceType = type;
    [self presentViewController:_imagePicker animated:YES completion:nil];
}

why so empty?

like image 474
KyleStew Avatar asked Sep 21 '13 08:09

KyleStew


3 Answers

I'm also using UIImagePickerController and ran into the same issue with a blank screen. I'd like to expand a little on what klaudz mentioned regarding iOS 7 authorization for the camera.

Reference: https://developer.apple.com/library/ios/documentation/AVFoundation/Reference/AVCaptureDevice_Class/Reference/Reference.html

"Recording audio always requires explicit permission from the user; recording video also requires user permission on devices sold in certain regions."

Here is some code fragments you can start with to check to see if you have permission for the camera and request it if your app hadn't previously requested it. If you are denied due to an earlier request, your app may need to put up a notice to the user to go into settings to manually enable access as klaudz pointed out.

iOS 7 example

NSString *mediaType = AVMediaTypeVideo; // Or AVMediaTypeAudio

AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:mediaType];

// This status is normally not visible—the AVCaptureDevice class methods for discovering devices do not return devices the user is restricted from accessing.
if(authStatus == AVAuthorizationStatusRestricted){
    NSLog(@"Restricted");
}

// The user has explicitly denied permission for media capture.
else if(authStatus == AVAuthorizationStatusDenied){
    NSLog(@"Denied");
}

// The user has explicitly granted permission for media capture, or explicit user permission is not necessary for the media type in question.
else if(authStatus == AVAuthorizationStatusAuthorized){
    NSLog(@"Authorized");
}

// Explicit user permission is required for media capture, but the user has not yet granted or denied such permission.
else if(authStatus == AVAuthorizationStatusNotDetermined){

    [AVCaptureDevice requestAccessForMediaType:mediaType completionHandler:^(BOOL granted) {

        // Make sure we execute our code on the main thread so we can update the UI immediately.
        //
        // See documentation for ABAddressBookRequestAccessWithCompletion where it says
        // "The completion handler is called on an arbitrary queue."
        //
        // Though there is no similar mention for requestAccessForMediaType, it appears it does
        // the same thing.
        //
        dispatch_async(dispatch_get_main_queue(), ^{

            if(granted){
                // UI updates as needed
                NSLog(@"Granted access to %@", mediaType);
            }
            else {
                // UI updates as needed
                NSLog(@"Not granted access to %@", mediaType);
            }
        });

    }];

}

else {
    NSLog(@"Unknown authorization status");
}
like image 157
Scott Carter Avatar answered Nov 09 '22 21:11

Scott Carter


In iOS 7, an app could access the camera before getting authorize of the user. When an app accesses the camera the first time, iOS show an alert view to ask user. Users could also set the authorize in Settings--Privacy--Camera--[Your app's name].

The camera will stay in a black blank view if the switch is off.

  1. If you call the camera by using AVCaptureDeviceInput, you can check like:

    NSError *inputError = nil;
    AVCaptureDeviceInput *captureInput =
        [AVCaptureDeviceInput deviceInputWithDevice:inputDevice error:&inputError];
    if (inputError &&
        inputError.code == AVErrorApplicationIsNotAuthorizedToUseDevice)
    {
        // not authorized
    }
    
  2. If you call by using UIImagePickerController, I am still looking for a way to check whether got the authorize.

    I tried these two methods:

    [UIImagePickerController isSourceTypeAvailable:]
    [UIImagePickerController isCameraDeviceAvailable:]
    

    but they did't work that they all returned YES.

UPDATE

Thanks for Scott's expanding. [AVCaptureDevice authorizationStatusForMediaType:] is a better way to check.

AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
if (authStatus == AVAuthorizationStatusAuthorized) {
    // successful
} else {
    // failed, such as
    // AVAuthorizationStatusNotDetermined
    // AVAuthorizationStatusRestricted
    // AVAuthorizationStatusNotDetermined
}

But remember to check the iOS version, because [AVCaptureDevice authorizationStatusForMediaType:] and AVAuthorizationStatus are available above iOS 7.

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
    // code for AVCaptureDevice auth checking
}
like image 32
klaudz Avatar answered Nov 09 '22 21:11

klaudz


I experienced the exact same problem, and tried every solution on the Internet with no luck. But finally I found out it was the background thread prevented the camera preview to show up. If you happen to have background thread running while trying to open the camera as I do, try to block the background thread and see what happens. Hope you can get around it.

like image 29
Vinson Li Avatar answered Nov 09 '22 21:11

Vinson Li