Вопрос или проблема
Я сталкиваюсь с ошибкой на iOS 18.0.1 при попытке воспроизвести видео из медиатеки устройства. Ошибка появляется только на физическом устройстве, а не в симуляторе.
(lldb) po error
Error Domain=NSCocoaErrorDomain Code=257 "Файл “IMG_0005.MOV” не может быть открыт, потому что у вас нет разрешения на его просмотр." UserInfo={NSURL=file:///var/mobile/Media/DCIM/100APPLE/IMG_0005.MOV#YnBsaXN0MDDRAQJfEBtSZWNvbW1lbmRlZEZvckltbWVyc2l2ZU1vZGUQAAgLKQAAAAAAAAEBAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAr, AVErrorFailedDependenciesKey=(
"assetProperty_AssetType",
"assetProperty_MediaPlaybackValidation"
), NSUnderlyingError=0x302d3c330 {Error Domain=NSOSStatusErrorDomain Code=-12203 "(null)"}}
Сообщение от отладчика: убито
Код:
func playVideo(_ url: URL) async throws {
let asset = AVAsset(url: url)
let isPlayable: Bool
if #available(iOS 15, *) {
isPlayable = try await asset.load(.isPlayable)
} else {
isPlayable = asset.isPlayable
}
if isPlayable {
DispatchQueue.main.async {
let player = AVPlayer(url: url)
let playerViewController = AVPlayerViewController()
playerViewController.player = player
self.coordinator.present(playerViewController)
player.play()
}
} else {
throw CAMError.playVideoIssue
}
}
Файл хранится здесь:
file:///var/mobile/Media/DCIM/100APPLE/IMG_0005.MOV#YnBsaXN0MDDRAQJfEBtSZWNvbW1lbmRlZEZvckltbWVyc2l2ZU1vZGUQAAgLKQAAAAAAAAEBAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAr
В этом коде isPlayable = try await asset.load(.isPlayable)
возвращает false
на физическом устройстве, но возвращает true
в симуляторе.
Что может быть причиной этого расхождения и как я могу исправить эту ошибку разрешения на физическом устройстве?
Ответ или решение
Ошибка NSCocoaErrorDomain Code=257 в iOS 18.0.1, связанная с AVAsset, возникает, когда ваше приложение пытается получить доступ к видеофайлу, но сталкивается с проблемами прав доступа на физическом устройстве. Эта ситуация обычно обусловлена тем, что для доступа к файлам медиа необходимо получить соответствующие разрешения от пользователя.
Причины возникновения ошибки NSCocoaErrorDomain Code=257:
-
Права доступа к медиафайлам: На устройствах iOS необходимо предоставление прав доступа к библиотеке медиа (фото и видео). Возможно, ваше приложение не имеет запрашиваемых прав доступа.
-
Симулятор против устройства: Симулятор iOS имеет прямой доступ ко многим ресурсам, тогда как физическое устройство требует более строгих мер безопасности. Таким образом, то, что работает в симуляторе, может не работать на реальном устройстве из-за ограниченных прав доступа.
-
Требуемые свойства AVAsset: Ошибка может указывать на отсутствие доступа к определенным свойствам видеоактива, что связано с правами доступа к файлам.
Решение проблемы:
-
Проверьте и запросите права на доступ к медиа:
Убедитесь, что ваше приложение имеет разрешения на доступ к библиотеке медиа:
import Photos func requestMediaLibraryAuthorization() { let status = PHPhotoLibrary.authorizationStatus() if status == .notDetermined { PHPhotoLibrary.requestAuthorization { newStatus in if newStatus == .authorized { // Права получили, можно продолжать } } } else if status == .authorized { // Права уже есть } else { // Права не предоставлены, сообщите пользователю } }
Вам необходимо вызывать
requestMediaLibraryAuthorization()
перед попыткой доступа к видео. -
Проверка доступности файла:
Перед тем как создавать
AVAsset
, проверьте доступность файла:guard FileManager.default.fileExists(atPath: url.path) else { throw NSError(domain: NSCocoaErrorDomain, code: 257, userInfo: [NSLocalizedDescriptionKey: "Файл не найден."]) }
-
Проверка доступности в самом AVAsset:
Попробуйте добавить дополнительный уровень обработки ошибок для проверки доступности:
do { let isPlayable = try await asset.load(.isPlayable) if !isPlayable { throw NSError(domain: NSCocoaErrorDomain, code: 257, userInfo: [NSLocalizedDescriptionKey: "Файл не может быть воспроизведен."]) } } catch { print("Ошибка загрузки asset: \(error.localizedDescription)") throw error }
-
Проверка настроек конфиденциальности:
Проверьте настройках конфиденциальности на вашем устройстве, что приложение имеет необходимые разрешения для доступа к медиафайлам.
Заключение:
Ошибка NSCocoaErrorDomain Code=257 может быть устранена через правильное управление правами доступа к библиотеке медиа, в сочетании с обработкой ошибок. Убедитесь, что ваше приложение запрашивает у пользователя доступ при первом запуске и имеет необходимые разрешения, прежде чем пытаться получить доступ к медиафайлам. Это позволит вам безопасно и эффективно работать с видеофайлами на физическом устройстве iOS.