Skip to content

Instantly share code, notes, and snippets.

@enomoto
Created November 28, 2021 05:48
Show Gist options
  • Select an option

  • Save enomoto/9eab81e1931ae1c5295e7e0245092548 to your computer and use it in GitHub Desktop.

Select an option

Save enomoto/9eab81e1931ae1c5295e7e0245092548 to your computer and use it in GitHub Desktop.
simple image cache for iOS
import UIKit
struct ImageCache {
static func loadImage(url: URL, user: User) async throws -> (UIImage, User) {
if let cachedImage = InMemoryImageCache.shared.get(forKey: url) {
return (cachedImage, user)
}
let urlRequest = URLRequest(url: url)
let (data, response) = try await URLSession.shared.data(for: urlRequest)
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {
throw ImageAPIError.unexpected
}
if let image = UIImage(data: data) {
InMemoryImageCache.shared.set(image, forKey: url)
return (image, user)
} else {
throw ImageAPIError.unexpected
}
}
private struct InMemoryImageCache {
static let shared = InMemoryImageCache()
private let cache = NSCache<NSURL, UIImage>()
private init() {}
func set(_ image: UIImage, forKey url: URL) {
cache.setObject(image, forKey: url as NSURL)
}
func get(forKey url: URL) -> UIImage? {
return cache.object(forKey: url as NSURL)
}
}
}
enum ImageAPIError: Error, LocalizedError {
case unexpected
var errorDescription: String? {
"something happened."
}
}
final class User: Decodable, Hashable {
let id: Int64
let login: String
let avatarURL: URL?
let uuid = UUID()
var image: UIImage = UIImage(named: "placeholder")!
enum CodingKeys: String, CodingKey {
case id
case login
case avatarURL = "avatar_url"
}
public func hash(into hasher: inout Hasher) {
hasher.combine(uuid)
}
static func == (lhs: User, rhs: User) -> Bool {
lhs.uuid == rhs.uuid
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment