Я не могу открыть изображение. Разбор не работает - PullRequest
0 голосов
/ 03 апреля 2020

Я не могу открыть "url" в "images". Разбор не работает. Пожалуйста помоги. Спасибо.

"images": [
        {
          "url": "https://ktar.com/wp-content/uploads/2020/03/ap_27df5153e3bf48198ebcfd40900446d6.jpg",
          "width": 1280,
          "height": 853,
          "title": "Arizona reports 124 new coronavirus cases, five additional deaths",
          "attribution": null

===================================== =================

=========================== ============================ API

{
      "path": "_news/2020-04-01-arizona-reports-124-new-coronavirus-cases-five-additional-deaths.md",
      "title": "Arizona reports 124 new coronavirus cases, five additional deaths",
      "excerpt": "The Arizona health department reported 124 new cases of coronavirus and five additional deaths on Wednesday morning, a day after the state's \"stay at home\" order went into effect.",
      "heat": 145,
      "tags": [
        "US"
      ],
      "type": "article",
      "webUrl": "https://ktar.com/story/3056413/arizona-reports-124-new-coronavirus-cases-five-additional-deaths/",
      "ampWebUrl": "https://ktar.com/story/3056413/arizona-reports-124-new-coronavirus-cases-five-additional-deaths/amp/",
      "cdnAmpWebUrl": "https://ktar-com.cdn.ampproject.org/c/s/ktar.com/story/3056413/arizona-reports-124-new-coronavirus-cases-five-additional-deaths/amp/",
      "publishedDateTime": "2020-04-01T09:09:00-07:00",
      "updatedDateTime": null,
      "provider": {
        "name": "KTAR News",
        "domain": "ktar.com",
        "images": null,
        "publishers": null,
        "authors": null
      },
      "images": [
        {
          "url": "https://ktar.com/wp-content/uploads/2020/03/ap_27df5153e3bf48198ebcfd40900446d6.jpg",
          "width": 1280,
          "height": 853,
          "title": "Arizona reports 124 new coronavirus cases, five additional deaths",
          "attribution": null
        }
      ],
      "locale": "en-us",
      "categories": [
        "news"
      ],
      "topics": [
        "Coronavirus in US",
        "Coronavirus",
        "New Cases"
      ]
    }

============ ================================================

== ================================================== ==

//  SPORTNEWSVC.swift
//  Hero

import Alamofire
import Kingfisher
import UIKit


class NewsVC: UICollectionViewController, UICollectionViewDelegateFlowLayout {

    var news = [Article]()

    override func viewDidLoad() {
        super.viewDidLoad()

        getArticles()

    }

    func getArticles() {

        let parameters: Parameters = ["Subscription-Key": "3009d4ccc29e4808af1ccc25c69b4d5d"]

        Alamofire.request("https://api.smartable.ai/coronavirus/news/US", parameters: parameters).responseData { (response) in

            guard let data = response.data else { return }

            do {

//                let json = try JSONSerialization.jsonObject(with: data, options: [])
//                print(json)

                let topHeadlinesResponse = try JSONDecoder().decode(TopHeadlinesResponse.self, from: data)
                self.news = topHeadlinesResponse.news
                self.collectionView?.reloadData()

            } catch {
                print(error)
            }

        }

    }


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

    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ArticleCell", for: indexPath) as? ArticleCell else { return UICollectionViewCell ()}

        let article = news[indexPath.item]
        cell.populate(with: article)

        return cell

    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

        let height: CGFloat = 277

        let width = (collectionView.frame.width / 2) - 2

        let size = CGSize(width: width, height: height)

        return size

    }

}

====================================== ===============

================================== =========================

//  Article.swift
//  Hero
//

import Foundation

struct Article: Decodable {
    let headline: String
    let url: String?

    private enum CodingKeys: String, CodingKey {
        case headline = "title"
        case url
    }

}

================ ============================================

====== ================================================

//
//  ArticleCell.swift
//  Hero

import UIKit
import Kingfisher

class ArticleCell: UICollectionViewCell {

    @IBOutlet weak var articleImageView: UIImageView!
    @IBOutlet weak var headlieLabel: UILabel!

    func populate(with article: Article){
        headlieLabel.text = article.headline

        if let url = article.url {
            let url = URL(string: url)
            articleImageView.kf.setImage(with: url)
        }

    }

}

================================================ ===========

======================================= =====================

import Foundation


struct TopHeadlinesResponse: Decodable {
    let news: [Article]
}

Ответы [ 2 ]

0 голосов
/ 03 апреля 2020

Идея состоит в том, что "изображения" в ответе JSON, который вы получаете, являются массивом, и вам необходимо отразить этот факт в структуре Codable. Маги декодирования c требуют, чтобы вы следовали JSON структуре данных и именам: так что если вы встречаете поле 'width' внутри словаря 'image' - вам нужно иметь поле с именем 'width' внутри поля 'image' (например, имея изображение как отдельную структуру)

вы можете узнать больше о Decodables здесь

struct NewsApiResponse : Decodable {
    let status : String
    let updatedDateTime : Date?
    let news : [Article]
}

struct Article : Decodable {
    let id : Int
    let title : String
    let excerpt : String
    let webUrl : String
    let publishedDateTime : Date?
    let images : [Image]
}

struct Image : Decodable {
    let url : String
    let width : Int
    let height : Int
    let title : String
}
0 голосов
/ 03 апреля 2020
*struct TopHeadLinesResponse: Codable {
    let path, title, excerpt: String
    let heat: Int
    let tags: [String]
    let type: String
    let webURL, ampWebURL, cdnAmpWebURL: String
    let publishedDateTime: Date
    let updatedDateTime: JSONNull?
    let provider: Provider
    let images: [Image]
    let locale: String
    let categories, topics: [String]

    enum CodingKeys: String, CodingKey {
        case path, title, excerpt, heat, tags, type
        case webURL
        case ampWebURL
        case cdnAmpWebURL
        case publishedDateTime, updatedDateTime, provider, images, locale, categories, topics
    }
}

// MARK: - Image
struct Image: Codable {
    let url: String
    let width, height: Int
    let title: String
    let attribution: JSONNull?
}

// MARK: - Provider
struct Provider: Codable {
    let name, domain: String
    let images, publishers, authors: JSONNull?
}

// MARK: - Encode/decode helpers

class JSONNull: Codable, Hashable {

    public static func == (lhs: JSONNull, rhs: JSONNull) -> Bool {
        return true
    }

    public var hashValue: Int {
        return 0
    }

    public init() {}

    public required init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        if !container.decodeNil() {
            throw DecodingError.typeMismatch(JSONNull.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for JSONNull"))
        }
    }

    public func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        try container.encodeNil()
    }
}
 extension UIImageView {
func loadImagee(_ urlString: String?, onSuccess: ((UIImage) -> Void)? = nil) {
    self.image = UIImage()
    guard let string = urlString else { return }
    guard let url = URL(string: string) else { return }
    self.sd_setImage(with: url) { (image, error, type, url) in
        if onSuccess != nil, error == nil {
            onSuccess!(image!)
        }
    }
}
}

// try using SD Web library code is above install SDweb instead of // king fisher
// check your struct also check this answer

https://stackoverflow.com/questions/60310054/im-having-troubles-displaying-an-image-from-json-in-a-table-view*
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...