How to fetch only assets with granted access on iOS 14?

Viewed 1522

Previously in our project we used PHAsset.fetchAssets(with:) to get the list of all media in user's library (returned as PHFetchResult<PHAsset>). We called object(at:) to access individual items and that worked just fine.

With iOS 14 and its new privacy features, the user can opt in to allow access to only selected photos from their library. The problem is that PHAsset.fetchAssets(with:) still returns all assets that the user has, but only the ones the app has access to can be used to retrieve the actual photo or video. The count property of PHFetchResult is not what's needed as well in this case.

Is there any way to conveniently request only the media items with granted access, so that I immediately have the proper count and assets?

The only example I found so far is to enumerate the assets and request the corresponding image for each one and manually filter out the ones with no access.

let assets = PHAsset.fetchAssets(with: fetchOptions)
print(assets.count) // prints 6 and equals all items in photo library
        
var assetsWithGrantedAccess: [UIImage] = []
        
let filteredImagesQueue = DispatchQueue(label: "filter.images.queue")
let dispatchGroup = DispatchGroup()
        
assets.enumerateObjects { (asset, _, _) in
     dispatchGroup.enter()
     PHImageManager.default().requestImage(for: asset, targetSize: size, contentMode: .aspectFit, options: imageRequestOptions) { (image, _) in
          defer { dispatchGroup.leave() }
          guard let image = image else {
               return
          }
          filteredImagesQueue.async {
               assetsWithGrantedAccess.append(image)
          }
     }
}
        
dispatchGroup.notify(queue: filteredImagesQueue) {
     print(assetsWithGrantedAccess.count) // prints 2 and equals number of items with granted access
}
1 Answers

This seems to be happening only in the simulator , PHAsset.fetchAssets(with:) on device return only the media items with granted access.

Related