I'm currently trying to build a camera application for fun and ran into a problem.
I was using an example that Apple provides you for the process of taking a photo or video. Found here:
https://developer.apple.com/library/content/samplecode/AVCam/Introduction/Intro.html
I'm having a problem using the PhotoCaptureDelegate. So currently when the user takes a photo it will save it to the users photo library. What I would like to do, is after it captures the photo I want to store the photoData Object of the photo. So that I can display the photo on another view as a preview before you save it.
This is what Apple suggests to use:
func capture(_ captureOutput: AVCapturePhotoOutput, didFinishCaptureForResolvedSettings resolvedSettings: AVCaptureResolvedPhotoSettings, error: Error?) {
if let error = error {
print("Error capturing photo: \(error)")
didFinish()
return
}
guard let photoData = photoData else {
print("No photo data resource")
didFinish()
return
}
PHPhotoLibrary.requestAuthorization { [unowned self] status in
if status == .authorized {
PHPhotoLibrary.shared().performChanges({ [unowned self] in
let creationRequest = PHAssetCreationRequest.forAsset()
creationRequest.addResource(with: .photo, data: photoData, options: nil)
if let livePhotoCompanionMovieURL = self.livePhotoCompanionMovieURL {
let livePhotoCompanionMovieFileResourceOptions = PHAssetResourceCreationOptions()
livePhotoCompanionMovieFileResourceOptions.shouldMoveFile = true
creationRequest.addResource(with: .pairedVideo, fileURL: livePhotoCompanionMovieURL, options: livePhotoCompanionMovieFileResourceOptions)
}
}, completionHandler: { [unowned self] success, error in
if let error = error {
print("Error occurered while saving photo to photo library: \(error)")
}
self.didFinish()
}
)
}
else {
self.didFinish()
}
}
}
How would I take the photoData object from my delegate and pass it back to my view controller, that is calling on this delegate?
There are a couple ways to solve this. You could also have your view controller own the photo capture delegate (like Apple's example) and pass it back up after the photo is taken. You could also just have your view controller be the photo capture delegate and not worry about passing anything!
1) Pass the photo back up
There are (again) a couple ways to do this. You could have the delegate pass the value back up to the controller. You could also have the delegate tell the controller it is done, and have the controller come grab the photo. I'll explain the second way below.
Looking at Apple's example, we can see that the
PhotoCaptureDelegatealready tells the controller when it is done! Whenever aPhotoCaptureDelegateobject is created, it is passed acompletedblock.To to allow the controller to grab the photo, we just have to make the photo object public!
private var photoData: Data? = nilinPhotoCaptureDelegateto bepublic var photoData: Data? = nilCameraViewControllerwhen you define thecompletedblock, you now have the photo data:2) View Controller as the AVCapturePhotoCaptureDelegate
Another way to solve this is to just have your
ViewControllerbe theAVCapturePhotoCaptureDelegate. Then you'll already have the photo data in the view controller! It could look something like this: