Photo Library - How to handle limited access

Hello everybody,

For the last couple of days I have been struggling with preparing my app to limited access to the Photo Library. I want the user to be able to choose limited access.

In my app I need to be able to access the photo, as well as, photo metadata like - creation date and location (if available).

Before showing the picker, I am asking the user for authorisation to access the Photo Library, like this.

Code Block
let accessLevel: PHAccessLevel = .readWrite
                                let status = PHPhotoLibrary.authorizationStatus(for: accessLevel)
                                switch status {
                                case .authorized:
                                    self.imagePickerIsPresented.toggle()
                                case .limited:
                                    print("Limited access - show picker.")
                                    self.imagePickerIsPresented.toggle()
                                case .denied:
                                    self.showPhotosAccessDeniedAlert.toggle()
                                case .notDetermined:
                                    PHPhotoLibrary.requestAuthorization(for: accessLevel) { newStatus in
                                        switch newStatus {
                                        case .limited:
                                            print("Limited access.")
                                            break
                                        case .authorized:
                                            print("Full access.")
                                        case .denied:
                                            break
                                        default:
                                            break
                                        }
                                    }
                                default:
                                    break
                                }


I have used breakpoints to debug this code, and this is working just fine.

When the user wants to import a photo to the application I am using a PHPicker. When the user calls the picker to select a photo, I am still able to see all the user photos, regardless of the previous selection made by the user.

However, I want to be able to see only the Photos the user selected. How can I handle this in the correct way?

Furthermore, regardless of the selection my picker is still able to access the photo as well as the metadata.

Here is the code for my PHPicker.

Code Block
//
//  ImagePicker.swift
//  Lepidoptera
//
//  Created by Tomás Mamede on 26/09/2020.
//  Copyright © 2020 Tomás Santiago. All rights reserved.
//
import SwiftUI
import PhotosUI
@available(iOS 14, *)
struct ImagePicker: UIViewControllerRepresentable {
    
    @Binding var imageToImport: UIImage
    @Binding var isPresented: Bool
    @Binding var imageWasImported: Bool
    
    func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> some UIViewController {
        
        var configuration = PHPickerConfiguration(photoLibrary: PHPhotoLibrary.shared())
        configuration.filter = .images
        configuration.selectionLimit = 1
        
        let imagePicker = PHPickerViewController(configuration: configuration)
        imagePicker.delegate = context.coordinator
        return imagePicker
    }
    
    func updateUIViewController(_ uiViewController: ImagePicker.UIViewControllerType, context: UIViewControllerRepresentableContext<ImagePicker>) {}
    
    func makeCoordinator() -> ImagePicker.Coordinator {
        return Coordinator(parent: self)
    }
    
    class Coordinator: NSObject, PHPickerViewControllerDelegate {
        
        var parent: ImagePicker
        
        init(parent: ImagePicker) {
            self.parent = parent
        }
        
        func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
            
            picker.dismiss(animated: true)
            
            if results.count != 1 {
                return
            }
            
            if let image = results.first {
                
                if image.itemProvider.canLoadObject(ofClass: UIImage.self) {
                    image.itemProvider.loadObject(ofClass: UIImage.self) { image, error  in
                       
                        guard error == nil else {
                            print(error!)
                            return
                        }
                        
                        if let image = image {
                            
                            let identifiers = results.compactMap(\.assetIdentifier)
                            let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: identifiers, options: nil)
                            
                            let imageMetadata = fetchResult[0]
                            print(imageMetadata.creationDate!)
                            print("Image impoted.")
                            self.parent.imageToImport = image as! UIImage
                            self.parent.imageWasImported.toggle()
                        }
                    }
                }
            }
            
            self.parent.isPresented.toggle()
        }
    }
}


My fundamental problem is:
  • How can I respect the user selection by only showing the photos chosen by the user?

By doing this I am sure I only can access metadata for photos approved by the user.

Thank you for your help.

Replies

I have the same question. If the user granted limited access to some photos, I would like to show that in my app. Is that supported? If so, how can I access to that gallery?
It seems you have to do the hiding by yourself, PHPickerFilter doesn't do it.
https://stackoverflow.com/questions/63822338/how-to-use-phauthorizationstatuslimited-in-ios-14
https ://www.wwdcnotes .com/notes/wwdc20/10641/

This may be of interest as well
https ://ikyle. me/blog/2020/phpickerviewcontroller

Note: when you post code, please use Paste and Match style to avoid all the extra blank lines that make code really hard to read.
Here with paste and match style:
Code Block
let accessLevel: PHAccessLevel = .readWrite
let status = PHPhotoLibrary.authorizationStatus(for: accessLevel)
switch status {
case .authorized:
self.imagePickerIsPresented.toggle()
case .limited:
print("Limited access - show picker.")
self.imagePickerIsPresented.toggle()
case .denied:
self.showPhotosAccessDeniedAlert.toggle()
case .notDetermined:
PHPhotoLibrary.requestAuthorization(for: accessLevel) { newStatus in
switch newStatus {
case .limited:
print("Limited access.")
break
case .authorized:
print("Full access.")
case .denied:
break
default:
break
}
}
default:
break
}