如何使用带有PHFetchOptions的NSPredicate按媒体子类型进行过滤

bca*_*tle 12 cocoa-touch objective-c nspredicate ios photosframework

如何使用NSPredicatewith 过滤媒体子类型PHFetchOptions?我正在尝试排除慢速(高帧速率)和时间推移视频.当我尝试使用该predicate字段时,我一直得到奇怪的结果PHFetchOptions.

我的手机有一堆(120+)常规视频和一个慢动作视频.当我从Apple的文档中运行示例时,我得到了正确的结果:1个慢动作视频.

PHFetchOptions *options = [PHFetchOptions new];
options.predicate = [NSPredicate predicateWithFormat:@"(mediaSubtype & %d) != 0 || (mediaSubtype & %d) != 0", PHAssetMediaSubtypeVideoTimelapse, PHAssetMediaSubtypeVideoHighFrameRate];
Run Code Online (Sandbox Code Playgroud)

但我试图排除慢动作,而不是选择它.但是如果我否定过滤条件,我会得到零结果:

options.predicate = [NSPredicate predicateWithFormat:@"(mediaSubtype & %d) == 0", PHAssetMediaSubtypeVideoHighFrameRate];

<PHFetchResult: 0x1702a6660> count=0
Run Code Online (Sandbox Code Playgroud)

令人困惑的是,Apple文档将字段的名称列为mediaSubtypes(带有"s"),而它们的样本谓词是过滤的mediaSubtype(没有"s").

尝试过滤mediaSubtypes会产生错误:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Can't do bit operators on non-numbers'
Run Code Online (Sandbox Code Playgroud)

有没有人能够做出这个谓词的正面或反面?

Tar*_*agi 5

首先,让我说说Apple 上的sin mediaSubtypes可用PHAsset,只有Apple的Photo团队知道为什么mediaSubtype没有它的方式以及如何工作s

@property (nonatomic, assign, readonly) PHAssetMediaType mediaType;
@property (nonatomic, assign, readonly) PHAssetMediaSubtype mediaSubtypes;
Run Code Online (Sandbox Code Playgroud)

现在让我尝试解释为什么它无法按预期工作。这是使用NS_OPTIONS或任何其他按位运算进行比较的方式。

PHAsset* asset = // my asset;
if((asset.mediaSubtypes & PHAssetMediaSubtypePhotoScreenshot) == PHAssetMediaSubtypePhotoScreenshot) {
    // This is a screenshot
}
Run Code Online (Sandbox Code Playgroud)

您可以通过以下方式比较资产是否不是屏幕截图-

PHAsset* asset = // my asset;
if(!((asset.mediaSubtypes & PHAssetMediaSubtypePhotoScreenshot) == PHAssetMediaSubtypePhotoScreenshot)) {
// This is not a screenshot
}
Run Code Online (Sandbox Code Playgroud)

现在,对于您而言,谓词应为-

  • 以高帧频获取所有视频

    [NSPredicate predicateWithFormat:@"((mediaSubtype & %d) == %d)", PHAssetMediaSubtypeVideoHighFrameRate, PHAssetMediaSubtypeVideoHighFrameRate];
    
    Run Code Online (Sandbox Code Playgroud)
  • 提取所有视频而没有高帧率

    [NSPredicate predicateWithFormat:@"!((mediaSubtype & %d) == %d)", PHAssetMediaSubtypeVideoHighFrameRate, PHAssetMediaSubtypeVideoHighFrameRate];
    
    Run Code Online (Sandbox Code Playgroud)

就我而言,这很不错。希望它对其他人有帮助。