3. For a tougher challenge, take the image generation code out of cellForRowAt: generate all images when the app first launches, and use those smaller versions instead. For bonus points, combine the getDocumentsDirectory() method I introduced in project 10 so that you save the resulting cache to make sure it never happens again.
As a reminder, here’s the code for getDocumentsDirectory():
func getDocumentsDirectory() -> URL {
    let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
    return paths[0]
}
}
The above is from Day 98 of Paul Hudson's excellent course: 100 Days of Swift. It is Challenge #3 and there is even a "bonus" challenge inside the challenge! In approaching the solution--before coding--I wrote down my thoughts and then gathered snippets of code that I thought would help. My notes are below. I thought it might be helpful for others to share them without giving away the solution.
- Read big images from bundle, see project 1.
- Render a image into a rect using CoreGraphics like in project 30.
- Read the thumbnails in like project 10.
- If a thumbnail does not exist then create it. Also like in project 10.
Next, I gathered the corresponding snippets of the code:
From project 1:
DispatchQueue.global(qos: .userInitiated).async { [weak self] in
    let fm = FileManager.default
    let path = Bundle.main.resourcePath!
    let items = try! fm.contentsOfDirectory(atPath: path)
    let pictureNames = items
        .filter { $0.hasPrefix("nssl") }
        .sorted { $0 < $1 }
    self?.storms = pictureNames.map {
        Storm(name: $0, imageName: $0) }
    DispatchQueue.main.async { [weak self] in
        self?.collectionView.reloadData()
    }
}
From project 30:
        let path = Bundle.main.path(forResource: imageRootName, ofType: nil)!
        let original = UIImage(contentsOfFile: path)!
        let renderRect = CGRect(origin: .zero, size: CGSize(width: 90, height: 90))
        let renderer = UIGraphicsImageRenderer(size: renderRect.size)
        let rounded = renderer.image { ctx in
            ctx.cgContext.addEllipse(in: renderRect)
            ctx.cgContext.clip()
            original.draw(in: renderRect)
        }
From project 10:
 Write:
        let imageName = UUID().uuidString
        let imagePath = getDocumentsDirectory().appendingPathComponent(imageName)
        if let jpegData = image.jpegData(compressionQuality: 0.8) {
            try? jpegData.write(to: imagePath)
        }
 Read:
        let path = getDocumentsDirectory().appendingPathComponent(person.imageName)
        cell.imageView.image = UIImage(contentsOfFile: path.path)
 
 
Nice.
ReplyDeleteOnline training