When an image is added to the store, it will be put into the cache under a unique key, and the associated Item object will be given that key. When the DetailViewController wants an image from the store, it will ask its item for the key and search the cache for the image.
Add a property to Item.swift to store the key.
let dateCreated: Date let itemKey: String
The image keys need to be unique for your cache to work. While there are many ways to hack together a unique string, you are going to use the Cocoa Touch mechanism for creating universally unique identifiers (UUIDs), also known as globally unique identifiers (GUIDs). Objects of type NSUUID represent a UUID and are generated using the time, a counter, and a hardware identifier, which is usually the MAC address of the Wi-Fi card. When represented as a string, UUIDs look something like this:
4A73B5D2-A6F4-4B40-9F82-EA1E34C1DC04
In Item.swift, generate a UUID and set it as the itemKey.
init(name: String, serialNumber: String?, valueInDollars: Int) { self.name = name self.valueInDollars = valueInDollars self.serialNumber = serialNumber self.dateCreated = Date() self.itemKey = UUID().uuidString super.init() }
Then, in DetailViewController.swift, update imagePickerController(_:didFinishPickingMediaWithInfo:) to store the image in the ImageStore.
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) { // Get picked image from info dictionary let image = info[UIImagePickerControllerOriginalImage] as! UIImage // Store the image in the ImageStore for the item's key imageStore.setImage(image, forKey: item.itemKey) // Put that image on the screen in the image view imageView.image = image // Take image picker off the screen - // you must call this dismiss method dismiss(animated: true, completion: nil) }
Each time an image is captured, it will be added to the store. Both the ImageStore and the Item will know the key for the image, so both will be able to access it as needed (Figure 15.14).
Similarly, when an item is deleted, you need to delete its image from the image store. In ItemsViewController.swift, update tableView(_:commit:forRowAt:) to remove the item’s image from the image store.
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { // If the table view is asking to commit a delete command... if editingStyle == .delete { let item = itemStore.allItems[indexPath.row] let title = "Delete (item.name)?" let message = "Are you sure you want to delete this item?" let ac = UIAlertController(title: title, message: message, preferredStyle: .actionSheet) let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil) ac.addAction(cancelAction) let deleteAction = UIAlertAction(title: "Delete", style: .destructive, handler: { (action) -> Void in // Remove the item from the store self.itemStore.removeItem(item) // Remove the item's image from the image store self.imageStore.deleteImage(forKey: item.itemKey) // Also remove that row from the table view with an animation self.tableView.deleteRows(at: [indexPath], with: .automatic) }) ac.addAction(deleteAction) // Present the alert controller present(ac, animated: true, completion: nil) } }