Error: 'Unsupported predicate in fetch options: mediaType == 2'
Asked Answered
P

2

15

I'm trying to use smartAlbum to generate an array of either only videos or only photos or both.
You can see my code below:

    PHFetchResult *collectionList = [PHCollectionList fetchMomentListsWithSubtype:PHCollectionListSubtypeMomentListCluster options:nil];
    PHFetchOptions *options = nil;
        if (self.xSelected) {
            options = [[PHFetchOptions alloc] init];
            options.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:NO]];
            options.predicate = [NSPredicate predicateWithFormat:@"mediaType = %d",PHAssetMediaTypeImage];
        }
        if (self.ySelected) {
            options = [[PHFetchOptions alloc] init];
            options.predicate = [NSPredicate predicateWithFormat:@"mediaType = %d",PHAssetMediaTypeVideo];
        }

    [collectionList enumerateObjectsUsingBlock:^(PHCollectionList *collection, NSUInteger idx, BOOL *stop) {
        PHFetchResult *momentsInCollection = [PHAssetCollection fetchMomentsInMomentList:collection options:options];
        for (id moment in momentsInCollection) {
            PHAssetCollection *castedMoment = (PHAssetCollection *)moment;
            [_smartAlbums insertObject:castedMoment atIndex:0];
        }
    }];


This however is constantly breaking on the first line inside the block and giving the following error: Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unsupported predicate in fetch options: mediaType == 2'

I did a little research and found this link.
I'm wondering if this is an Apple bug or if its just something wrong with my code.
It seems like it worked for the people that referred to this answer, which is so weird coz its basically the same thing.


Thanks in advance,
Anish

EDIT:
I think I found the answer here in Apple's Documentation. Looks like mediaType is a key only for PHAsset and not PHAssetCollection. So now I guess the question is how to get PFAssetCollection with only videos or only images.

Philosophy answered 23/2, 2016 at 23:52 Comment(1)
Did you work out how to fetch PHAssetCollection with only videos or images?Geilich
D
0

Use this method to get photos and videos assets array separately.

Get All Videos

func getAllVideos(completion:@escaping  (_ videoAssets : [PHAsset]?) -> Void) {
    var videoAssets : [PHAsset] = []

    let fetchOptions = PHFetchOptions()
    fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate",ascending: false)]
    fetchOptions.predicate = NSPredicate(format: "mediaType = %d", PHAssetMediaType.video.rawValue)
    let allVideo = PHAsset.fetchAssets(with: .video, options: fetchOptions)
    allVideo.enumerateObjects { (asset, index, bool) in
        videoAssets.append(asset)
    }
    completion(videoAssets)
}

Get All Photos

func getAllPhotos(completion:@escaping  (_ photosAssets : [PHAsset]?) -> Void) {
    var photosAssets : [PHAsset] = []

    let fetchOptions = PHFetchOptions()
    let scale = UIScreen.main.scale
    let screenWidth = UIScreen.main.bounds.width * scale
    let screenHeight = UIScreen.main.bounds.height  * scale

    fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate",ascending: false)]
    fetchOptions.predicate = NSPredicate(format: "mediaType = %d || (mediaSubtype & %d) != 0 && (pixelHeight != %d AND pixelWidth != %d) OR (pixelHeight != %d AND pixelWidth != %d)", PHAssetMediaType.image.rawValue, PHAssetMediaSubtype.photoLive.rawValue ,screenHeight, screenWidth, screenWidth, screenHeight)

    let allPhotos = PHAsset.fetchAssets(with: .image, options: fetchOptions)
    allPhotos.enumerateObjects { (asset, index, bool) in
        photosAssets.append(asset)
    }
    completion(photosAssets)
}
Dorran answered 8/2, 2019 at 6:47 Comment(0)
M
0

No need to put mediaType in predicate In swift 4.0 this is how i used fetchAsset() method from Photos framework , to get all videos from photo library.

You can also get the video from specific folder using predicate.

   func fetchAllVideos()
{
    //let albumName = "blah"
    let fetchOptions = PHFetchOptions()
    //        fetchOptions.predicate = NSPredicate(format: "title = %@", albumName)
    //uncomment this if you want video from custom folder
    fetchOptions.predicate = NSPredicate(format: "mediaType = %d ", PHAssetMediaType.video.rawValue )

    let allVideo = PHAsset.fetchAssets(with: .video, options: fetchOptions)
    allVideo.enumerateObjects { (asset, index, bool) in
        // videoAssets.append(asset)
        let imageManager = PHCachingImageManager()
        imageManager.requestAVAsset(forVideo: asset, options: nil, resultHandler: { (asset, audioMix, info) in
            if asset != nil {
                let avasset = asset as! AVURLAsset
                let urlVideo = avasset.url
                print(urlVideo)

            }
        })

    }

}

Hope this help!!!

Mccauley answered 22/11, 2019 at 14:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.