我从运行iOS 10.2.1的iPhone 5s面朝上收到崩溃报告。
我正在检查相机是否可用于:
if (UIImagePickerController.availableCaptureModesForCameraDevice(.Rear) != nil) || (UIImagePickerController.availableCaptureModesForCameraDevice(.Front) != nil) {
shootPhoto()
}
回溯表明崩溃发生在picker.sourceType行上的shootPhoto()中:
func shootPhoto() {
picker.allowsEditing = false
picker.sourceType = UIImagePickerControllerSourceType.Camera
picker.cameraCaptureMode = .Photo
picker.popoverPresentationController?.sourceRect = sender.bounds
picker.popoverPresentationController?.sourceView = sender
picker.view.tintColor = UIColor.blackColor()
presentViewController(picker, animated: true, completion: nil)
}
由于我首先要检查相机是否可用,所以我不明白为什么它崩溃了。我需要检查
UIImagePickerController.availableMediaTypesForSourceType(.Camera)
吗?我无法重现该问题,所以不确定是否可以解决问题,对吗?还是我需要检查其他内容?回溯:
Fatal Exception: NSInvalidArgumentException
Source type 1 not available
0 CoreFoundation 0x1913f51b8 __exceptionPreprocess
1 libobjc.A.dylib 0x18fe2c55c objc_exception_throw
2 UIKit 0x197505714 +[UIImagePickerController _isMediaTypeAvailable:forSource:]
3 MyApp 0x1000afd8c TDTStartingViewViewController.(buttonActon(UIButton) -> ()).(closure #2) (TDTStartingViewViewController.swift:887)
4 UIKit 0x19774512c -[UIAlertController _invokeHandlersForAction:]
5 UIKit 0x1977459c8 __85-[UIAlertController _dismissAnimated:triggeringAction:triggeredByPopoverDimmingView:]_block_invoke.443
6 UIKit 0x1975f6130 -[UIPresentationController transitionDidFinish:]
7 UIKit 0x1975f98b0 __56-[UIPresentationController runTransitionForCurrentState]_block_invoke_2
8 UIKit 0x1973d1be8 -[_UIViewControllerTransitionContext completeTransition:]
9 UIKit 0x1972e35b8 -[UIViewAnimationBlockDelegate _didEndBlockAnimation:finished:context:]
10 UIKit 0x1972e30dc -[UIViewAnimationState sendDelegateAnimationDidStop:finished:]
11 UIKit 0x1972e2ef8 -[UIViewAnimationState animationDidStop:finished:]
12 QuartzCore 0x1947517e8 CA::Layer::run_animation_callbacks(void*)
13 libdispatch.dylib 0x19027e1bc _dispatch_client_callout
14 libdispatch.dylib 0x190282d68 _dispatch_main_queue_callback_4CF
15 CoreFoundation 0x1913a2810 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__
16 CoreFoundation 0x1913a03fc __CFRunLoopRun
17 CoreFoundation 0x1912ce2b8 CFRunLoopRunSpecific
18 GraphicsServices 0x192d82198 GSEventRunModal
19 UIKit 0x1973157fc -[UIApplication _run]
20 UIKit 0x197310534 UIApplicationMain
21 MyApp 0x1001329ec main (AppDelegate.swift:24)
22 libdispatch.dylib 0x1902b15b8 (Missing)
编辑:建议的代码(检查可用的媒体类型和捕获模式),这似乎可行,想法/建议吗?
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera) { //returns YES if source is available (i.e. camera present)
if UIImagePickerController.isCameraDeviceAvailable(.Rear) || UIImagePickerController.isCameraDeviceAvailable(.Front) { //returns YES if camera device is available
var isImageMediaTypeAvailble = false
var rearCameraSupportsPhotoCapture = false
var frontCameraSupportsPhotoCapture = false
let availableMediaTypes = UIImagePickerController.availableMediaTypesForSourceType(.Camera) //returns array of available media types (i.e. kUTTypeImage)
if availableMediaTypes != nil {
for mediaType in availableMediaTypes! {
if mediaType == kUTTypeImage as String {
isImageMediaTypeAvailble = true
}
}
}
if UIImagePickerController.isCameraDeviceAvailable(.Rear) {
let availableCaptureModes = UIImagePickerController.availableCaptureModesForCameraDevice(.Rear) // returns array of NSNumbers (UIImagePickerControllerCameraCaptureMode)
if availableCaptureModes != nil {
for mode in availableCaptureModes! {
if mode == UIImagePickerControllerCameraCaptureMode.Photo.rawValue { //camera can capture image
rearCameraSupportsPhotoCapture = true
}
}
}
}
if UIImagePickerController.isCameraDeviceAvailable(.Front) {
let availableCaptureModes = UIImagePickerController.availableCaptureModesForCameraDevice(.Front) // returns array of NSNumbers (UIImagePickerControllerCameraCaptureMode)
if availableCaptureModes != nil {
for mode in availableCaptureModes! {
if mode == UIImagePickerControllerCameraCaptureMode.Photo.rawValue { //camera can capture image
frontCameraSupportsPhotoCapture = true
}
}
}
}
if UIImagePickerController.isSourceTypeAvailable(.Camera) && isImageMediaTypeAvailble && (rearCameraSupportsPhotoCapture || frontCameraSupportsPhotoCapture) {
actionSheet.addAction(UIAlertAction(title: "Camera", style: UIAlertActionStyle.Default, handler: { action in
self.shootPhoto()
}))
}
}
}
最佳答案
根据定义,
open class func availableCaptureModes(for cameraDevice: UIImagePickerControllerCameraDevice) -> [NSNumber]?
// returns array of NSNumbers (UIImagePickerControllerCameraCaptureMode)
availableCaptureModes
返回UIImagePickerControllerCameraCaptureMode
的数组public enum UIImagePickerControllerCameraCaptureMode : Int {
case photo
case video
}
我想您需要先设置
.photo
可用模式,然后再设置picker.cameraCaptureMode = .Photo
而且看起来您需要检查
availableMediaTypes
open class func availableMediaTypes(for sourceType: UIImagePickerControllerSourceType) -> [String]?
// returns array of available media types (i.e. kUTTypeImage)
我认为这就是您所说的
1 libobjc.A.dylib 0x18fe2c55c objc_exception_throw
2 UIKit 0x197505714 +[UIImagePickerController _isMediaTypeAvailable:forSource:]