iOS 应用程序因相机权限而崩溃

问题描述 投票:0回答:1

我有一个视图控制器,我正在尝试打开相机来扫描二维码。每次我打开 VC 时,它都会使我的应用程序崩溃并显示错误消息:

此应用程序已崩溃,因为它试图在没有使用说明的情况下访问隐私敏感数据。 应用程序的 Info.plist 必须包含一个 NSCameraUsageDescription 键,其中包含一个字符串值,向用户解释应用程序如何使用此数据。

我也仔细检查了我的 info.plist 和 Target。我已经允许使用相机,但每次仍然面临相同的错误。缺少的点是什么?这是我的 VC 代码:

enter image description here

import UIKit


import AVFoundation

class Scanner__VC: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
var captureSession: AVCaptureSession!
var previewLayer: AVCaptureVideoPreviewLayer!




override func viewDidLoad() {
    super.viewDidLoad()

    
    view.backgroundColor = UIColor.black
            captureSession = AVCaptureSession()

            guard let videoCaptureDevice = AVCaptureDevice.default(for: .video) else { return }
            let videoInput: AVCaptureDeviceInput

    do {
        videoInput = try AVCaptureDeviceInput(device: videoCaptureDevice)
        
    } catch {
                return
            }

    if (captureSession.canAddInput(videoInput)) {
        captureSession.addInput(videoInput)
        
    } else {
        failed()
        return
        
    }

            let metadataOutput = AVCaptureMetadataOutput()

    if (captureSession.canAddOutput(metadataOutput)) {
        captureSession.addOutput(metadataOutput)
        
        metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
        metadataOutput.metadataObjectTypes = [.qr]
        
    } else {
        failed()
        return
        
    }

    previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
    previewLayer.frame = view.layer.bounds
    previewLayer.videoGravity = .resizeAspectFill
    view.layer.addSublayer(previewLayer)

    captureSession.startRunning()
    
}


func failed() {
    let ac = UIAlertController(title: "Scanning not supported", message: "Your device does not support scanning a code from an item. Please use a device with a camera.", preferredStyle: .alert)
    ac.addAction(UIAlertAction(title: "OK", style: .default))
    present(ac, animated: true)
    captureSession = nil
    
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    
    if (captureSession?.isRunning == false) {
        captureSession.startRunning()
    }
    
    
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    
    if (captureSession?.isRunning == true) {
        captureSession.stopRunning()
    }
    
}

func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
    captureSession.stopRunning()
    
    if let metadataObject = metadataObjects.first {
        guard let readableObject = metadataObject as? AVMetadataMachineReadableCodeObject else { return }
        guard let stringValue = readableObject.stringValue else { return }
        AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
        found(code: stringValue)
    }
    
    dismiss(animated: true)
    
}

func found(code: String) {
    print(code)
    
}

override var prefersStatusBarHidden: Bool {
    return true
    
}

override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return .portrait
    
}


func showAlert(with message: String) {
    let alert = UIAlertController(title: "QR Code Scanned", message: message, preferredStyle: .alert)
    alert.addAction(UIAlertAction(title: "OK", style: .default))
    present(alert, animated: true)
    
}
ios swift error-handling camera
1个回答
0
投票

你有:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>UIApplicationSceneManifest</key>
    <dict>
        <key>NSCameraUsageDescription</key>
        <string>Camera usage reason</string>
        <key>UIApplicationSupportsMultipleScenes</key>
        <false/>
        <key>UISceneConfigurations</key>
        <dict>
            <key>UIWindowSceneSessionRoleApplication</key>
            <array>
                <dict>
                    <key>UISceneConfigurationName</key>
                    <string>Default Configuration</string>
                    <key>UISceneDelegateClassName</key>
                    <string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
                    <key>UISceneStoryboardFile</key>
                    <string>Snapped</string>
                </dict>
            </array>
        </dict>
    </dict>
</dict>
</plist>

对于我的答案中

NSCameraUsageDescription
的下一次使用,它也可以应用于照片库和两个位置权限。

NSCameraUsageDescription
位于
UIApplicationSceneManifest
内部(从层次结构级别来说),而它应该位于plist的顶层层次结构,与
UIApplicationSceneManifest
处于同一级别。

你应该有这样的东西:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>NSCameraUsageDescription</key>
    <string>Camera usage reason</string>
    <key>UIApplicationSceneManifest</key>
    <dict>
        <key>UIApplicationSupportsMultipleScenes</key>
        <false/>
        <key>UISceneConfigurations</key>
        <dict>
            <key>UIWindowSceneSessionRoleApplication</key>
            <array>
                <dict>
                    <key>UISceneConfigurationName</key>
                    <string>Default Configuration</string>
                    <key>UISceneDelegateClassName</key>
                    <string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
                    <key>UISceneStoryboardFile</key>
                    <string>Snapped</string>
                </dict>
            </array>
        </dict>
    </dict>
</dict>
</plist>

© www.soinside.com 2019 - 2024. All rights reserved.