Прием и сортировка массивов с помощью Alamofire - PullRequest
0 голосов
/ 13 апреля 2019

просьба помочь с alamofire (два дня не могу найти и понять ошибку); по заданию мне нужно получить данные JSON через api и автоматически «разложить» их в

var articles = [Articles]()

Эти значения (JSON) приходят и печатаются, но из-за неправильного метода / структуры я не могу автоматически их разложить.

let api_url = "https://newsapi.org/v2/everything?q=bitcoin&from=2019-03-13&sortBy=publishedAt&apiKey=xxx"

let formatter = "https://jsonformatter.curiousconcept.com/"

И

struct Articles: Decodable {

    var author: String?
    var content: String?
    var description: String?
    var publishedAt: String?
    var title: String?
    var url: String?
    var urlToImage: String?

    init(dict: [String: Any]) {

        let author = dict["author"] as? String ?? ""
        // some let's...
        let urlToImage = dict["urlToImage"] as? String ?? ""

        self.author = author
        // some self's...
        self.publishedAt = publishedAt
    }

    static func getArray(from arrayOfItems: Any) -> [Articles]? {
        guard let arrayOfItems = arrayOfItems as? Array<[String: Any]> 
        else { print("ERROR at ArticleModel -> Articles"); return nil }

        return arrayOfItems.compactMap { Articles(dict: $0) }
    }
}

//Download Data

func fetchDataWithAlamofire() {

    guard let url = URL(string: api_url) else { return }

    request(url).validate().responseJSON { (dataResponse) in

        switch dataResponse.result {
        case .success(let value):
            print(value)

            if let response = Articles.getArray(from: value) {
                self.articles = response
            }

            DispatchQueue.main.async {
                self.tableView.reloadData()
            }

        case .failure(let error):
            print(error)
        }
    }
}

Данные JSON, которые я получил, должны автоматически (через метод) распространяться в массиве и отображаться в ячейке симулятора (я уже сделал ячейки, проблема в Array / Dict / Struct)

1 Ответ

1 голос
/ 13 апреля 2019

Прежде всего, почему ваша структура соответствует Decodable, хотя вы вообще не используете JSONDecoder?

Вы делаете общую ошибку, вы игнорируете корневой объект.Вам нужно две структуры, и, пожалуйста, назовите Article в единственном числе.

struct Root : Decodable {
    let status : String
    let totalResults : Int?
    let message : String? // message is used in case of an error
    let articles : [Article]?
}

struct Article : Decodable {

    let author : String?
    let content : String?
    let description : String
    let publishedAt : Date
    let title : String
    let url : URL
    let urlToImage : URL?
}

Инициализатор и статическая функция в Article не нужны.

В fetchDataWithAlamofire() используйте responseData вместо responseJSON и декодировать JSON с помощью JSONDecoder.
url и urlToImage можно декодировать непосредственно в URL, а publishedAt можно декодировать в Date

func fetchDataWithAlamofire() {

    guard let url = URL(string: api_url) else { return }

    request(url).validate().responseData { dataResponse in

        switch dataResponse.result {
        case .success(let data):
            do {
                let decoder = JSONDecoder()
                decoder.dateDecodingStrategy = .iso8601
                let result = try decoder.decode(Root.self, from: data)
                self.articles = result.articles

                DispatchQueue.main.async {
                   self.tableView.reloadData()
                }
            } catch {
                print(error)
            }

        case .failure(let error):
            print(error)
        }
    }
}
...