iOS 18 PHAsset URL из requestAVAsset

от автора

Всем привет! Сегодня я с большой радостью буду обсуждать iOS 18. Наконец-то, уважаемые коллеги, пришло время и мне приобщиться к этой замечательной операционной системе — iOS 18 beta 4. Главной причиной моего участия стали наши продвинутые пользователи, которые уже активно тестируют iOS 18. Спасибо вам за это!

Сразу скажу, что я истинный любитель Apple и все, что с ней связано, вызывает у меня огромный интерес.

Стоит отметить, что iOS 18 beta 4 я буду сокращенно называть iOS 18. Также важно понимать, что методы и способы работы с ними могут измениться в релизной версии iOS 18.

В статье я поделюсь своим недавним опытом работы со следующими методами под iOS 18 beta 4, которые удивительным образом отличаются от предыдущих версий iOS.

Методы, которые я рассмотрю:

  • PHCachingImageManager().requestAVAsset()

  • FileManager.default.fileExists()

  • avAssetImageGenerator.copyCGImage(at:)

  • avAssetImageGenerator.generateCGImagesAsynchronously()

  • URL(filePath:)

Причина, по которой я выбрал именно эти методы, проста: отработанная технология, успешно работающая на iOS 15-17, дала сбой в них.

Все эти методы относятся к работе с медиафайлами пользователя и способам обращения к ним: path и URL. В статье я не буду подробно рассматривать детали работы с path и URL. Рекомендую ознакомиться с хорошей статьей на эту тему:

Напомню, что:

Path:

  • Для медиа файлов на симуляторе:

    /Users/someUser/Library/Developer/CoreSimulator/Devices/062F31BC-B783-40E6-AD93-F5ABA5CF4636/data/Media/DCIM/100APPLE/IMG_0001.MOV 
  • Для файлов приложения на симуляторе:

    /Users/someUser/Library/Developer/CoreSimulator/Devices/062F31BC-B783-40E6-AD93-F5ABA5CF4636/data/Containers/Data/Application/E3C0E780-2249-4EE5-BDAE-A1FE5BCEDCC4/Documents/Media/Videos/IMG_0001.MOV 

На устройстве:

  • Для медиа файлов:

    file:///var/mobile/Media/DCIM/118APPLE/IMG_8018.MP4 
  • Для файлов приложения:

    /var/mobile/Containers/Data/Application/07B67A27-4573-4A1E-9DA1-DB0E1437945D/Documents/Media/Videos/IMG_0001.MP4 

Начнем с метода requestAVAsset

Метод requestAVAsset позволяет получить AVAsset для работы с медиа. Запрос вызывается следующим образом:

@available(iOS 8, *) open func requestAVAsset(forVideo asset: PHAsset, options: PHVideoRequestOptions?, resultHandler: @escaping (AVAsset?, AVAudioMix?, [AnyHashable: Any]?) -> Void) -> PHImageRequestID 

Пример использования:

PHCachingImageManager().requestAVAsset(     forVideo: userPhoto.imageAsset,     options: options ) { asset, _, _ in     if let asset = asset as? AVURLAsset {         print(asset.url.absoluteString)        // выводит строку пути       // file:///var/mobile/Media/DCIM/118APPLE/IMG_0001.MP4#YnBsaXN0MDDRAQJfEBtSZWNvbW1lbmRlZEZvckltbWVyc2l2ZU1vZGUQAAgLKQAAAAAAAAEBAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAr                print(asset.url.relativePath)        // выводит относительный путь       // prints: /var/mobile/Media/DCIM/118APPLE/IMG_0001.MP4     } } 

В результате запроса после типа файла (.mov или .mp4) добавляется странная строка/суффикс, например, #YnBsa.... Я еще не выяснил, что это означает, но для симулятора и устройства значение идентично. Возможно, это связано с Apple ID.

Далее нас ждут различные преобразования с медиафайлом, и, скорее всего, мы сохраним путь к файлу в медиатеке, чтобы не хранить само медиа.

Метод fileExists(atPath:)

Из документации:

open func fileExists(atPath path: String) -> Bool 

Для проверки существования файла после выполнения каких-либо операций:

let relativePath = someUrl.relativePath let absolutePath = someUrl.absoluteString FileManager.default.fileExists(atPath: relativePath) // вернет true FileManager.default.fileExists(atPath: absolutePath) // вернет false 

В данном случае это объясняется тем, что fileExists(atPath: absolutePath) ищет файл с суффиксом #YnBsa....

Метод AVAssetImageGenerator.generateCGImagesAsynchronously

Из документации:

open func generateCGImagesAsynchronously(forTimes requestedTimes: [NSValue], completionHandler handler: @escaping AVAssetImageGeneratorCompletionHandler) 

Предположим, мы используем строку, которую использовали для проверки fileExists, которая не содержит дополнительного элемента #YnBsa...:

let relativePath = someUrl.relativePath let absolutePath = someUrl.absoluteString var newURL = URL(filePath: relativePath) let asset = AVAsset(url: newURL) let avAssetImageGenerator = AVAssetImageGenerator(asset: asset) avAssetImageGenerator.generateCGImagesAsynchronously(forTimes: Array([time, time])) { time, cgImage, _, result, error in if let error { print(error.localizedDescription) // получаем ошибку return } } 

В этом случае мы получаем ошибку: «Не удалось открыть файл «IMG_0001.MOV», так как у Вас нет разрешения на его просмотр.»

po error.localizedDescription  some : Error Domain=NSCocoaErrorDomain Code=257 "Не удалось открыть файл «IMG_0001.MOV», так как у Вас нет разрешения на его просмотр." UserInfo={NSURL=file:// /var/mobile/Media/DCIM/118APPLE/IMG_0001.MOV, AVErrorFailedDependenciesKey=( «assetProperty_AssetType" 

Если использовать someUrl.absoluteString:

var newURL = URL(fileURLWithPath: someUrl.absoluteString) let asset = AVAsset(url: newURL) let avAssetImageGenerator = AVAssetImageGenerator(asset: asset) 

То generateCGImagesAsynchronously будет работать как положено.

Итог

Таким образом, в iOS 18 мы получили новую защиту доступа к работе AVAssetImageGenerator, используя дополнительный ключ.

Где найти документацию?

Это вопрос времени.

А пока…

Любим, кодим, изучаем!


ссылка на оригинал статьи https://habr.com/ru/articles/831902/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *