官术网_书友最值得收藏!

Loading and auto-saving the Shopping List

Now that we have the app working the way we want, there is one thing missing: the app doesn't save our Shopping List every time we make changes to our list. Also, we do not want to show the fake items. So let's see how we can persist the Shopping List and save it every time we make changes. For this we will need to:

  1. Switch to Item.swift and first import the core Foundation framework as we will be using UserDefaults , PropertyListEncoder, and PropertyListDecoder class objects to save our items. Add the following line to the top of the file:
import Foundation
  1. Have the Item class implement the Codable protocol, which will allow our item to be encoded and decoded to be stored in UserDefaults. UserDefaults is a quick and easy way to save user settings or data that is application-specific:
class Item: Codable {
  1. Add a new instance method called toggleCheck, which will return a new item with the same name, but with its isChecked value toggled. We will use this new item and update our item in the Table View Controller with this new item rather than mutating the item itself:
func toggleCheck() -> Item {
return Item(name: name, isChecked: !isChecked)
}
  1. Use extensions in Swift to extend the Array class to add a save method and a class level load method to save and load the items from UserDefaults:
extension Array where Element == Item {
func save() {
let data = try? PropertyListEncoder().encode(self)
UserDefaults.standard.set(data, forKey: String(describing:
Element.self))
UserDefaults.standard.synchronize()
}

static func load() -> [Element] {
if let data = UserDefaults.standard.value(forKey:
String(describing: Element.self)) as? Data,
let items = try? PropertyListDecoder().decode([Element].self,
from: data){
return items
}

return []
}
}
  1. Switch to the ItemTableViewController file and update the items instance variable that is defaulting to fake items, to actually load from UserDefaults. We can do so by updating it to this:
var items: [Item] = [Item].load() {
didSet {
items.save()
}
}
  1. In the preceding code block, we are setting items array to default to items loaded from the UserDefaults storage. This is done by calling [Item].load(). We also have a didSet block defined that gets called every time the items array is modified. We need to save the items to UserDefaults again when that happens by calling the save method on the items array.
  2. Update the tableView(_:didSelectRowAt:) method again and replace it with this and use the toggleCheck method that we just created instead to trigger the didSet method to automatically save our items:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
items[indexPath.row] = items[indexPath.row].toggleCheck()
tableView.reloadRows(at: [indexPath], with: .middle)
}

Let's run the app now and you should not see any items at first but if you add few items, check some items, close the app, and start it up again, you will see the items will load in the state they were before closing the app.

主站蜘蛛池模板: 安泽县| 鲜城| 宁蒗| 高淳县| 观塘区| 罗江县| 葫芦岛市| 资中县| 秦皇岛市| 县级市| 宜章县| 玉溪市| 边坝县| 扶风县| 福泉市| 双鸭山市| 贺州市| 巴塘县| 贵港市| 洪江市| 巴南区| 宁明县| 巴彦淖尔市| 龙川县| 东源县| 涟水县| 瑞昌市| 合肥市| 福泉市| 东山县| 且末县| 茂名市| 如东县| 山阳县| 新田县| 盖州市| 广汉市| 东台市| 荥经县| 海口市| 秦皇岛市|