PhotoCaptureProcessor.swift (3061B)
1 // 2 // PhotoCaptureProcessor.swift 3 // damus 4 // 5 // Created by Suhail Saqan on 8/5/23. 6 // 7 8 import Foundation 9 import Photos 10 11 class PhotoCaptureProcessor: NSObject { 12 private(set) var requestedPhotoSettings: AVCapturePhotoSettings 13 private(set) var photoOutput: AVCapturePhotoOutput? 14 15 lazy var context = CIContext() 16 var photoData: Data? 17 private var maxPhotoProcessingTime: CMTime? 18 19 private let willCapturePhotoAnimation: () -> Void 20 private let completionHandler: (PhotoCaptureProcessor) -> Void 21 private let photoProcessingHandler: (Bool) -> Void 22 23 init(with requestedPhotoSettings: AVCapturePhotoSettings, 24 photoOutput: AVCapturePhotoOutput?, 25 willCapturePhotoAnimation: @escaping () -> Void, 26 completionHandler: @escaping (PhotoCaptureProcessor) -> Void, 27 photoProcessingHandler: @escaping (Bool) -> Void) { 28 self.requestedPhotoSettings = requestedPhotoSettings 29 self.willCapturePhotoAnimation = willCapturePhotoAnimation 30 self.completionHandler = completionHandler 31 self.photoProcessingHandler = photoProcessingHandler 32 self.photoOutput = photoOutput 33 } 34 35 func capturePhoto(settings: AVCapturePhotoSettings) { 36 if let photoOutput = self.photoOutput { 37 photoOutput.capturePhoto(with: settings, delegate: self) 38 } 39 } 40 } 41 42 extension PhotoCaptureProcessor: AVCapturePhotoCaptureDelegate { 43 func photoOutput(_ output: AVCapturePhotoOutput, willBeginCaptureFor resolvedSettings: AVCaptureResolvedPhotoSettings) { 44 maxPhotoProcessingTime = resolvedSettings.photoProcessingTimeRange.start + resolvedSettings.photoProcessingTimeRange.duration 45 } 46 47 func photoOutput(_ output: AVCapturePhotoOutput, willCapturePhotoFor resolvedSettings: AVCaptureResolvedPhotoSettings) { 48 DispatchQueue.main.async { 49 self.willCapturePhotoAnimation() 50 } 51 52 guard let maxPhotoProcessingTime = maxPhotoProcessingTime else { 53 return 54 } 55 56 DispatchQueue.main.async { 57 self.photoProcessingHandler(true) 58 } 59 60 let oneSecond = CMTime(seconds: 2, preferredTimescale: 1) 61 if maxPhotoProcessingTime > oneSecond { 62 DispatchQueue.main.async { 63 self.photoProcessingHandler(true) 64 } 65 } 66 } 67 68 func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) { 69 DispatchQueue.main.async { 70 self.photoProcessingHandler(false) 71 } 72 73 if let error = error { 74 print("Error capturing photo: \(error)") 75 } else { 76 photoData = photo.fileDataRepresentation() 77 78 } 79 } 80 81 func photoOutput(_ output: AVCapturePhotoOutput, didFinishCaptureFor resolvedSettings: AVCaptureResolvedPhotoSettings, error: Error?) { 82 if let error = error { 83 print("Error capturing photo: \(error)") 84 return 85 } 86 87 DispatchQueue.main.async { 88 self.completionHandler(self) 89 } 90 } 91 }