Подтвердить что ты не робот

+ [AVURLAsset isPlayableExtendedMIMEType:] ведет себя по-разному при тестировании устройства

В моем приложении, вызывающем [AVURLAsset isPlayableExtendedMIMEType:@"video/mp4; codecs=\"avc1.64001F, mp4a.40.2\""], возвращается YES, что ожидается.

Если я запустил тот же самый код в unit test, он возвращает NO.

Оба приложения и unit test запускаются с Xcode 5.0.2 на iPhone Retina (4-дюймовый) симулятор с iOS 7.0.

- (void) testPlayableExtendedMIMEType
{
    XCTAssertTrue([AVURLAsset class], @"");
    XCTAssertTrue([AVURLAsset isPlayableExtendedMIMEType:@"video/mp4; codecs=\"avc1.64001F, mp4a.40.2\""], @"");
}

Первое утверждение проходит, но второе утверждение терпит неудачу.

Почему это поведение будет отличаться в unit test и в приложении?

4b9b3361

Ответ 1

После обратного проектирования, как +[AVURLAsset isPlayableExtendedMIMEType:] реализовано, я нашел причину проблемы.

Вот трассировка стека того, что он делает:

frame #0: 0x01b2861e CoreMedia`CelestialGetModelSpecificName
frame #1: 0x01b2885a CoreMedia`CelestialCFCreatePropertyListFromBundleIdentifier + 11
frame #2: 0x00050039 AVFoundation`__33+[AVURLAsset _avfValidationPlist]_block_invoke_0 + 39
frame #3: 0x02e99014 libdispatch.dylib`_dispatch_client_callout + 14
frame #4: 0x02e8b09f libdispatch.dylib`dispatch_once_f + 57
frame #5: 0x02e8b061 libdispatch.dylib`dispatch_once + 31
frame #6: 0x00050006 AVFoundation`+[AVURLAsset _avfValidationPlist] + 49
frame #7: 0x00050664 AVFoundation`+[AVURLAsset isPlayableExtendedMIMEType:] + 64

Функция CelestialCFCreatePropertyListFromBundleIdentifier пытается прочитать файл MediaValidator.plist внутри рамки MediaToolbox. Расположение файла plist зависит от имени модели устройства. Ниже приведены различные файлы MediaValidator.plist для симулятора iOS 7.

MediaToolbox.framework
|-- J1
|   `-- MediaValidator.plist
|-- K93
|   `-- MediaValidator.plist
|-- N41
|   `-- MediaValidator.plist
`-- N94
    `-- MediaValidator.plist

При запуске приложения функция CelestialGetModelSpecificName возвращает N41, i.e. iPhone 5.
При выполнении модульных тестов функция CelestialGetModelSpecificName возвращает N88, то есть iPhone 3GS. Как вы можете видеть, в среде MediaToolbox нет каталога N88, поэтому +[AVURLAsset isPlayableExtendedMIMEType:] в конечном итоге терпит неудачу.

Более пристальный взгляд на функцию CelestialGetModelSpecificName показывает решение. Симулятор читает переменную среды IPHONE_SIMULATOR_CLASS, чтобы знать, какое устройство моделируется. Если переменная среды IPHONE_SIMULATOR_CLASS не установлена, то она по умолчанию имеет значение hardcoded N88.

Итак, чтобы тест прошел, нам просто нужно вручную установить переменную среды IPHONE_SIMULATOR_CLASS в N41, так как бегун unit test не устанавливает ее автоматически.

setenv("IPHONE_SIMULATOR_CLASS", "N41", 0);