DOCUMENT-BASED APPS

Теперь SwiftUI поддерживает создание и редактирование пользовательских документов. Это могут быть абсолютно любые документы, такие как текстовые, графические или видео. Для этого SwiftUI предоставляет два новых типа: протокол FileDocument, который позволяет определить, как будет выглядеть документ в приложении, и структуру DocumentGroup, которая позволяет пользователям создавать, открывать и сохранять документы.

Создание приложения для работы с документами состоит из трех шагов:

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

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

Кроме этого нам так же надо будет создать объект с типом DocumentGroup, который позволить создавать файлы и отображать их в пользовательском интерфейсе.

Итак сейчас надо определить тип документа, с которым нам предстоит работать. В зависимости от типа документа контент можно сохранять в файлы с различными расширениями, например видео записи можно сохранять в формате mov, mp4 и т.д. Но сейчас в качестве примера мы будем использовать документ для работы с простым текстом PlainText. Нам нужно будет реализовать возможность для чтения, редактирования и сохранения документа на диск в виде файла.

Создаем проект и в файле ContentView импортируем фреймворк UniformTypeIdentifiers:

import UniformTypeIdentifiers

Это позволит определить тип данных с которыми будет работать ваш документ.

Теперь реализуем структуру, которая будет определять файл для работы с простым текстом:

struct TextFile: FileDocument {
// определяем типы файлов, с которыми мы будем работать
static var readableContentTypes = [UTType.plainText]
// свойство, определяющее контент документа
var text = ""
// инициализатор для создания пустого документа
init(initialText: String = "") {
text = initialText
}
// инициализатор для загрузки ранее сохраненных данных
init(fileWrapper: FileWrapper, contentType: UTType) throws {
if let data = fileWrapper.regularFileContents {
text = String(decoding: data, as: UTF8.self)
}
}
// метод для сохранения документа на диск
func write(to fileWrapper: inout FileWrapper, contentType: UTType) throws {
let data = Data(text.utf8)
fileWrapper = FileWrapper(regularFileWithContents: data)
}
}

Обратите внимание, как в методе write (to :) мы конвертируем нашу текстовую строку в экземпляр Data, а затем сохраняем ее с помощью FileWrapper. Мы не знаем, где должен храниться файл - iOS позаботится об этом за нас.

На втором шаге нам надо создать своего рода редактор, где пользователь сможет работать с текстом. Для этого в представлении ContentView объявим свойство document, обернув его в оболочку @Binding, чтобы оно обновляло текст в структуре TextFile, не создавая при этом локальной копии:

struct ContentView: View {
@Binding var document: TextFile
var body: some View {
TextEditor(text: $document.text)
}
}

And now our final step is to edit the main Swift file for the project to include a DocumentGroup, which presents the system-standard interface for browsing, opening, and creating files:

И на последнем шаге нам надо поработать в файле main Swift нашего проекта, включив в него DocumentGroup, который представляет стандартный системный интерфейс для просмотра, открытия и создания файлов:

@main
struct SwiftUIiOS14App: App {
var body: some Scene {
DocumentGroup(newDocument: TextFile()) { file in
ContentView(document: file.$document)
}
}
}

А так же инициализировать представление ContentView:

struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(document: .constant(TextFile()))
}
}

Запускаем симулятор и для создания нового текстового документа переходим на вкладку Browse. Нажимаем кнопку добавления и редактируем текстовую область. Все внесенные данные сохраняются при возврате.

Первоисточник