Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save theoknock/4b85498d7ac19bfb4a05760cd9803b90 to your computer and use it in GitHub Desktop.
Save theoknock/4b85498d7ac19bfb4a05760cd9803b90 to your computer and use it in GitHub Desktop.
import SwiftUI
import UniformTypeIdentifiers
struct MyStruct: Codable, Identifiable {
let id: Int
var name: String
}
struct ContentView: View {
@State private var structs = [MyStruct]()
@State private var isExporting = false
@State private var isImporting = false
var body: some View {
VStack {
Button("Generate Dummy Data") {
generateDummyData()
}
Button("Export") {
isExporting = true
}
.fileExporter(isPresented: $isExporting, document: StructsDocument(structs: structs), contentType: .json) { result in
switch result {
case .success(let url):
print("Exported to \(url)")
case .failure(let error):
print("Failed to export: \(error)")
}
}
Button("Import") {
isImporting = true
}
.fileImporter(isPresented: $isImporting, allowedContentTypes: [.json], allowsMultipleSelection: false) { result in
switch result {
case .success(let urls):
guard let url = urls.first else { return }
do {
guard url.startAccessingSecurityScopedResource() else {
print("Failed to gain secure access to the file")
return
}
defer { url.stopAccessingSecurityScopedResource() }
let data = try Data(contentsOf: url)
var importedStructs = try JSONDecoder().decode([MyStruct].self, from: data)
importedStructs = importedStructs.map { MyStruct(id: $0.id, name: $0.name.uppercased()) }
structs = importedStructs
} catch {
print("Failed to read or decode file: \(error)")
}
case .failure(let error):
print("Failed to import: \(error)")
}
}
List(structs) { myStruct in
Text("\(myStruct.id): \(myStruct.name)")
}
}
}
func generateDummyData() {
structs = [
MyStruct(id: 1, name: "Alice"),
MyStruct(id: 2, name: "Bob"),
MyStruct(id: 3, name: "Charlie")
]
}
}
struct StructsDocument: FileDocument {
static var readableContentTypes: [UTType] { [.json] }
static var writableContentTypes: [UTType] { [.json] }
var structs: [MyStruct]
init(structs: [MyStruct]) {
self.structs = structs
}
init(configuration: ReadConfiguration) throws {
guard let data = configuration.file.regularFileContents else {
throw CocoaError(.fileReadCorruptFile)
}
structs = try JSONDecoder().decode([MyStruct].self, from: data)
}
func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {
let data = try JSONEncoder().encode(structs)
return FileWrapper(regularFileWithContents: data)
}
}
@appfrosch
Copy link

Thanks for sharing this–was able to take some bits and peaces from this in my own app and have it working in no time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment