捕获图像崩溃即使检查相机是否可用,源类型1仍然不可用

时间:2017-04-21 21:32:47

标签: ios iphone swift camera uiimagepickercontroller

我收到了运行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()
            }))
        }
    }
}

1 个答案:

答案 0 :(得分:0)

根据定义,

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:]