Sample code for Ch27 in Xcode 9.3


#1
//  ViewController.swift

import UIKit

class ViewController: UIViewController {
  @IBOutlet weak var itemTextField: UITextField!
  @IBOutlet weak var tableView: UITableView!

  var todoList = ToDoList()

  override func viewDidLoad() {
    super.viewDidLoad()

    todoList.loadItems()
    tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
    tableView.dataSource = self
  }

  @IBAction func addButtonTapped(_ sender: UIButton) {
    guard let todo = itemTextField.text, !todo.trimmingCharacters(in: .whitespaces).isEmpty else {
      return
    }
    todoList.add(todo)
    tableView.reloadData()
    itemTextField.text = ""
  }
}

// MARK: - UITableViewDataSource

extension ViewController: UITableViewDataSource {
  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return todoList.items.count
  }

  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
    let item = todoList.items[indexPath.row]
    cell.textLabel?.text = item
    return cell
  }

  func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == .delete {
      todoList.items.remove(at: indexPath.row)
      tableView.deleteRows(at: [indexPath], with: .fade)
    }
  }
}
//  ToDoList.swift

import UIKit

struct ToDoList {
  var items = [String]()

  mutating func add(_ item: String) {
    items.append(item)
  }

  mutating func remove(at index: Int) {
    items.remove(at: index)
  }

  let archiveURL: URL = {
    let documentFolderURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
    return documentFolderURL.appendingPathComponent("todolist").appendingPathExtension("plist")
  }()

  func saveItems() {
    print("Saving items to \(archiveURL)")
    let propertyListEncoder = PropertyListEncoder()
    let data = try? propertyListEncoder.encode(items)
    do {
      try data?.write(to: archiveURL, options: .noFileProtection)
    } catch {
      print("Could not save to-do list")
    }
  }

  mutating func loadItems() {
    print("Loading items from \(archiveURL)")
    guard let data = try? Data(contentsOf: archiveURL) else {
      print("Could not load to-do list")
      return
    }
    let propertyListDecoder = PropertyListDecoder()
    items = (try? propertyListDecoder.decode([String].self, from: data)) ?? []
  }
}
//  AppDelegate.swift

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
...
  func applicationDidEnterBackground(_ application: UIApplication) {
    guard let viewController = window?.rootViewController as? ViewController else { return }
    viewController.todoList.saveItems()
  }
}

#2

What is the full implementation for AppDelegate.swift?


#3
//  AppDelegate.swift

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

  var window: UIWindow?

  func applicationDidEnterBackground(_ application: UIApplication) {
    guard let viewController = window?.rootViewController as? Ch27iTahDoodleViewController else { return }
    viewController.todoList.saveItems()
  }
}