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) | |
} | |
} | |
} |