Error: 'Unsupported predicate in fetch options: mediaType == 2'

狂风中的少年 提交于 2019-12-03 11:39:27

问题


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.


回答1:


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)
}



回答2:


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!!!



来源:https://stackoverflow.com/questions/35590640/error-unsupported-predicate-in-fetch-options-mediatype-2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!