1

I want to get list of assets from Photo Library but exclude subtypes or assets from smartfolders such as smartAlbumBursts, smartAlbumLivePhotos, smartAlbumScreenshots

my code is

let options = PHFetchOptions()
options.sortDescriptors = [ NSSortDescriptor(key: "creationDate", ascending: true) ]
options.predicate = predicate
let assets = PHAsset.fetchAssets(with: PHAssetMediaType.image, options: options)

I was trying to make predicate like that:

let predicateType = NSPredicate(format: "mediaSubtypes != %@", 
   PHAssetMediaSubtype.photoScreenshot as! CVarArg)

but 1. it crashes 2. i can add PHAssetMediaSubtype only for screenshot and livePhoto but not for burst photo.

I know that there is method

if let collection = PHAssetCollection.fetchAssetCollections(with: .smartAlbum, 
   subtype: .smartAlbumBursts, options: nil).firstObject {

but i am not sure how to use that metdhod or subtype for my purposes

Was trying to use representsBurst but have a crash:

let predicateType = NSPredicate(format: "representsBurst == %@", NSNumber(value: false))

reason: 'Unsupported predicate in fetch options: representsBurst == 0'

Mebin Joe
  • 2,172
  • 4
  • 16
  • 22
Haloo
  • 57
  • 5

2 Answers2

3

Please refer to the table of supported predicate and sort descriptor keys of PHFetchOptions.

I'd make an assumption that if an asset doesn't represent a burst then it doesn't have a burst identifier. You can combine it as you want:

let options = PHFetchOptions()
options.sortDescriptors = [ NSSortDescriptor(key: "creationDate", ascending: true) ]

// fetch all images with no burstIdentifier
options.predicate = NSPredicate(format: "burstIdentifier == nil")
var assets = PHAsset.fetchAssets(with: PHAssetMediaType.image, options: options)

// fetch all images with photoScreenshot media subtype
options.predicate = NSPredicate(format: "((mediaSubtype & %d) != 0)", PHAssetMediaSubtype.photoScreenshot.rawValue)
assets = PHAsset.fetchAssets(with: PHAssetMediaType.image, options: options)

// fetch all images with photoLive media subtype
options.predicate = NSPredicate(format: "((mediaSubtype & %d) != 0)", PHAssetMediaSubtype.photoLive.rawValue)
assets = PHAsset.fetchAssets(with: PHAssetMediaType.image, options: options)

// fetch all non-photoScreenshot and non-photoLive images
options.predicate = NSPredicate(format: "NOT (((mediaSubtype & %d) != 0) || ((mediaSubtype & %d) != 0))", PHAssetMediaSubtype.photoScreenshot.rawValue, PHAssetMediaSubtype.photoLive.rawValue)
assets = PHAsset.fetchAssets(with: PHAssetMediaType.image, options: options)

// fetch all non-photoScreenshot and non-photoLive images with no burstIdentifier
options.predicate = NSPredicate(format: "NOT (((mediaSubtype & %d) != 0) || ((mediaSubtype & %d) != 0)) && burstIdentifier == nil", PHAssetMediaSubtype.photoScreenshot.rawValue, PHAssetMediaSubtype.photoLive.rawValue)
assets = PHAsset.fetchAssets(with: PHAssetMediaType.image, options: options)
Pavel Kozlov
  • 993
  • 6
  • 16
0

NSPredicate is tricky. The way to say "not" is like this:

NSPredicate(
    format: "!((assetCollectionSubtype & %d) == %d)",
        PHAssetCollectionSubtype.smartAlbumBursts.rawValue)
matt
  • 515,959
  • 87
  • 875
  • 1,141