如何使用 NSPredicate
和 PHFetchOptions
按媒体子类型进行过滤?
我试图排除慢动作(高帧率)和延时视频。当我尝试使用 PHFetchOptions
的 predicate
字段时,我总是得到奇怪的结果。
我的手机有一堆 (120+) 常规视频和一个慢动作视频。当我运行来自 Apple's docs 的示例时,我得到正确的结果:1 慢动作视频。
PHFetchOptions *options = [PHFetchOptions new];
options.predicate = [NSPredicate predicateWithFormat:@"(mediaSubtype & %d) != 0 || (mediaSubtype & %d) != 0", PHAssetMediaSubtypeVideoTimelapse, PHAssetMediaSubtypeVideoHighFrameRate];
但我试图排除慢动作,而不是选择它。但是,如果我否定过滤条件,我会得到零结果:
options.predicate = [NSPredicate predicateWithFormat:@"(mediaSubtype & %d) == 0", PHAssetMediaSubtypeVideoHighFrameRate];
<PHFetchResult: 0x1702a6660> count=0
令人困惑的是,Apple 文档将字段名称列为 mediaSubtypes
(带有“s”),而他们的示例谓词正在过滤 mediaSubtype
(没有“s”)。
尝试过滤 mediaSubtypes
会产生错误:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Can't do bit operators on non-numbers'
有没有人能够得出这个谓词的正面或反面?
最佳答案
首先,让我谈谈 PHAsset
上可用的 mediaSubtypes
中的 s
,只有 Apple 的照片团队知道为什么以及如何使用 mediaSubtype
在没有 s
的情况下工作。
@property (nonatomic, assign, readonly) PHAssetMediaType mediaType;
@property (nonatomic, assign, readonly) PHAssetMediaSubtype mediaSubtypes;
现在让我试着解释一下为什么它没有按预期工作。以下是使用 NS_OPTIONS 或任何其他按位运算进行比较的方式。
PHAsset* asset = // my asset;
if((asset.mediaSubtypes & PHAssetMediaSubtypePhotoScreenshot) == PHAssetMediaSubtypePhotoScreenshot) {
// This is a screenshot
}
以下是您将如何比较 Assets 是否不是屏幕截图-
PHAsset* asset = // my asset;
if(!((asset.mediaSubtypes & PHAssetMediaSubtypePhotoScreenshot) == PHAssetMediaSubtypePhotoScreenshot)) {
// This is not a screenshot
}
现在在你的情况下谓词应该是-
获取所有高帧率的视频
[NSPredicate predicateWithFormat:@"((mediaSubtype & %d) == %d)", PHAssetMediaSubtypeVideoHighFrameRate, PHAssetMediaSubtypeVideoHighFrameRate];
获取所有没有高帧率的视频
[NSPredicate predicateWithFormat:@"!((mediaSubtype & %d) == %d)", PHAssetMediaSubtypeVideoHighFrameRate, PHAssetMediaSubtypeVideoHighFrameRate];
这对我来说效果很好。希望对其他人有帮助。
关于ios - 如何使用带 PHFetchOptions 的 NSPredicate 按媒体子类型进行过滤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31528441/