Get a random cat image:
Cats.getRandomImageURL { url in
}Set a random cat image on UIImageView:
imageView.setRandomCatImage()| enum Cats { | |
| private struct CatResponse: Decodable { | |
| let url: URL | |
| } | |
| @discardableResult | |
| static func getRandomImageURL(completion: @escaping (URL?) -> Void) -> URLSessionDataTask { | |
| let request = URLRequest(url: URL(string: "https://api.thecatapi.com/v1/images/search")!) | |
| let task = URLSession.shared.dataTask(with: request) { data, _, _ in | |
| let catURL: URL? = { | |
| guard let data = data, | |
| let cats = try? JSONDecoder().decode([CatResponse].self, from: data), | |
| let firstCat = cats.first | |
| else { return nil } | |
| return firstCat.url | |
| }() | |
| DispatchQueue.main.async { | |
| completion(catURL) | |
| } | |
| } | |
| task.resume() | |
| return task | |
| } | |
| @discardableResult | |
| static func image(url: URL, completion: @escaping (UIImage?) -> Void) -> URLSessionDataTask { | |
| let task = URLSession.shared.dataTask(with: url) { data, _, _ in | |
| let image: UIImage? = { | |
| guard let data = data else { return nil } | |
| return UIImage(data: data) | |
| }() | |
| DispatchQueue.main.async { | |
| completion(image) | |
| } | |
| } | |
| task.resume() | |
| return task | |
| } | |
| } |
| extension UIImageView { | |
| func setRandomCatImage(placeholder: UIImage? = nil, emptyImage: UIImage? = nil) { | |
| activeCatRequest?.cancel() | |
| image = placeholder | |
| activeCatRequest = Cats.getRandomImageURL { [weak self] url in | |
| switch url { | |
| case let .some(url): | |
| self?.setCatImage(url: url, emptyImage: emptyImage) | |
| case .none: | |
| self?.image = emptyImage | |
| } | |
| } | |
| } | |
| private func setCatImage(url: URL, emptyImage: UIImage?) { | |
| activeCatRequest = Cats.image(url: url) { [weak self] image in | |
| switch image { | |
| case let .some(image): | |
| self?.image = image | |
| case .none: | |
| self?.image = emptyImage | |
| } | |
| } | |
| } | |
| } | |
| private extension UIImageView { | |
| struct AssociatedKeys { | |
| static var activeCatRequest = "ActiveCatRequest" | |
| } | |
| var activeCatRequest: URLSessionDataTask? { | |
| get { | |
| objc_getAssociatedObject(self, &AssociatedKeys.activeCatRequest) as? URLSessionDataTask | |
| } | |
| set { | |
| objc_setAssociatedObject(self, &AssociatedKeys.activeCatRequest, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) | |
| } | |
| } | |
| } |