swift 在集合视图中没有显示图像

ddarikpa  于 2022-10-31  发布在  Swift
关注(0)|答案(1)|浏览(790)

我遇到了一个我无法处理的问题。现在我正在开发一个显示照片的应用程序。我使用的是来自unplash的api。下面我将向你展示我的代码。

我的代码来自ViewModel,我在其中向服务器发出请求:

class PhotoViewModel {
    //        let url = URL(string: "https://api.unsplash.com/photos/random/?count=30&client_id=\(key)")
    private let key = "KEY"
    private let authorization = "Authorization"
    var cell = HomeCollectionViewCell()
    var photo: [Photo] = []

    // MARK: func fetchPhoto
    func fetchPhoto(){
        let url = URL(string: "https://api.unsplash.com/photos")
        var request = URLRequest(url: url!)
        request.httpMethod = "GET"
        request.setValue("Client-ID KEY)", forHTTPHeaderField: "Authorization")

        URLSession.shared.dataTask(with: request) { data, response, error in
            if let data = data {
                do {
                    let image = try JSONDecoder().decode([Photo].self, from: data)
                    self.photo.append(contentsOf: image)

                    print(image)

                } catch let error {
                    print(error.localizedDescription)
                }
            }
        }.resume()
    }

}

"这是我正在使用的模型"

struct Photo: Codable {
    let id: String
    let created_at: String
    let width: Int
    let height: Int
    let likes: Int
    let urls: URLs
}
struct URLs: Codable {
    let raw: String
}

显示数据的单元格。为了上传照片,我决定使用Kingfisher。

class HomeCollectionViewCell: UICollectionViewCell {

    @IBOutlet weak var unsplashPhoto: UIImageView!
    @IBOutlet weak var test: UILabel!

    func setup(photo: Photo) {
        let url = URL(string: photo.urls.raw)
        unsplashPhoto.kf.setImage(with: url)
        self.test.text = photo.created_at
    }

}

这是我的主要ViewController代码。

class ViewController: UIViewController {
    var photos =  [Photo]()
    private var photoViewModel = PhotoViewModel()

    @IBOutlet weak var homeCV: UICollectionView!

    override func viewDidLoad() {
        super.viewDidLoad()
        self.homeCV.dataSource = self
        self.homeCV.delegate = self

        photoViewModel.fetchPhoto()
        DispatchQueue.main.async {
            self.homeCV.reloadData()}

    }

}
extension ViewController:  UICollectionViewDataSource, UICollectionViewDelegate {

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return photos.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! HomeCollectionViewCell
        let photo = photos[indexPath.row]
        cell.setup(photo: photo)
        return cell

    }

}

尝试了不同的选项。我可以看到我的JSON文件显示在控制台中,但当我运行模拟器时,数据没有显示在屏幕上。

wj8zmpe1

wj8zmpe11#

您没有显示数据,因为您没有从ViewController填充数组。我会尝试将包含数据的完成处理程序传递到ViewController,并在那里填充dataSource。您的请求已经发出,但您没有进一步将数据传递到ViewController。我会将来自viewModel的请求重写为:

func fetchPhoto(completion: @escaping (Result<[Photo], Error>) -> Void){
                   let url = URL(string: "https://api.unsplash.com/photos")
                   var request = URLRequest(url: url!)
                   request.httpMethod = "GET"
                   request.setValue("Client-ID KEY)", forHTTPHeaderField: "Authorization")

                   URLSession.shared.dataTask(with: request) { data, response, error in
                       if let data = data {
                           do {
                               let image = try JSONDecoder().decode([Photo].self, from: data)
                               self.photo.append(contentsOf: image)
                               completion(.success(photo))
                               print(image)

                           } catch let error {
                               completion(.failure(error))
                               print(error.localizedDescription)
                           }
                       }
                   }.resume()
               }

并在ViewController中这样调用请求:并且只有在填充了dataSource之后才对collectionView调用reloadData。

photoViewModel.fetchPhoto { result in
            switch result {
            case .success(let data):
                self.photos = data
                DispatchQueue.main.async { [weak self] in
                    self?.homeCV.reloadData()
                }
            case .failure(let err):
                break
            }
       }

相关问题