我正在创建使用照片输出来捕获照片的自定义相机。
当用户点击捕获按钮时,将调用photoOutput.capturePhoto(with: settings, delegate: self)
,由于self
符合UIViewController
,因此它将第二个参数作为表示UIViewController
的{{1}}。
但是,在通过消息实现AVCapturePhotoCaptureDelegate
时出现1个奇怪的警告-
实例方法'photoOutput(:didFinishProcessingPhoto:error :)'与协议'AVCapturePhotoCaptureDelegate'的可选要求'photoOutput(:didFinishProcessingPhoto:error :)'几乎匹配 >
此外,点击带有错误消息的捕获按钮时发生崩溃-
由于未捕获的异常'NSInvalidArgumentException'而终止应用程序,原因:'-[AVCapturePhotoOutput capturePhotoWithSettings:delegate:]如果在设置中指定了非null格式的字典,则您的代表必须响应选择器captureOutput:didFinishProcessingPhoto :错误:
即使设置的格式字典不是nil。
但是当我实现符合func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?)
的自定义类时,没有警告,并且效果很好。
所以我很好奇。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
}
}
...
}
答案 0 :(得分:0)
尽管自发布以来已经过去了将近一年,但在经历了完全相同的事情之后,我才才发现它,并且让我困惑了几个小时,然后才得到了解释。
我遵循的是一个古老的示例,可以在here中找到。
对我来说,问题出在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?) { ... }