Как проверить импорт документов iOS и срок действия доступа к файлу

Как проверить импорт документов iOS и срок действия доступа к файлу

Когда команда отлаживает iOS-приложение на облачном Mac, легко принять успешный предварительный просмотр PDF, выбранного через приложение «Файлы», за завершённый импорт. Но приложение могло лишь временно получить доступ к внешнему файлу. При следующем запуске прежний путь может стать недоступным, и запись в списке чтения не откроется. Проверять нужно не то, появляется ли окно выбора, а права доступа, принадлежность файла и срок его доступности после передачи приложению внешним поставщиком.

Разберём это на примере импорта PDF для длительного хранения и чтения. К машине разработки можно подключиться удалённо, но правила доступа к файлам определяет iOS-устройство, на котором работает приложение. Разделим реализацию импорта и автоматизированные тесты: первая обрабатывает URL, полученный от настоящего окна выбора, вторые проверяют собственную копию приложения и сценарии ошибок.

Определите, когда импорт считается завершённым

Открыть файл — не значит получить собственную копию. При использовании UIDocumentPickerViewController(forOpeningContentTypes: [.pdf], asCopy: false) URL в обратном вызове указывает на расположение, предоставленное окном выбора. Его нельзя просто сохранить в записи списка чтения как постоянный путь. Если документ должен открываться и при следующем запуске, оригинал нужно прочитать, пока доступ к нему действителен, скопировать в постоянный каталог приложения и связать запись с новой копией.

Заранее задайте три наблюдаемых результата: отмена выбора не создаёт запись; ошибка копирования не создаёт запись об успешном импорте; после успешного импорта приложение открывает свою копию даже после перемещения оригинала и перезапуска. Временный каталог подходит для промежуточного этапа импорта, но не для постоянной библиотеки. Если запись должна храниться долго, переместите проверенную временную копию в постоянный каталог приложения, например Application Support.

Считать импорт успешным следует после записи и проверки копии, а не в момент, когда окно выбора вернуло URL.

Скопируйте файл с координацией, пока доступ действителен

Получив URL в обратном вызове окна выбора, сначала откройте доступ через область безопасности, затем согласуйте чтение с помощью NSFileCoordinator. Функция ниже показывает только временное сохранение одного небольшого PDF. Вызывающему коду ещё предстоит решить, как проверить содержимое, перенести файл в постоянный каталог и обновить запись. Пример использует режим открытия asCopy: false; его не следует превращать в универсальную функцию копирования, которая считает любой источник внешним файлом с предоставленным доступом.

func stagePickedPDF(_ url: URL) throws -> URL {
    guard url.startAccessingSecurityScopedResource() else {
        throw CocoaError(.fileReadNoPermission)
    }
    defer { url.stopAccessingSecurityScopedResource() }

    let destination = FileManager.default.temporaryDirectory
        .appendingPathComponent(UUID().uuidString)
        .appendingPathExtension("pdf")
    var coordinationError: NSError?
    var copyError: Error?

    NSFileCoordinator().coordinate(
        readingItemAt: url,
        options: [],
        error: &coordinationError
    ) { readableURL in
        do {
            try FileManager.default.copyItem(
                at: readableURL,
                to: destination
            )
        } catch {
            copyError = error
        }
    }

    if let coordinationError { throw coordinationError }
    if let copyError { throw copyError }
    return destination
}

Вызов coordinate синхронный: копирование большого файла не должно надолго блокировать поток интерфейса. В рабочей реализации весь процесс — открытие доступа, согласованное чтение и закрытие доступа — можно выполнять в фоновой задаче. Не закрывайте доступ в обратном вызове перед тем, как передать внешний URL фоновой задаче. При ошибке доступ тоже необходимо закрыть; здесь defer проще проверить, чем несколько вызовов закрытия в разных ветках.

Превратите временную копию в восстанавливаемую запись

