【问题标题】:Error: 'Unsupported predicate in fetch options: mediaType == 2'错误:“获取选项中不支持的谓词:mediaType == 2”
【发布时间】:2016-06-06 01:31:12
【问题描述】:

我正在尝试使用 smartAlbum 生成仅包含视频或仅包含照片或两者的数组。
您可以在下面看到我的代码:

    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];
        }
    }];


然而,这在block 内的第一行不断中断,并给出以下错误: Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unsupported predicate in fetch options: mediaType == 2'

我做了一些研究,发现了这个link
我想知道这是 Apple 的错误还是我的代码有问题。
似乎它适用于提到这个answer 的人,这太奇怪了,因为它基本上是一样的。


在此先感谢,
阿尼什

编辑:
我想我在 Apple 的文档中找到了答案 here。看起来 mediaType 仅适用于 PHAsset 而不是 PHAssetCollection。所以现在我想问题是如何获得PFAssetCollection 只有视频或只有图像。

【问题讨论】:

  • 你知道如何仅使用视频或图像获取PHAssetCollection 吗?

标签: ios iphone nspredicate photosframework


【解决方案1】:

使用此方法分别获取照片和视频资产数组。

获取所有视频

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

获取所有照片

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】:

    无需将 mediaType 放在谓词中 在 swift 4.0 中,我使用 Photos framework 中的 fetchAsset() 方法从照片库中获取所有视频。

    您还可以使用谓词从特定文件夹中获取视频。

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

    希望有帮助!!!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-06-29
      • 2021-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-02
      • 1970-01-01
      相关资源
      最近更新 更多