我正在创建自定义相机,它使用照片输出来捕捉照片。
当用户点击“捕获”按钮时,就会调用photoOutput.capturePhoto(with: settings, delegate: self),它将第二个参数作为表示UIViewController的self,因为UIViewController符合AVCapturePhotoCaptureDelegate。
但是,当使用消息实现func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?)时,出现了一个奇怪的警告-
'photoOutput(:didFinishProcessingPhoto:error:)‘实例方法几乎与协议'AVCapturePhotoCaptureDelegate'的可选需求'photoOutput(:didFinishProcessingPhoto:error:)’相匹配。
另外,当有错误信息的点击捕获按钮时,会发生崩溃-
由于“NSInvalidArgumentException”异常导致终止应用程序,原因:“-AVCapturePhotoOutput capturePhotoWithSettings:委托:如果在设置中指定非零格式字典,则委托必须响应选择器
即使设置有格式字典,也不是零。
但是,当我实现符合AVCapturePhotoCaptureDelegate的自定义类时,没有警告,而且效果很好。
所以我很好奇。UIViewController不应该符合AVCapturePhotoCaptureDelegate吗?如果不是,为什么?
错误示例:
final class CameraViewController: UIViewController, AVCapturePhotoCaptureDelegate {
...
@IBAction func captureButtonDidTap(_ sender: UIButton) {
guard isSessionRunning else { return }
if let previewLayerOrientation = previewLayer?.connection?.videoOrientation {
let photoOutputConnection = photoOutput?.connection(with: .video)
photoOutputConnection?.videoOrientation = previewLayerOrientation
}
guard let photoOutput = self.photoOutput else { return }
let settings = AVCapturePhotoSettings()
photoOutput.capturePhoto(with: settings, delegate: self)
}
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
if let error = error {
print(error)
return
}
}
...
}很好的例子:
final class CameraViewController: UIViewController {
...
@IBAction func captureButtonDidTap(_ sender: UIButton) {
guard isSessionRunning else { return }
guard let photoOutput = self.photoOutput else { return }
let settings = AVCapturePhotoSettings()
let processor = CameraCaptureProcessor(photoOutput: photoOutput, settings: settings)
self.capturedDelegate = processor
processor.capturePhoto()
}
...
}
final class CameraCaptureProcessor: NSObject, AVCapturePhotoCaptureDelegate {
private var photoOutput: AVCapturePhotoOutput!
private(set) var settings: AVCapturePhotoSettings!
convenience init(photoOutput: AVCapturePhotoOutput, settings: AVCapturePhotoSettings) {
self.init()
self.photoOutput = photoOutput
self.settings = settings
}
func capturePhoto() {
photoOutput.capturePhoto(with: settings, delegate: self)
}
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
if let error = error {
print(error)
return
}
}
}发布于 2019-11-14 13:00:29
虽然这篇文章发布已经将近一年了,但在我经历了同样的事情之后,我现在才发现它,这让我困惑了几个小时,然后我才明白了这个解释。
我遵循的是一个可以找到这里的老例子。
对我来说,问题是由于Swift模块。在本例中,引入自定义Error的方式如下
class CameraController: NSObject, AVCapturePhotoCaptureDelegate {
enum Error: Swift.Error {
case noDeviceAvailable
case captureSessionMissing
}
... 通过遵循委托协议并在CameraController范围内实现该方法
class CameraController: NSObject, AVCapturePhotoCaptureDelegate {
...
//MARK: - AVCapturePhotoCaptureDelegate
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) { ... }
...您实际上导致编译器触发警告,因为委托方法中的Error类型与作用域中可用的CameraController.Error类型不匹配。
解决方案是将自定义Error定义移出类的作用域之外,或者显式地告诉编译器委托方法使用Swift.Error。
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Swift.Error?) { ... }https://stackoverflow.com/questions/54312307
复制相似问题