Как фильтровать подтипом мультимедиа, используя NSPredicate с PHFetchOptions

142
15

Как фильтровать субтитры с помощью NSPredicate с помощью PHFetchOptions?
Я пытаюсь исключить медленные (высокие частоты кадров) и видеоролики с временным временем. Я получаю странные результаты, когда пытаюсь использовать поле predicate PHFetchOptions.


В моем телефоне есть куча (120+) обычных видеороликов и одно медленное видео. Когда я запускаю пример из Apple docs, я получаю правильный результат: 1 медленное видео mo.


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

Но я пытаюсь исключить медленный mo, а не выбирать его. Однако, если я отрицаю условие фильтра, я возвращаю нулевые результаты:


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'

Кто-нибудь мог сделать головы или хвосты этого предиката?

спросил(а) 2015-07-21T03:23:00+03:00 5 лет, 4 месяца назад
1
Решение
83

Прежде всего, позвольте мне сказать о s в mediaSubtypes, доступном на PHAsset, и только команда Photos в 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
}

Вот как вы бы сравнили, чтобы увидеть, не является ли ресурс скриншотом -

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

Это прекрасно работает в моем случае. Надеюсь, это поможет кому-то еще.

ответил(а) 2016-09-08T15:16:00+03:00 4 года, 2 месяца назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема