Я работаю над созданием пользовательской камеры, которая использует вывод фотографий для захвата фотографии.
Когда пользователь нажимает кнопку захвата, вызывается photoOutput.capturePhoto(with: settings, delegate: self)
, который принимает второй параметр как self
, представляющий UIViewController
,потому что UIViewController
соответствует AVCapturePhotoCaptureDelegate
.
Но при реализации func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?)
с сообщением появляется 1 странное предупреждение -
Метод экземпляра 'photoOutput (: didFinishProcessingPhoto:error :) «почти соответствует необязательному требованию» photoOutput (: didFinishProcessingPhoto: error :) 'протокола' AVCapturePhotoCaptureDelegate '
Также происходит сбой при нажатии кнопки захвата с сообщением об ошибке -
Завершение приложения из-за неперехваченного исключения «NSInvalidArgumentException», причина: '- [AVCapturePhotoOutput capturePhotoWithSettings: Delegate:] Если вы задаете словарь ненулевого формата в своих настройках, ваш делегат должен ответить на селектор captureOutput: didFinishProcessingPhoto: ошибка:
Даже если в настройках есть словарь формата, которыйне ноль.
Но когда я реализую пользовательский класс, который соответствует 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
}
}
}