我需要将每个口袋妖怪图像添加到我的CollectionView中,但无法弄清楚该怎么做。
我的结构如下:
struct Pokemon: Codable {
var results: [Species]?
var abilities: [Ability]?
var height, weight: Int?
var imageURL: String?
var image: Data?
var description: String?
var evolutionChain: [EvolutionChain]?
var id, attack, defense: Int?
var name, type: String?
var sprites: Sprites?
var stats: [Stat]?
init(id: Int, dictionary: [String: AnyObject]) {
self.id = id
if let name = dictionary["name"] as? String {
self.name = name
}
if let imageUrl = dictionary["imageUrl"] as? String {
self.imageURL = imageUrl
}
if let description = dictionary["description"] as? String {
self.description = description
}
if let weight = dictionary["weight"] as? Int {
self.weight = weight
}
if let height = dictionary["height"] as? Int {
self.height = height
}
if let defense = dictionary["defense"] as? Int {
self.defense = defense
}
if let attack = dictionary["attack"] as? Int {
self.attack = attack
}
if let type = dictionary["type"] as? String {
self.type = type.capitalized
}
}
}
我的API调用如下:
func getOtherPokes(handler: @escaping ([Pokemon]) -> Void) {
var pokemonArray = [Pokemon]()
var myImage = UIImage()
AF.request(secondAPI).responseJSON { (response) in
do {
guard let pokeFetched = response.value as? [AnyObject] else { return }
print("You have \(pokeFetched.count) pokemon listed by now.")
// Get all the elements of the pokemon objects
for (key, result) in pokeFetched.enumerated() {
if let dictionary = result as? [String: AnyObject] {
var pokemon = Pokemon(id: key, dictionary: dictionary)
guard let imageURL = pokemon.imageURL else { return }
self.fetchImages(withUrl: imageURL) { (img) in
var mysImage = pokemon.image
mysImage = img.pngData()
print(mysImage)
pokemonArray.append(pokemon)
pokemonArray.sort { (poke1, poke2) -> Bool in
return poke1.id! < poke2.id!
}
handler(pokemonArray)
}
}
}
} catch {
print("There was an error: \(error)")
}
}.resume()
}
PD:我不能将图像设置为UIImage类型,因为Pokemon结构符合Codable。
我不知道如何获取该图像并将其获取到我的CollectionViewcontroller。有帮助吗?
答案 0 :(得分:0)
我假设您的函数getOtherPokes正在运行,因此您可以在视图控制器上执行一系列口袋妖怪的操作,并在cellForItem函数上获取图像。
enum ServiceError: Error{
case emptyData
case connectionError
case apiError
var localizedDescription: String{
switch self {
case .apiError:
return "Something went wrong."
case .emptyData:
return "Nothing was found, try again or change the filters."
case .connectionError:
return "Your phone is not connected, conecte it and try again."
}
}
}
//Your ImageTask Service
class ImageTask {
private static let imageCache = NSCache<NSString, UIImage>()
static func fetchImages(withUrl urlString: String, handler: @escaping (Result<UIImage, Error>) -> Void) {
// Get a url as a parameter, so I can use it on fetchPokes
guard let url = URL(string: urlString) else { return }
//Verify if the image is already on cache
if let imageCached = ImageTask.imageCache.object(forKey: url.absoluteString as NSString){
handler(.success(imageCached))
return nil
}
AF.request(url).response { (response) in
if let error = response.error {
handler(.failure(ServiceError.apiError))
print("There was an error downloading the image. Check it out: \n \(error)")
return
}
guard let data = response.data, let image = UIImage(data: data) else {
handler(.failure(ServiceError.emptyData))
return
}
//Save image on cache
ImageTask.imageCache.setObject(image, forKey: url.absoluteString as NSString)
handler(.success(image))
}.resume()
}
/// method to get image from cache
static func getImageOnCache(by url: String) -> UIImage?{
if let imageCached = ImageTask.imageCache.object(forKey: url as NSString){
return imageCached
}
return nil
}
static func cleanCache(){
ImageAPI.imageCache.removeAllObjects()
}
}
class YourViewController: UIViewController,UICollectionViewDataSource{
var pokemons: [Pokemon] = [Pokemon]()
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
return confiCell(index: indexPath)
}
private func confiCell(index: IndexPath)->UICollectionViewCell{
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "YourIdentifier", for: index) as? YourCell else {
return UICollectionViewCell()
}
if let url = pokemons[index.row].imageURL{
//Verify if image already exist on cache
if let imageDownloaded = ImageTask.getImageOnCache(by: url){
cell.populate(with: imageDownloaded)
}else{
ImageTask.fetchImages(withUrl: url){ result in
let image = try? result.get()
DispatchQueue.main.async {
if let img = image{
cell.populate(with: img)
}else{
// treat in case of error
}
}
}
}
}
return cell
}
}