I am loading in a json file and creating an array. When a button is clicked, additional data is inserted into the array. What I want to do is export the modified array to a file. So essentially the array that has new data inserted into it.
What I'm not sure about is whether it is possible when exporting data from an array? or maybe I am going about this the wrong way?
EDIT: I don't necessarily want to export a json file, that was just the file type I first tried. I would be happy to export text files or csv's
ContentView
import SwiftUI
import UniformTypeIdentifiers
struct ContentView: View {
@State private var name = ""
@FocusState private var nameIsFocused: Bool
@State var labels: [LabelData] = []
@State var index = 0
@State var saveFile = false
var body: some View {
HStack {
Button(action: {
index += 1
if index <= labels.count {
labels[index - 1]._label = "Yellow" }
}) {
Text("Y")
}
Button(action: {
saveFile.toggle()
//print(labels[index - 1])
}) {
Text("Export")
.frame(width: 100, height: 100)
.foregroundColor(Color(red: 0.362, green: 0.564, blue: 1))
.background(Color(red: 0.849, green: 0.849, blue: 0.849))
.clipShape(RoundedRectangle(cornerRadius: 25.0, style: .continuous))
}
.offset(x: 0, y: 0)
.fileExporter(isPresented: $saveFile, document: Doc(url: Bundle.main.path(forResource: "labeldata", ofType: "json")!), contentType: .json) { (res) in
do {
let fileUrl = try res.get()
print(fileUrl)
}
catch {
print("cannot save doc")
print(error.localizedDescription)
}
}
}
VStack{
VStack {
if index < labels.count{
if let test = labels[index] {
Text(test._name)
}}}
.offset(x: 0, y: -250)
.frame(
minWidth: 0,
maxWidth: 325
)
VStack {
if index < labels.count{
if let test = labels[index] {
Text(test._name)
}}}
.offset(x: 0, y: -150)
.frame(
minWidth: 0,
maxWidth: 325
)
VStack {
if index < labels.count{
if let test = labels[index] {
Text(test._label)
}}}
.offset(x: 0, y: -50)
.frame(
minWidth: 0,
maxWidth: 325
)
}
.onAppear {
labels = load("labeldata.json")
}
}
}
struct Doc : FileDocument {
var url : String
static var readableContentTypes: [UTType]{[.json]}
init(url : String) {
self.url = url
}
init(configuration: ReadConfiguration) throws {
url = ""
}
func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {
let file = try! FileWrapper(url: URL(fileURLWithPath: url), options: .immediate)
return file
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
LabelData
import Foundation
struct LabelData: Codable {
var _id: Int
var _name: String
var _type: String
var _description: String
var _label: String
}
labeldata.json
[
{
"_id" : 1,
"_name" : "Label1",
"_type" : "type1",
"_description" : "description1",
"_label" : ""
},
{
"_id" : 2,
"_name" : "Label2",
"_type" : "type2",
"_description" : "description2",
"_label" : ""
}
]
DataLoader
import Foundation
func load<T: Decodable>(_ filename: String) -> T {
let data: Data
guard let file = Bundle.main.url(forResource: filename, withExtension: nil)
else {
fatalError("Couldn't find \(filename) in main bundle.")
}
do {
data = try Data(contentsOf: file)
} catch {
fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
}
do {
let decoder = JSONDecoder()
return try decoder.decode(T.self, from: data)
} catch {
fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")
}
}