fileWrapper(configuration:)
Serializes a document snapshot to a file wrapper.
Declaration
func fileWrapper(configuration: Self.WriteConfiguration) throws -> FileWrapperParameters
- configuration:
Information about a file that already exists for the document, if any.
Return Value
The destination to serialize the document contents to. The value can be a newly created FileWrapper or an update of the one provided in the configuration input.
Discussion
To store a document — for example, in response to a Save command — SwiftUI calls this method. Use it to serialize the document’s data and create or modify a file wrapper with the serialized data:
func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {
let data = try JSONEncoder().encode(model)
return FileWrapper(regularFileWithContents: data)
}To store a document as a package — a directory containing multiple files — track which parts of the model changed and reuse WriteConfiguration/existingFile as the base directory wrapper to avoid rewriting unchanged files. The example below stores collection metadata in a file and each note in its own <uuid>.json file at the package root and only rewrites the files that changed:
struct NoteCollection: FileDocument {
var metadata: Metadata
var notes: [Note] = []
// ...
func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {
let documentPackage = configuration.existingFile
?? FileWrapper(directoryWithFileWrappers: [:])
let encoder = JSONEncoder()
// Update the metadata if it changed.
if metadata.isChanged {
if let old = documentPackage.fileWrappers?[Metadata.fileName] {
documentPackage.removeFileWrapper(old)
}
documentPackage.addRegularFile(
withContents: try encoder.encode(metadata),
preferredFilename: Metadata.fileName)
}
// Sync note wrappers with the notes collection.
let currentNotes = Set(notes.map(\.filename))
let notesFiles = documentPackage.fileWrappers ?? [:]
// Remove notes no longer in the collection.
for (filename, wrapper) in notesFiles {
if !currentNotes.contains(filename)
&& filename != Metadata.fileName {
documentPackage.removeFileWrapper(wrapper)
}
}
// Write notes that are new or changed.
for note in notes where note.isChanged {
if let old = documentPackage.fileWrappers?[note.filename] {
documentPackage.removeFileWrapper(old)
}
documentPackage.addRegularFile(
withContents: try encoder.encode(note),
preferredFilename: note.filename)
}
return documentPackage
}
}