I have a viewcontroller that presents my custom ImagePicker class. One of the presented options is to select an image from 'Files', using UIDocumentPickerViewController. Picking an image works fine, but i want close the security resources conform the recommendations.
ProjectimagePicker {
(...)
let documentsPicker = UIDocumentPickerViewController(documentTypes: ["public.image", "public.jpeg", "public.png"], in: .open)
documentsPicker.delegate = self
documentsPicker.allowsMultipleSelection = false
documentsPicker.modalPresentationStyle = .fullScreen
self.presentationController?.present(documentsPicker, animated: true, completion: nil)
}
//MARK: - Ext. Delegate DocumentPicker
extension ProjectImagePicker: UIDocumentPickerDelegate {
public func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
guard controller.documentPickerMode == .open, let url = urls.first, url.startAccessingSecurityScopedResource() else { return }
defer {
DispatchQueue.main.async {
url.stopAccessingSecurityScopedResource()
}
}
guard let image = UIImage(contentsOfFile: url.path) else { return }
self.delegate?.didSelect(image: image)
controller.dismiss(animated: true)
}
public func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
controller.dismiss(animated: true)
}
}
And in the viewController that called the picker class:
//MARK: - Delegate ProjectImagePicker
extension ProjectDetailsViewController: ProjectImagePickerDelegate {
func didSelect(image: UIImage?) {
if let image = image {
selectedImage = image
projectImageView.image = image
}
}
}
Part of the problem I circumvent by wrapping a dispatch call around stopAccessingSecurityScopedResource(). The image gets send back (delegate) and presented
in the viewController. But when I eventually save (write to documents directory) my project and that image (selectedImage), I get the security error
2020-05-08 13:54:04.429936+0200 ProjectS[3482:1339708] [ProjectS] createDataWithMappedFile:1524: 'open' failed '/private/var/mobile/Library/Mobile Documents/com~apple~CloudDocs/10.JPEG' error = 1 (Operation not permitted)
So, apperently the image is still referencing the URL from the Documents picker. I could try and save the image temporarily in the didPickDocumentsAt method, but that seems ugly. Or I can omit calling stopAccessingSecurityScopedResource(0 all together, but that may cause problems?
Any ideas on how to hanlde this the best possible way ?