Created
January 28, 2024 06:09
-
-
Save theoknock/4b85498d7ac19bfb4a05760cd9803b90 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.