I have previous coding experience but I'm extremely new to both Swift and iOS. I'm developing an app for personal use to coalesce the functions of multiple different apps I use to help manage ADHD into one place. The main view of the app provides a way to track daily expenditures. I'm trying to use UserDefaults to store the information entered so it will still be there when I reopen the app. The app runs fine, and as near as I can figure out I've written the data handling right, but it simply doesn't work. I've been beating my head against the wall at this for the past few days including on this website, so any help would be greatly appreciated. Here's the code for the main view of the app:
import SwiftUIFontIcon
import SwiftUI
//import UIKit
struct ContentView: View {
@State public var purchases = [Purchases]()
@State public var prices = [Price]()
@State public var isActive = false
@State public var goTo: String = ""
@State public var purchase: String = ""
@State public var price: String = ""
// @State public var isActive: Bool = false
init(){
if let data = UserDefaults.standard.data(forKey: "Purchases"){
if let decoded = try? JSONDecoder().decode([Purchases].self, from: data){
self.purchases = decoded
}
return
}
self.purchases = []
if let data2 = UserDefaults.standard.data(forKey: "Bread"){
if let decoded2 = try? JSONDecoder().decode([Price].self, from: data2){
self.prices = decoded2
}
return
}
self.prices = []
}
func addItem(){
saveStuff()
self.purchases.append(Purchases(name: purchase))
saveStuff()
purchase = ""
}
func addPrice(){
saveBread()
self.prices.append(Price(name: price))
saveBread()
price = ""
}
func deleteItem(at offsets: IndexSet){
purchases.remove(atOffsets: offsets)
}
func deletePrice(at offsets: IndexSet){
prices.remove(atOffsets: offsets)
}
func saveStuff(){
if let encodedData = try? JSONEncoder().encode(purchases){
UserDefaults.standard.set(encodedData, forKey: "Purchases")
}
// return
}
func saveBread(){
if let encodedData = try? JSONEncoder().encode(prices){
UserDefaults.standard.set(encodedData, forKey: "Bread")
}
// return
}
func clearList(){
self.prices.removeAll()
self.purchases.removeAll()
}
var body: some View {
NavigationView{
ZStack {
Color.gray
.edgesIgnoringSafeArea(/*@START_MENU_TOKEN@*/.all/*@END_MENU_TOKEN@*/)
VStack {
// Spacer()
// HStack {
// // Spacer()
// NavigationLink(
// destination: ToDoList(rootIsActive: self.$isActive),
// isActive: self.$isActive
//
// ){
// FontIcon.text(.ionicon(code: .ios_list_box), fontsize: 48, color: .black)
// }
// Spacer()
// NavigationLink(destination: ReminderView()){
// FontIcon.text(.ionicon(code: .ios_warning), fontsize: 48, color: .black)
// }
// // Spacer()
// }
Spacer()
VStack{
Spacer()
HStack {
Spacer()
HStack {
Spacer()
TextField("Add an Item", text: $purchase)
.padding(12)
.border(Color.black)
Spacer()
Spacer()
Spacer()
TextField("Add a Price", text: $price)
.padding(12)
.border(Color.black)
// Spacer()
FontIcon.button(.ionicon(code: .ios_add_circle), action: {
addItem()
addPrice()
saveStuff()
saveBread()
}, padding: 12, fontsize: 45, color: .black)
}
.opacity(1)
.padding(12)
// .border(Color.black)
// Spacer()
}
Spacer()
VStack {
HStack {
Spacer()
List{
ForEach(purchases){ purchase in
Text(purchase.name)
.cornerRadius(16)
.padding(10)
}
.onDelete(perform: deleteItem)
// .listStyle(GroupedListStyle())
}
Spacer()
List{
ForEach(prices){ price in
Text(price.name)
.cornerRadius(16)
.padding(10)
}
.onDelete(perform: deletePrice)
// .onAppear{UITableView.appearance().separatorColor = .clear}
}
Spacer()
}
Spacer()
HStack {
// Spacer()
// FontIcon.button(.ionicon(code: .ios_save), action: {
// saveStuff()
// saveBread()
// }, padding: 12, fontsize: 78, color: .green)
Spacer()
FontIcon.button(.ionicon(code: .ios_trash),action:{
clearList()
}, padding: 12, fontsize: 78, color: .red)
Spacer()
NavigationLink(destination: ViewLists()){
FontIcon.text(.ionicon(code: .ios_filing), fontsize: 58, color: .black)
}
Spacer()
NavigationLink(destination: ViewTotals()){
FontIcon.text(.ionicon(code: .ios_add), fontsize: 58, color: .black)
}
Spacer()
NavigationLink(destination: IncomeView()){
FontIcon.text(.ionicon(code: .ios_musical_note), fontsize: 58, color: .black)
}
Spacer()
}
// Spacer()
}
Spacer()
}
Spacer()
}
.navigationBarTitle("ADD ToolKit", displayMode: .large)
Spacer()
// .navigationBarTitle("Ledger", displayMode: .large)
// Spacer()
}
.toolbar{
ToolbarItem(placement: .primaryAction){
// Spacer()
// Spacer()
HStack {
Spacer()
NavigationLink(destination: ReminderView()){
FontIcon.text(.ionicon(code: .ios_warning), fontsize: 48, color: .black)
// Spacer()
}
}
}
ToolbarItem(placement: .navigationBarLeading){
HStack {
Spacer()
NavigationLink(
destination: ToDoList(rootIsActive: self.$isActive),
isActive: self.$isActive
){
FontIcon.text(.ionicon(code: .ios_list_box), fontsize: 48, color: .black)
}
}
}
}
//
}
.background(
NavigationLink(destination: Text(self.goTo), isActive: $isActive){
EmptyView()
})
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
and the code for the model where I define all the array structs:
import Foundation
import SwiftUI
struct Purchases: Identifiable, Codable{
let id: String
let name: String
init(id: String = UUID().uuidString, name: String){
self.id = id
self.name = name
}
}
struct Price: Identifiable, Codable{
let id: String
let name: String
init(id: String = UUID().uuidString, name: String){
self.id = id
self.name = name
}
}
struct ToDo: Identifiable, Codable{
let id: String
let name: String
init(id: String = UUID().uuidString, name: String){
self.id = id
self.name = name
}
}
struct Reminder: Identifiable, Codable{
let id: String
let name: String
init(id: String = UUID().uuidString, name: String){
self.id = id
self.name = name
}
}
struct Income: Identifiable, Codable{
let id: String
let name: String
init(id: String = UUID().uuidString, name: String){
self.id = id
self.name = name
}
}
Thanks in advance