swiftphotos

Live Photos and normal photos through PHAsset


I'm trying to have a collection of photo's displayed. to get these photo's, I'm using the Photos framework.

I was using the following code to get the photos:

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

images = PHAsset.fetchAssets(with: .image, options: options)

However, I'd also like to get Live Photo's (so a combination of both, Live Photo's would ideally just be the first still Frame.

Now I know you can get Live Photos like this:

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

options.predicate = NSPredicate(format: "(mediaSubtype & %d) != 0", PHAssetMediaSubtype.photoLive.rawValue)

images = PHAsset.fetchAssets(with: options)

However, I don't know how to make a combination of the two... Is there any way to do this, perhaps by creating two NSPredicates?

Thanks


Solution

  • Here's how you get both Live Photos and still photos through PHAsset:

    Step 1: Create a NSPredicate to detect normal photos:

    let imagesPredicate = NSPredicate(format: "mediaType = %d", PHAssetMediaType.image.rawValue)
    

    Step 2: Create a NSPredicate to detect Live Photos:

    let liveImagesPredicate = NSPredicate(format: "(mediaSubtype & %d) != 0", PHAssetMediaSubtype.photoLive.rawValue)
    

    Step 3: Combine both with a NSCompoundPredicate:

    let compound = NSCompoundPredicate(orPredicateWithSubpredicates: [imagesPredicate, liveImagesPredicate])
    

    Step 4: Assign the NSCompoundPredicate to your PHFetchOptions:

    options.predicate = compound
    

    Step 5: Enjoy!

    So in your case:

    let options = PHFetchOptions()
    options.sortDescriptors = [
        NSSortDescriptor(key: "creationDate", ascending: false)
    ]
    
    // Get all still images
    let imagesPredicate = NSPredicate(format: "mediaType = %d", PHAssetMediaType.image.rawValue)
    
    // Get all live photos
    let liveImagesPredicate = NSPredicate(format: "(mediaSubtype & %d) != 0", PHAssetMediaSubtype.photoLive.rawValue)
    
    // Combine the two predicates into a statement that checks if the asset
    // complies to one of the predicates.
    options.predicate = NSCompoundPredicate(orPredicateWithSubpredicates: [imagesPredicate, liveImagesPredicate])