我从运行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:]

09-04 14:03
查看更多