Лучший подход к использованию UserDefaults - PullRequest
0 голосов
/ 21 февраля 2020

Я только начал изучать swift, решил создать первое приложение todo, и у меня возник вопрос. Необходимо сохранять все данные при любых действиях пользователя: создании, изменении или удалении задачи. Вызов метода для сохранения данных каждый раз - плохой подход. Что вы можете порекомендовать?

func addItem(itemName: String, isCompleted: Bool = false) {
   tasks.append(Tasks(taskName: itemName, isCompleted: isCompleted))
   saveData()
}

Я храню задачи в структуре. Перед использованием структуры я использовал вычисляемое свойство следующим образом:

var ToDoItems: [[String: Any]] {
   set {
     UserDefaults.standard.set(newValue, forKey: "ToDoDataKey")
     UserDefaults.standard.synchronize()
   }

   get {
     if let userData = UserDefaults.standard.array(forKey: "ToDoDataKey") as? 
 [[String: Any]] {
       return userData
   } else {
     return []
   }
 }
}

Ответы [ 2 ]

2 голосов
/ 21 февраля 2020

Нет необходимости нажимать на диск каждый раз, когда изменяется массив задач. Обычно нужно зарегистрироваться для уведомления UIApplication , в котором говорится, что ваше приложение собирается деактивироваться, и сохранить его там по умолчанию.

Вам нужно получить данные по умолчанию только на viewDidLoad Как вам уже сказали.

(В iOS 13 с поддержкой нескольких окон все немного сложнее; см. В iOS 13, когда сохранять данные? .)

1 голос
/ 21 февраля 2020

В didSet из tasks array вы можете просто установить текущие элементы массива в UserDefaults.

struct Task: Codable {
    let taskName: String
    let isCompleted: Bool
}

var tasks = [Task]() {
    didSet {
        let data = try? JSONEncoder().encode(tasks)
        UserDefaults.standard.set(data, forKey: "ToDoDataKey")
    }
}

func addItem(itemName: String, isCompleted: Bool = false) {
    tasks.append(Task(taskName: itemName, isCompleted: isCompleted))
}

Это обеспечит, что данные в UserDefaults синхронизируется с текущим в памяти.

И извлекает данные только в viewDidLoad(), где данные будут загружены в первый раз.

func fetchTasks() -> [Task] {
    if let data = UserDefaults.standard.data(forKey: "ToDoDataKey"), let tasks = try? JSONDecoder().decode([Task].self, from: data) {
        return tasks
    }
    return []
}

Вызов fetchTasks() в viewDidLoad().

...