Работа с api. Создания приложения на основе collection view

swift

#1

Проблема в следующем я спарсил json с api сайта (https://pixabay.com) с картинками(пытаюсь сделать приложение по примеру )
Суть такая есть модель

import Foundation

struct CurrentImageData: Codable {
    let hits: [Hits]
}

struct Hits: Codable {
    let id: String
    let pageURL: String
    let type: String
    let tags: String
    let previewURL: String
    let previewWidth: String
    let previewHeight: String
    let webformatURL: String
    let webformatWidth: String
    let webformatHeight: String
    let largeImageURL: String
    let imageWidth: String
    let imageHeight: String
    let imageSize: String
    let views: String
    let downloads: String
    let collections: String
    let likes: String
    let user: String
    let userImageURL: String
}

тут я для ячейки коллекции сделал модель для придачи в нее информации в будем (преобразую ссылку в картинку и предам )

        import Foundation

struct CurrrenImage {
    let image: String
    
    init?(currentImageData: CurrentImageData) {
        self.image = currentImageData.hits.first!.userImageURL
    }
}

Вот тут написана логика парсера и нам как раз таки вся проблема и заключается(проблему напишу в коде после //)

 struct NetworkImageManager {
    func fetchCurrentImage() {
        let urlString = "https://pixabay.com/api/?key=\(key)&q&image_type=photo"
        guard let url = URL(string: urlString) else {return}
        let urlSession = URLSession(configuration: .default)
        let task = urlSession.dataTask(with: url) { data, responce, error in
            if let data = data {
                let currentImage = self.parseJSON(withData: data)
            }

        }
        task.resume()
    }

    func parseJSON(withData data: Data) -> CurrrenImage {
        let decoder = JSONDecoder()
        do {
            let currentImageData = try decoder.decode(CurrentImageData.self, from: data)
            guard let currentImage = CurrrenImage(currentImageData: CurrentImageData) else{return nil} //'nil' is incompatible with return type 'CurrrenImage'
             // Cannot convert value of type 'CurrentImageData.Type' to expected 
                //argument type 'CurrentImageData'
            return currentImage
        } catch let error as NSError {
            print(error.localizedDescription)
        }
        return nil

    }

}

Вот так выглядит json прогнанный через quicktype.io

 import Foundation

// MARK: - Image
struct Image: Codable {
    let total, totalHits: Int
    let hits: [Hit]
}

// MARK: - Hit
struct Hit: Codable {
    let id: Int
    let pageURL: String
    let type: TypeEnum
    let tags: String
    let previewURL: String
    let previewWidth, previewHeight: Int
    let webformatURL: String
    let webformatWidth, webformatHeight: Int
    let largeImageURL: String
    let imageWidth, imageHeight, imageSize, views: Int
    let downloads, collections, likes, comments: Int
    let userID: Int
    let user: String
    let userImageURL: String

    enum CodingKeys: String, CodingKey {
        case id, pageURL, type, tags, previewURL, previewWidth, previewHeight, webformatURL, webformatWidth, webformatHeight, largeImageURL, imageWidth, imageHeight, imageSize, views, downloads, collections, likes, comments
        case userID = "user_id"
        case user, userImageURL
    }
}

enum TypeEnum: String, Codable {
    case photo = "photo"
}

#2

Проверил:

Вот где ошибка

 guard let currentImage = CurrrenImage(currentImageData: CurrentImageData) else{return nil}

Заменить на:

 guard let currentImage = CurrrenImage(currentImageData: currentImageData) else{return nil}

Принты подставил

    func fetchCurrentImage() {
    let key = "Секретный ключ"
       let urlString = "https://pixabay.com/api/?key=\(key)&q&image_type=photo"
       guard let url = URL(string: urlString) else {return}
       let urlSession = URLSession(configuration: .default)
       let task = urlSession.dataTask(with: url) { data, responce, error in
           if let data = data {
               let currentImage = self.parseJSON(withData: data)
            print(currentImage?.image) // Optional("https://cdn.pixabay.com/user/2021/03/26/06-18-19-299_250x250.jpg")
           }

       }
       task.resume()
   }

   func parseJSON(withData data: Data) -> CurrrenImage? {
       let decoder = JSONDecoder()
       do {
           let currentImageData = try decoder.decode(Images.self, from: data)
           guard let currentImage = CurrrenImage(currentImageData: currentImageData) else{return nil}
        print(currentImage.image) // https://cdn.pixabay.com/user/2021/03/26/06-18-19-299_250x250.jpg
           return currentImage
       } catch let error as NSError {
           print(error.localizedDescription)
       }
       return nil
   }
}

import Foundation

// MARK: - Images
struct Images: Codable {
let total, totalHits: Int
let hits: [Hit]
}

// MARK: - Hit
struct Hit: Codable {
let id: Int
let pageURL: String
let type: TypeEnum
let tags: String
let previewURL: String
let previewWidth, previewHeight: Int
let webformatURL: String
let webformatWidth, webformatHeight: Int
let largeImageURL: String
let imageWidth, imageHeight, imageSize, views: Int
let downloads, collections, likes, comments: Int
let userID: Int
let user: String
let userImageURL: String

enum CodingKeys: String, CodingKey {
    case id, pageURL, type, tags, previewURL, previewWidth, previewHeight, webformatURL, webformatWidth, webformatHeight, largeImageURL, imageWidth, imageHeight, imageSize, views, downloads, collections, likes, comments
    case userID = "user_id"
    case user, userImageURL
 }
}

enum TypeEnum: String, Codable {
case photo = "photo"
}

#3

спасибо большое, за целый день глаз замылился


#4

а может подскажите еще такой вопрос, вот получений json надо предать в массив, что бы полученный массив картинок передать в для начала в

override func collectionView( _ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
а потом и в ячейку что бы вывести на экран