article

Tuesday, May 4, 2021

Todo app SwiftUI iOS and UserDefaults database

Todo app SwiftUI iOS and UserDefaults database
 
//
//  ContentView.swift
//  todos
//
//  Created by Cairocoders
//

import SwiftUI

struct ContentView: View { //User Interface
    
    @State private var newTodo = ""
    @State private var allTodos: [TodoItem] = []
    private let todosKey = "todosKey"
    
    var body: some View {
      NavigationView {
        VStack { //vertical stack
            
            HStack { //Horizontal Stack
            TextField("Add todo...", text: $newTodo)
              .textFieldStyle(RoundedBorderTextFieldStyle())
            
            Button(action: {
              guard !self.newTodo.isEmpty else { return }
              self.allTodos.append(TodoItem(todo: self.newTodo))
              self.newTodo = ""
              self.saveTodos()
            }) {
                Image(systemName: "plus")
            }
            .padding(.leading, 5)
          }.padding() //end horizontal stack

          List { //List view to display all of the to-dos in our allTodos
            ForEach(allTodos) { todoItem in
              Text(todoItem.todo)
            }.onDelete(perform: deleteTodo)
          }
            
        }//end vertical stack
        .navigationBarTitle("Todos")
      }.onAppear(perform: loadTodos)
    }
    
    //Storing To-dos in UserDefaults
    //UserDefaults is a database where you store key-value
    //https://developer.apple.com/documentation/foundation/userdefaults
    
    private func saveTodos() {
      UserDefaults.standard.set(try? PropertyListEncoder().encode(self.allTodos), forKey: todosKey)
    }
    
    private func loadTodos() {
      if let todosData = UserDefaults.standard.value(forKey: todosKey) as? Data {
        if let todosList = try? PropertyListDecoder().decode(Array<TodoItem>.self, from: todosData) {
          self.allTodos = todosList
        }
      }
    }
    
    private func deleteTodo(at offsets: IndexSet) {
      self.allTodos.remove(atOffsets: offsets)
      saveTodos()
    }
    
}

//Add codable to make Sure each item encoded and decoded
struct TodoItem: Codable, Identifiable { //Identifiable protocol this ensures that the system can distinguish one TodoItem from another
    var id = UUID()
  let todo: String
}

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

Related Post