Swift 4 中的 AVCaptureDeviceInput 中的 init() 不可用

init() is unavailable in AVCaptureDeviceInput in Swift 4

我的应用程序中有一个视图控制器,它像 Snapchat 一样显示后置摄像头,它在 Swift 3 中运行良好,但是当我更新到 Swift 4 时,编译器不会让我 运行 因为以下错误:

init() is unavailable for AVCaptureDeviceInput

这个视图控制器应该像 Snapchat 一样在没有任何按钮或额外东西的情况下显示相机。所以,这里是完整的视图控制器代码:

import UIKit
import AVFoundation

class cameraViewController: UIViewController , UIImagePickerControllerDelegate , UINavigationControllerDelegate {

var captureSession : AVCaptureSession?

var stillImageOutput : AVCaptureStillImageOutput?

var previewLayer : AVCaptureVideoPreviewLayer?

var imagePicker: UIImagePickerController!

@IBOutlet weak var cameraView: UIView!

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    previewLayer?.frame = cameraView.bounds
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)


    captureSession = AVCaptureSession()

    captureSession?.sessionPreset = AVCaptureSessionPreset1280x720

    let backCamera = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)

    let error : NSError?

    var input = AVCaptureDeviceInput()

    do {
        input = try AVCaptureDeviceInput(device: backCamera)
    }
    catch {
        //  error
    }

    if error == nil && (captureSession?.canAddInput(input))! {

        captureSession?.addInput(input)

        stillImageOutput = AVCaptureStillImageOutput()

        stillImageOutput?.outputSettings = [AVVideoCodecKey : AVVideoCodecJPEG]


        if (captureSession?.canAddOutput(stillImageOutput))! {

            captureSession?.addOutput(stillImageOutput)

            previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)

            previewLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill

            previewLayer?.connection.videoOrientation = AVCaptureVideoOrientation.portrait

            cameraView.layer.addSublayer(previewLayer!)

            captureSession?.startRunning() 

        }
    }

}

}

我无法运行申请,因为这条线:

var input = AVCaptureDeviceInput()

你必须像下面这样使用:

if let backCamera = AVCaptureDevice.default(for: .video) {
    do {
        var input = try AVCaptureDeviceInput(device: backCamera)
    } catch {
        //  error
    }
}

如何在您的代码中使用:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    captureSession = AVCaptureSession()
    captureSession?.sessionPreset = AVCaptureSession.Preset.hd1280x720

    guard let backCamera = AVCaptureDevice.default(for: .video) else {
        print("AVCaptureDevice backCamera is nil")
        return
    }

    let error : NSError?

    do {
        let input = try AVCaptureDeviceInput(device: backCamera)

        if (captureSession?.canAddInput(input))! {
            captureSession?.addInput(input)
            stillImageOutput = AVCaptureStillImageOutput()
            stillImageOutput?.outputSettings = [AVVideoCodecKey : AVVideoCodecJPEG]

            if (captureSession?.canAddOutput(stillImageOutput!))! {
                captureSession?.addOutput(stillImageOutput!)
                previewLayer = AVCaptureVideoPreviewLayer(session: captureSession!)
                previewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
                previewLayer?.connection?.videoOrientation = AVCaptureVideoOrientation.portrait
                cameraView.layer.addSublayer(previewLayer!)
                captureSession?.startRunning()
            }
        }
    }
    catch {
        //  error
    }
}

在Swift4中,你必须指定一个设备才能初始化AVCaptureDeviceInput - 事实上,你已经在初始化它一二抛出错误的代码之后的行。

此外,您在 if 语句中隐含地解包了一个安全解包的 AVCaptureSession

这是您的代码,已完善:

do {
    guard let input = try AVCaptureDeviceInput(device: backCamera),
        captureSession = captureSession else {
        print("Error in initializing a device input")
    }

    if error == nil && (captureSession.canAddInput(input)) {

    [...]
}
catch let error {
    print(error.localizedDescription)
}

所以我在 do catch 中使用了所有左边的代码,我得到了结果,应用程序在 swift 中运行良好 4 - 所以我的问题代码中不会出现视图,而是使用下面的代码

 override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)


    captureSession = AVCaptureSession()

    captureSession?.sessionPreset = AVCaptureSessionPreset1280x720


    do {
        let input = try AVCaptureDeviceInput(device: .defaultDevice(withMediaType: AVMediaTypeVideo))

        captureSession?.addInput(input)

        stillImageOutput = AVCaptureStillImageOutput()

        stillImageOutput?.outputSettings = [AVVideoCodecKey : AVVideoCodecJPEG]


        if (captureSession?.canAddOutput(stillImageOutput))! {

            captureSession?.addOutput(stillImageOutput)

            previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)

            previewLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill

            previewLayer?.connection.videoOrientation = AVCaptureVideoOrientation.portrait

            cameraView.layer.addSublayer(previewLayer!)

            captureSession?.startRunning()

        }



    } catch {

        print(error)

    }

}

我已经回答了我的问题以帮助其他人