Хотя я могу использовать модификатор fileExporter()
для экспорта документов в памяти, то есть однофайлового документа (.txt
, .jpg
, ...), а также для пользовательских типов файлов (после регистрации их в настройках проекта с определенным UTType
), я не могу понять, как использовать этот модификатор для экспорта/сохранения документа пакета.
У меня есть единое приложение для iOS/macOS, которое использует project.json
в дополнение к файлам, выбранным пользователем. Моя папка с документами пользовательского пакета выглядит примерно так:
/Users/xyz/somefolder/MyAppFile.myfile
----- project.json
----- file001.mp4
----- file002.jpg
----- file003.mp3
----- etc, etc...
Протокол FileDocument
запрашивает Data
при сохранении, это правильно, когда вам нужно экспортировать один файл, но не тогда, когда вам нужна папка, в которой вы сохраняете и копируете файл во время обычного использования приложения.
@Sweeper да :-) У тебя, наверное, проблема. Обычно я реализую fileWrapper(configuration:)
. Не могли бы вы показать пример в ответе? Это может быть правильный вариант!
В реализации fileWrapper(configuration:)
создайте FileWrapper
, используя init(directoryWithFileWrappers:). Это создаст FileWrapper
, представляющий каталог.
Например, вот очень простая реализация FileDocument
:
struct MyFile: FileDocument {
init() {}
init(configuration: ReadConfiguration) throws {
}
func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {
FileWrapper(directoryWithFileWrappers: [
"project.json": FileWrapper(
regularFileWithContents: """
{ "some key": "some value" }
""".data(using: .utf8)!
),
"foo.txt": FileWrapper(
regularFileWithContents: """
Lorem Ipsum
""".data(using: .utf8)!
),
])
}
static let readableContentTypes: [UTType] =
[.init(exportedAs: "your.exported.uttype.identifier", conformingTo: .package)]
}
При экспорте будет создан пакет с двумя файлами — project.json и foo.txt.
Пример использования с .fileExporter
:
@State var presented = false
var body: some View {
Button("Export") {
presented = true
}.fileExporter(isPresented: $presented, document: MyFile(), defaultFilename: "Foo") { _ in
// ...
}
}
Большое спасибо. Поэтому я использую эту оболочку для создания каталога пакета и сохраняю project.json
каждый раз, когда пользователь сохраняет его. И я копирую дополнительные файлы, используя классический метод копирования элемента FileManager
внутри этой директории?
@AltairJones Немного сложно говорить об этом, не видя вашего реального кода. Я думаю, что то, что вы описываете, сработает, но почему вы не можете также представить «дополнительные файлы» с помощью FileWrapper
? Передайте данные из этих файлов в FileWrapper(regularFileWithContents: ...)
или, если это существующий файл, используйте FileWrapper(url: ...)
.
извините, я объясню эту идею, поэтому, если у вас есть какие-либо подсказки, которые лучше подходят, я буду рад, если вы поделитесь со мной. Это приложение для редактирования видео. Пользователь создает проект (папку пакета, содержащую файл .json
). Во время работы с приложением пользователь добавляет фильмы и аудиоклипы. Таким образом, приложение перед добавлением их на временную шкалу копирует эти файлы внутри пакета, чтобы к ним можно было безопасно получить доступ позже.
@AltairJones Хорошо, то, что я сказал, остается в силе. Предполагая, что у вас есть URL-адреса аудио- и видеофайлов, выбранных пользователем, вы можете использовать FileWrapper(url: ...)
для создания оболочек файлов, представляющих видео и аудиоклипы. Затем вы можете добавить их в каталог пакета, используя addFileWrapper в цикле. Если у вас есть конкретная проблема по этому поводу, вам, вероятно, следует опубликовать новый вопрос.
«Протокол
FileDocument
запрашиваетData
при сохранении» Можете ли вы продемонстрировать, как это сделать?FileDocument
насколько я знаю, вообще этого не делает. Вы применяете методfileWrapper(configuration:)
? Если да, вы можете просто вернутьFileWrapper(directoryWithFileWrappers: ...)
.