Swift – How to save a list into UserDefaults

By | 22/06/2022

In this post, we will see how to save a list of objects into UserDefaults.

First of all, we create a new Swift project and we add a Struct called Person:

[PERSON.SWIFT]

import Foundation

// Identifiable is a protocol and means that our object can be 
// identified uniquely.
// Codable is a protocol and indicate whether an object can be 
// encoded into JSON data, or materialized from JSON data.
struct Person: Identifiable, Codable {
    let id = UUID()
    var Name: String
    var Surname: String
    var Age: Int
}



Then, we define a Class called People, used to save and load data from UserDefaults:

[PEOPLE.SWIFT]

import Foundation

class People: ObservableObject {
    @Published var lstPeople = [Person](){
        didSet{
            // every time value of lstPeople change, system will save new value
            // into UserDefaults
            let encoder = JSONEncoder()
            
            if let encoded = try? encoder.encode(lstPeople){
                UserDefaults.standard.set(encoded, forKey: "People")
            }
        }
    }
    
    init() {
        // everytime we create an instance of People, system will load the value
        // from UserDefaults
        if let savedPeople = UserDefaults.standard.data(forKey: "People"){
            if let decodedPeople = try? JSONDecoder().decode([Person].self, from: savedPeople){
                lstPeople = decodedPeople
                return
            }
        }
        lstPeople = []
    }
}



Now, we create a SwiftUI View file called AddPerson where we will define the form for adding a new person:

[ADDPERSON.SWIFT]

import SwiftUI

struct AddPerson: View {
    @ObservedObject var people: People
    // var used to dismiss the sheet
    @Environment(\.dismiss) var dismiss
    
    @State private var name = ""
    @State private var surname = ""
    @State private var age = 0
    
    var body: some View {
        NavigationView{
            Form{
                TextField("Name", text: $name)
                
                TextField("Surname", text: $surname)
                
                TextField("Age", value: $age, format: .number)
                    .keyboardType(.numberPad)
            }
                .navigationTitle("Add new Person")
                .toolbar{
                    Button("Save"){
                        let newPerson = Person(Name: name, Surname: surname, Age: age)
                        people.lstPeople.append(newPerson)
                        dismiss()
                    }
                }
        }
    }
}

struct AddPerson_Previews: PreviewProvider {
    static var previews: some View {
        AddPerson(people: People())
    }
}



Finally, we define the ContentView file:

[CONTENTVIEW.SWIFT]

struct ContentView: View {
    @StateObject var people = People()
    @State private var showAddnewPerson = false
    
    var body: some View {
        NavigationView{
            List{
                ForEach(people.lstPeople){item in
                    HStack{
                        VStack(alignment: .leading){
                            Text(item.Surname)
                                .font(.headline)
                            Text(item.Name)
                        }
                        Spacer()
                        Text(item.Age, format: .number)
                    }
                }
                .onDelete(perform: RemovePerson)
            }
            .navigationTitle("List People")
            .toolbar{
                Button{
                    showAddnewPerson = true
                }label: {
                    Image(systemName: "plus")
                }
            }
            .sheet(isPresented: $showAddnewPerson){
                AddPerson(people: people)
            }
        }
    }
    
    func RemovePerson(at offsets: IndexSet){
        people.lstPeople.remove(atOffsets: offsets)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}



We have done and now, if we run the application, this will be the result:



Leave a Reply

Your email address will not be published. Required fields are marked *