После копирования убедитесь, что файл существует и его размер выглядит правдоподобно, а затем попробуйте открыть его PDF-парсером: одно расширение .pdf не подтверждает корректность содержимого. Если проверка прошла успешно, переместите файл в постоянный каталог приложения и сохраните относительный путь под идентификатором, созданным приложением. Если проверка или перемещение не удались, удалите временный файл, покажите пользователю ошибку с возможностью повторить попытку и не добавляйте документ в список чтения.

При сохранении данных учитывайте и промежуточный сбой: файл уже записан, а запись о нём — ещё нет. Один из вариантов — сначала создать запись в состоянии ожидания, а после перемещения пометить её как доступную. При запуске приложение может проверять незавершённые записи, сверять их с файлами и удалять остатки неудачных операций. Конкретная схема зависит от способа хранения данных, но цель одна: в списке не должно быть элементов, указывающих на несуществующий файл.

Не добавляйте отображаемое имя, предоставленное окном выбора, непосредственно в целевой путь. Создавайте имя файла в приложении, а исходное сохраняйте как поле для отображения. Это предотвращает перезапись при совпадении имён и снижает риск ошибок из-за символов в пути. Если продукт должен всегда читать внешний оригинал, а не хранить копию, потребуется другая модель доступа: отдельно продумайте повторное предоставление прав и интерфейс на случай недоступности источника. Использовать для этого состояние «импортировано локально» нельзя.

Проверяйте импорт по уровням на облачном Mac

Сначала с помощью XCTest подайте логике после импорта образцы PDF из песочницы приложения. Проверьте успешный разбор, ошибку для повреждённого файла, отсутствие перезаписи при совпадении имён и то, что после удаления временного файла запись в списке по-прежнему указывает на постоянную копию. Не выдавайте этот уровень тестов за проверку доступа через область безопасности: у файлов из песочницы обычно нет условий доступа, характерных для настоящего поставщика файлов.

Затем пройдите весь интерфейс в симуляторе. Подготовьте PDF, видимый в окне выбора приложения «Файлы», и проверьте отдельно выбор файла и отмену. После импорта закройте и снова запустите приложение, убедившись, что запись в списке чтения открывается. Затем попробуйте убрать исходный файл из доступного через окно выбора расположения и проверьте, действительно ли приложение читает собственную копию. Поведение поставщиков, которым нельзя надёжно управлять автоматически, заносите в список ручных проверок; не маскируйте неопределённость ожиданием фиксированного числа секунд.

Наконец, проверьте права доступа и загрузку на целевом устройстве с теми поставщиками файлов, которыми будут пользоваться на практике. Некоторые документы в момент выбора ещё не полностью загружены на устройство. Если чтение не удалось, интерфейс должен показать ошибку и позволить выбрать файл снова, а не создавать пустую копию. Здесь проверяется обработка ошибки, а не гарантируется время загрузки со стороны поставщика.

Завершите проверку матрицей ошибок

Действие Ожидаемый результат
Отмена выбора Список чтения не изменился, временных файлов не осталось
Источник недоступен для чтения Показана понятная ошибка, запись об успешном импорте не создана
Проверка копии не пройдена Временный файл удалён, доступна повторная попытка
Источник перемещён после импорта После перезапуска копия приложения по-прежнему открывается
Приложение прервано во время импорта При следующем запуске незавершённая запись обнаружена и обработана

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

Часто задаваемые вопросы

Можно ли сохранить путь, полученный из окна выбора документа?

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

Достаточно ли симулятора для проверки импорта документов?

Нет. В нём удобно проверять копирование, обработку и ошибки, но разрешения, отмену выбора и перемещение исходного файла нужно проверить и с реальным поставщиком файлов.

XCZone · облачный Mac

Нужен выделенный физический Mac с удалённым доступом?

Сравните конфигурации M4 Start, M4 Work и M4 Pro, расположение узлов и периоды оплаты, чтобы выбрать подходящий вариант.

Посмотреть тарифы на облачный Mac