Creating and Using Keys

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.

Listing 15.15  Adding a new property for a unique identifier (Item.swift)

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 UUID represent a UUID and are generated using the time, a counter, and a hardware identifier, which is usually the MAC address of the WiFi 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.

Listing 15.16  Generating a UUID (Item.swift)

init(name: String, serialNumber: String?, valueInDollars: Int) {
    self.name = name
    self.valueInDollars = valueInDollars
    self.serialNumber = serialNumber
    self.dateCreated = Date()
    self.itemKey = UUID().uuidString
}

Then, in DetailViewController.swift, update imagePickerController(_:didFinishPickingMediaWithInfo:) to store the image in the ImageStore.

Listing 15.17  Storing the image (DetailViewController.swift)

func imagePickerController(_ picker: UIImagePickerController,
        didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: 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. Notice that the images are saved immediately after being taken, while the instances of Item are saved only when the application enters the background. You save the images right away because they are too big to keep in memory for long.

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.9).

Figure 15.9  Accessing images from the cache

Accessing images from the cache

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.

Listing 15.18  Deleting the image from the ImageStore (ItemsViewController.swift)

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]

        // Remove the item from the store
        itemStore.removeItem(item)

        // Remove the item's image from the image store
        imageStore.deleteImage(forKey: item.itemKey)

        // Also remove that row from the table view with an animation
        tableView.deleteRows(at: [indexPath], with: .automatic)
    }
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.137.162.110