NSCocoaErrorDomain Код=257 – Ошибка прав доступа к файлу в iOS 18.0.1 для AVAsset на Swift

Вопрос или проблема

Я сталкиваюсь с ошибкой на 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:

  1. Права доступа к медиафайлам: На устройствах iOS необходимо предоставление прав доступа к библиотеке медиа (фото и видео). Возможно, ваше приложение не имеет запрашиваемых прав доступа.

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

  3. Требуемые свойства AVAsset: Ошибка может указывать на отсутствие доступа к определенным свойствам видеоактива, что связано с правами доступа к файлам.

Решение проблемы:

  1. Проверьте и запросите права на доступ к медиа:

    Убедитесь, что ваше приложение имеет разрешения на доступ к библиотеке медиа:

    import Photos
    
    func requestMediaLibraryAuthorization() {
       let status = PHPhotoLibrary.authorizationStatus()
       if status == .notDetermined {
           PHPhotoLibrary.requestAuthorization { newStatus in
               if newStatus == .authorized {
                   // Права получили, можно продолжать
               }
           }
       } else if status == .authorized {
           // Права уже есть
       } else {
           // Права не предоставлены, сообщите пользователю
       }
    }

    Вам необходимо вызывать requestMediaLibraryAuthorization() перед попыткой доступа к видео.

  2. Проверка доступности файла:

    Перед тем как создавать AVAsset, проверьте доступность файла:

    guard FileManager.default.fileExists(atPath: url.path) else {
       throw NSError(domain: NSCocoaErrorDomain, code: 257, userInfo: [NSLocalizedDescriptionKey: "Файл не найден."])
    }
  3. Проверка доступности в самом 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
    }
  4. Проверка настроек конфиденциальности:

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

Заключение:

Ошибка NSCocoaErrorDomain Code=257 может быть устранена через правильное управление правами доступа к библиотеке медиа, в сочетании с обработкой ошибок. Убедитесь, что ваше приложение запрашивает у пользователя доступ при первом запуске и имеет необходимые разрешения, прежде чем пытаться получить доступ к медиафайлам. Это позволит вам безопасно и эффективно работать с видеофайлами на физическом устройстве iOS.

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

Капча загружается...