Context: I'm building an app where a user can select Screenshots from their Photos Library, and display them in a more organized manner. These images are not saved to a database, but instead are simply fetched back from the Library (using PHFetchOptions) be means of the localIdentifier of that image (which is saved locally). Since iOS 14 requesting authorization provides two options: 1) "Select Photos", and 2) "Allow Access To All Photos." I'm currently using the latter, which works fine – but is a bigger request from the user.
Goal: I'd like to be able to handle the situation where the user chooses 1) "Select Photos" as well. When the user picks photos using the PHPickerViewController those photos should then also be added to the limited library.
Problem: I can't figure out how to save photos picked by the PHPickerController to the Limited Library. Is that even an option? Currently the only photo that gets saved to this array is the one selected during Auth (see code).
Thanks!!
Code for request Authorization
PHPhotoLibrary.requestAuthorization(for: .readWrite) { status in
switch status{
case .limited, .authorized:
print("status: \(status)")
// Handle "success" state
// When the user taps "Select Photos" prompt is displayed and the user can select images. This however is a bad experience, because in the UI it's the moment where the user authorizes the app for the first time.
case .notDetermined, .denied, .restricted:
print("Need to authorize still..")
default: break }
}
Code for checking Limited Library:
PHPhotoLibrary.shared().presentLimitedLibraryPicker(from: self) { identifiers in
for newlySelectedAssetIdentifier in identifiers {
// this is limited to the very first selection
}
}
Code presenting Picker:
private func presentPicker(filter: PHPickerFilter?) {
var configuration = PHPickerConfiguration(photoLibrary: .shared())
configuration.filter = PHPickerFilter.screenshots // was "filter"
configuration.preferredAssetRepresentationMode = .current
configuration.selection = .ordered
configuration.preselectedAssetIdentifiers = selectedAssetIdentifiers
let picker = PHPickerViewController(configuration: configuration)
picker.delegate = self
present(picker, animated: true)
}
Code Displaying the image result
func displayNext() {
guard let assetIdentifier = selectedAssetIdentifierIterator?.next() else { return }
let itemProvider = selection[assetIdentifier]!.itemProvider
if itemProvider.canLoadObject(ofClass: UIImage.self) {
let _ = itemProvider.loadObject(ofClass: UIImage.self) { [weak self] image, error in
if let image = image as? UIImage {
self?.selectedImage = image
self?.tempLocalIdentifier = assetIdentifier
DispatchQueue.main.async {
self?.updateImageSelectionUI()
self?.enableSaveButtonIfConditionMet()
}
}
}
}
}