ios - 更新到 Xcode 9/Swift 4 后 AVCapture 出现奇怪的编译错误

标签 ios swift4 xcode9

<分区>

我有一个普通的 UIViewController,它使用 AVCapturePhoto,我在其中创建了一个自定义捕获 Controller 。

在我更新到 Xcode 9 并将我的代码转换为 Swift 4 之前一切正常,现在当我尝试编译时我得到了这个编译错误:

Undefined symbols for architecture x86_64: "__T0So22AVCapturePhotoSettingsC12AVFoundation01_abC16SwiftNativeTypesACWP", referenced from: __T05Union16CameraControllerC18handleCapturePhotoyyF in CameraController.o "__T012AVFoundation39_AVCapturePhotoSettingsSwiftNativeTypesPAAE016availablePreviewc11PixelFormatG0Says6UInt32VGfg", referenced from: __T05Union16CameraControllerC18handleCapturePhotoyyF in CameraController.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)

错误托盘中显示了这条消息:

Apple Mach-O Linker Error Group

任何提示可能是什么原因造成的?

更新信息

这是错误日志的 Xcode 9 打印屏幕。希望对解决编译错误有帮助。

enter image description here

编辑

只是执行一些测试——如果我注释类代码,编译错误就会消失。

我在 Swift 4 中遗漏的以下 class 实现有什么问题吗??

import UIKit
import AVFoundation


class CameraController: UIViewController, AVCapturePhotoCaptureDelegate, UIViewControllerTransitioningDelegate {

    let dismissButton: UIButton = {
        let button = UIButton(type: .system)
        button.setImage(#imageLiteral(resourceName: "right_arrow_shadow").withRenderingMode(.alwaysOriginal), for: .normal)
        button.addTarget(self, action: #selector(handleDismiss), for: .touchUpInside)
        return button
    }()

    let capturePhotoButton: UIButton = {
        let button = UIButton(type: .system)
        button.setImage(#imageLiteral(resourceName: "capture_photo").withRenderingMode(.alwaysOriginal), for: .normal)
        button.addTarget(self, action: #selector(handleCapturePhoto), for: .touchUpInside)
        return button
    }()

    let output = AVCapturePhotoOutput()

    override func viewDidLoad() {
        super.viewDidLoad()

        transitioningDelegate = self
        setupCaptureSession()
        setupHUD()
    }


    // hiddes the status bar
    override var prefersStatusBarHidden: Bool { return true }

    //MARK: General funcs
    fileprivate func setupCaptureSession() {
        let captureSession = AVCaptureSession()

        //1. setup inputs - camera
        let captureDevice = AVCaptureDevice.default(for: AVMediaType.video)
        do {
            let input = try AVCaptureDeviceInput(device: captureDevice!)
            if captureSession.canAddInput(input) {
                captureSession.addInput(input)
            }
        } catch let err {
            print("Could not setup camera input:", err)
        }
        //2. setup outputs
        if captureSession.canAddOutput(output) {
            captureSession.addOutput(output)
        }
        //3.setup output preview
        let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)      
        previewLayer.frame = view.frame
        view.layer.addSublayer(previewLayer)

        // starts the inputs/outputs
        captureSession.startRunning()
    }


    fileprivate func setupHUD() {
        // botão de captura
        view.addSubview(capturePhotoButton)
        capturePhotoButton.anchor(top: nil, left: nil, bottom: view.bottomAnchor, right: nil, paddingTop: 0, paddinfLeft: 0, paddingBottom: 24, paddingRight: 0, width: 80, height: 80)
        capturePhotoButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true

        // dismiss button
        view.addSubview(dismissButton)
        dismissButton.anchor(top: view.topAnchor, left: nil, bottom: nil, right: view.rightAnchor, paddingTop: 12, paddinfLeft: 0, paddingBottom: 0, paddingRight: 12, width: 50, height: 50)
    }


    @objc func handleCapturePhoto() {
        // processes the captured photo
        let settings = AVCapturePhotoSettings()
        guard let preview = settings.availablePreviewPhotoPixelFormatTypes.first else { return }
        settings.previewPhotoFormat = [kCVPixelBufferPixelFormatTypeKey as String: preview]
        output.capturePhoto(with: settings, delegate: self)
    }


    @objc func handleDismiss() {
        dismiss(animated: true, completion: nil)
    }


    // Camera delegate
    func photoOutput(_ captureOutput: AVCapturePhotoOutput, didFinishProcessingPhoto photoSampleBuffer: CMSampleBuffer?, previewPhoto previewPhotoSampleBuffer: CMSampleBuffer?, resolvedSettings: AVCaptureResolvedPhotoSettings, bracketSettings: AVCaptureBracketedStillImageSettings?, error: Error?) {
        // access the captured image
        let imageData = AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: photoSampleBuffer!, previewPhotoSampleBuffer: previewPhotoSampleBuffer!)
        let previewImage = UIImage(data: imageData!)

        // shows the image
        let containerView = PreviewPhotoContainerView()
        containerView.previewImageView.image = previewImage

        view.addSubview(containerView)
        containerView.anchor(top: view.topAnchor, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor, paddingTop: 0, paddinfLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)

    }   
}

最佳答案

所以我设法解决了这个问题。

不知何故,在 Xcode 9 中,您无法实现无法在 iOS 模拟器上运行的“免费”代码。

错误 - 在解决它之后 - 非常简单。

我无法在模拟器中使用摄像头,因为它不会工作。

我认为 Xcode 可以提供更有用的错误信息。

为了解决这个问题,在我的 CameraController 类 中,我必须编辑我的 handleCapturePhoto() 函数。

我必须检查是否使用的架构不是 x86_64(模拟器),然后我可以呈现相机输出。

这是函数求解状态:

@objc func handleCapturePhoto() {
    // processes the captured photo
    let settings = AVCapturePhotoSettings()

    // doesn't show in the simulator
    #if (!arch(x86_64))
        guard let preview = settings.previewPhotoFormat?.first else { return }
        settings.previewPhotoFormat = [kCVPixelBufferPixelFormatTypeKey as String: preview]
        output.capturePhoto(with: settings, delegate: self)
    #endif
}

希望这对以后的人有帮助。

关于ios - 更新到 Xcode 9/Swift 4 后 AVCapture 出现奇怪的编译错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46227230/

相关文章:

java - 如何在 iPhone 真实设备上检查和编写 xpath

iphone - 是否可以以编程方式更改 iOS Safari 设置

ios - Objective-c Shinobi 网格更新到 2.8

ios - 如何在 swift 4 中添加虚折线?

ios - Xcode 9 bug : build on device fails with lots of errors, 模拟器运行良好

ios - 在发布配置中使用 IMP 调用时,方法参数为零

ios - 如何使用 Swift 4 和 Alamofire 从 API 获取数据

ios - 如何将 Storyboard中的 subview 添加到 swift 4 代码中的另一个 View ?

ios - 处理背靠背 HTTP 帖子 SWIFT 4.0

ios - Xcode 9 - 关于 Info.plist 中位置使用说明的警告 - iOS 11