Home:ALL Converter>AVCam Project Crashes On iPad

AVCam Project Crashes On iPad

Ask Time:2016-11-22T09:05:41         Author:Matt Long

Json Formatter

Apple's demo source code for the AVCam demo app found here: https://developer.apple.com/library/content/samplecode/AVCam/Introduction/Intro.html crashes when attempting to take a picture (regardless of whether you build the Objective-C or Swift versions) on the line in the AVCamCameraViewController/CameraViewController(Swift) that captures the photo:

[self.photoOutput capturePhotoWithSettings:photoSettings delegate:photoCaptureDelegate];

or (Swift)

self.photoOutput.capturePhoto(with: photoSettings, delegate: photoCaptureDelegate)

The error message when it crashes is:

2016-11-21 17:44:31.590070 AVCam[2178:2303627] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* -[AVCapturePhotoOutput capturePhotoWithSettings:delegate:] flashMode must be set to a value present in the supportedFlashModes array'

And when I examine the flash modes array, I get this:

(lldb) po [self.photoOutput supportedFlashModes] <__NSSingleObjectArrayI 0x170007c50>( 0 )

So in order to add the flash mode, the docs say you have to specify what modes you want to support in the AVCapturePhotoSettings object. I've done that with this line of code:

photoSettings.flashMode = AVCaptureFlashModeAuto;

or (Swift)

photoSettings.flashMode = .auto

So my hunch is that this is a bug specifically related to the 12.9" iPad Pro and I probably need to submit a radar, but thought I would ask here in case someone's seen it before. Any ideas?

Update

I've been able to duplicate this other iPads as well, so it doesn't appear to be only the 12.9" iPad Pro only.

Author:Matt Long,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/40732183/avcam-project-crashes-on-ipad
FreedomOfSpeech :

// Also for someone that might be having this problem while trying to use the Apple supplied AVCam sample code in XCode on MacOS, using the Objective C supplied version of the code, just add this (in Objective C):\n\nAVCaptureDevicePosition position = self.videoDeviceInput.device.position;\nif (position == AVCaptureDevicePositionFront)\n{\n photoSettings.flashMode = AVCaptureFlashModeOff;\n}\nelse\n{\n photoSettings.flashMode = AVCaptureFlashModeAuto;\n}\n\n\n//right before:\n\n[self.photoOutput.capturePhoto(with: photoSettings, delegate: photoCaptureDelegate]\n",
2017-02-25T00:44:27
Ofir Malachi :

You must check if the device supports \"Flash\" mode\nwith:\n\n[self.photoOutput.supportedFlashModes containsObject:[NSNumber numberWithInt:AVCaptureFlashModeOn]])\n\n\nand then use:\n\n@property (nonatomic) AVCapturePhotoOutput *photoOutput;\n\n\nAVCapturePhotoSettings *photoSettings = [AVCapturePhotoSettings photoSettings];\n\n\n AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];\n if ([device hasTorch] && [device hasFlash]){\n [device lockForConfiguration:nil];\n if([self.photoOutput.supportedFlashModes containsObject:[NSNumber numberWithInt:AVCaptureFlashModeOn]]){\n [device setFlashMode:AVCaptureFlashModeOn];\n photoSettings.flashMode = AVCaptureFlashModeAuto;\n }\n else{\n photoSettings.flashMode = AVCaptureFlashModeOff;\n }\n [device unlockForConfiguration];\n }\n else{\n photoSettings.flashMode = AVCaptureFlashModeOff;\n [device unlockForConfiguration];\n }\n\n\nthen\n\n[self.photoOutput.capturePhoto(with: photoSettings, delegate: photoCaptureDelegate]\n",
2017-04-26T11:45:45
JPetric :

In swift it has to be checked whether photo output supports flash mode at all.\n\n let settings = AVCapturePhotoSettings()\n if photoOutput.supportedFlashModes.contains(.on) {\n settings.flashMode = self.flashMode\n } else {\n settings.flashMode = .off\n }\n\n self.photoOutput?.capturePhoto(with: settings, delegate: self)\n",
2020-02-05T08:54:12
Andrew Koster :

To check if a camera has a flash, use the AVCaptureDevice.hasFlash property on that camera.\n\nIt doesn't really make sense to use the back/front position to guess this, when there's already something that just tells you whether or not it has a flash.",
2018-08-21T10:32:24
Omar HossamEldin :

No need to check the camera position, all what we need is to check if the camera has flash of not and according to that we set the flash mode.\nphotoSettings.flashMode = AVCaptureDevice.default(for: AVMediaType.video)!.hasFlash ? .on : .off\n",
2020-09-10T10:17:14
Matt Long :

So building on Soja's answer, I decided to interrogate the supportedFlashModes array provided by the photoOutput variable which is an AVCapturePhotoOutput.\n\nself.inProgressPhotoCaptureDelegates[photoCaptureDelegate.requestedPhotoSettings.uniqueID] = photoCaptureDelegate\n\nif let _ = self.photoOutput.supportedFlashModes.filter({ (mode) -> Bool in\n return mode.intValue == AVCaptureFlashMode.auto.rawValue\n}).last {\n let position = self.videoDeviceInput.device.position\n photoSettings.flashMode = position == .front || position == .unspecified ? .off : .auto\n} else {\n photoSettings.flashMode = .off\n}\n\nself.photoOutput.capturePhoto(with: photoSettings, delegate: photoCaptureDelegate)\n\n\nThere are probably some more comprehensive ways to do it, but this ensures that the .auto mode is supported before attempting to use it. The difference and issue here seems to relate to the type of device, iPhone vs iPad due to the fact that iPads don't have a flash on the back like iPhones do. In other words, it works fine on my phone.",
2017-02-03T02:51:25
Soja :

Add this ...\n\nlet position = self.videoDeviceInput.device.position\nphotoSettings.flashMode = position == .front || position == .unspecified ? .off : .auto\n\n\nright before this ...\n\nself.photoOutput.capturePhoto(with: photoSettings, delegate: photoCaptureDelegate)\n\n\nThat should fix the problem. ",
2017-01-22T19:02:46
yy