ios – Saving Checked / Unchecked Duties to UserDefaults


How one can save “Checked / Unchecked Duties” to persist knowledge with UserDefaults?

In my ListViewModel, I am making an attempt to avoid wasting the checkmarks Bool isCompleted state to UserDefaults. While you relaunch the App, the checkmarks reset to false.

Undecided if I want so as to add an EnvironmentObject or ObservableObject to the ListView

ListViewModel.swift

//
//  ListViewModel.swift
//

import Basis

class ListViewModel: ObservableObject {
    
    @Printed var objects: [ItemModel] = [] {
        didSet {
            saveItems()
        }
    }
    
    let itemsKey: String = "task_items_list"
    
    init() {
        myTaskItems()
    }
    
    func myTaskItems() {
        let taskItems = [
            ItemModel(title: "This is the first task!", isCompleted: false),
            ItemModel(title: "This is the second task!", isCompleted: false),
            ItemModel(title: "This is the third task!", isCompleted: false),
            ItemModel(title: "This is the fourth task!", isCompleted: false),
            ItemModel(title: "This is the fifth task!", isCompleted: false)
        ]
        objects.append(contentsOf: taskItems)
        
        guard
            let knowledge = UserDefaults.customary.knowledge(forKey: itemsKey),
            let savedTaskItems = attempt? JSONDecoder().decode([ItemModel].self, from: knowledge)
        else { return }
        
        self.objects = savedTaskItems
    }
    // Replace TaskdItems Toggle
    func updateItem(merchandise:ItemModel) {
        if let index = objects.firstIndex(the place: { $0.id == merchandise.id }) {
            objects[index] = merchandise.updateCompletion()
        }
    }
    // Save to UserDefaults
    func saveItems() {
        if let encodedData = attempt? JSONEncoder().encode(objects) {
            UserDefaults.customary.set(encodedData, forKey: itemsKey)
        }
    }
}


ItemModel.swift

//  ItemModel.swift
//

import Basis

struct ItemModel:Identifiable, Codable {
    let id: String
    let title: String
    let isCompleted: Bool
    
    init(id: String = UUID().uuidString, title: String, isCompleted: Bool) {
        self.id = UUID().uuidString
        self.title = title
        self.isCompleted = isCompleted
    }
    
    func updateCompletion() -> ItemModel {
        return ItemModel(id: id, title: title, isCompleted: !isCompleted)
    }
    
}

ListView.swift

//
//  ListView.swift
//

import SwiftUI

struct ListView: View {
    
    @EnvironmentObject var listViewModel: ListViewModel
    
    var physique: some View {
        Record {
            ForEach(listViewModel.objects) { merchandise in
                ListRowView(merchandise: merchandise)
                    .onTapGesture {
                        listViewModel.updateItem(merchandise: merchandise)
                    }
            }
        }
        .listStyle(PlainListStyle())
        .navigationTitle("My Process Record")
    }
    
    
    struct ListView_Previews: PreviewProvider {
        static var previews: some View {
            NavigationView {
                ListView()
            }
            .environmentObject(ListViewModel())
        }
    }
    
}

ListRowView.swift

//
//  ListRowView.swift
//

import SwiftUI

struct ListRowView: View {
    
    let merchandise: ItemModel
    
    var physique: some View {
        HStack {
            Picture(systemName: merchandise.isCompleted ? "checkmark.circle" : "circle")
                .foregroundColor(merchandise.isCompleted ? .inexperienced : .grey)
            Textual content(merchandise.title)
            Spacer()
        }
        .font(.title2)
        .padding(.vertical, 8)
    }
}

struct ListRowView_Previews: PreviewProvider {
    
    static var item1 = ItemModel(title: "First merchandise!", isCompleted: false)
    static var item2 = ItemModel(title: "Second merchandise!", isCompleted: true)
    
    static var previews: some View {
        
        Group {
            ListRowView(merchandise: item1)
            ListRowView(merchandise: item2)
        }
        .previewLayout(.sizeThatFits)
    }
}

TaskListApp.swift

//
//  TaskListApp.swift
//

import SwiftUI

@principal
struct TaskListApp: App {

    @StateObject var listViewModel: ListViewModel = ListViewModel()

    var physique: some Scene {
        WindowGroup {
            NavigationView {
                ListView()
            }
            .environmentObject(listViewModel)
        }
    }
}

ScreenShot of My Task List

Leave a Reply