Невозможно получить словарь из JSON - PullRequest
0 голосов
/ 24 июня 2018

Это код, который я использую, но я не могу получить JSON.

Сообщение об ошибке:

Ожидается декодирование словаря, но вместо него найден массив.

func getMovieByName(completion: @escaping (Bool, Any?, Error?) -> Void) {
    guard let url = URL(string:"https://api.themoviedb.org/3/search/movie?api_key=4cb1eeab94f45affe2536f2c684a5c9e&query='star") else { return }

    let session = URLSession.shared
    let task = session.dataTask(with: url) { (data, _, _) in
        guard let data = data else { return  }
        do {
            let items = try JSONDecoder().decode(ItemList.self, from: data)

            DispatchQueue.main.async {
                completion(true, items, nil)
            }
        } catch {
            DispatchQueue.main.async {
                completion(false, nil, error)
            }
        }
    }
    task.resume()
}

JSON:

{
    "page": 1,
    "total_results": 2102,
    "total_pages": 106,
    "results": [{
        "vote_count": 9052,
        "id": 11,
        "video": false,
        "vote_average": 8.2,
        "title": "Star Wars",
        "popularity": 31.502792,
        "poster_path": "/btTdmkgIvOi0FFip1sPuZI2oQG6.jpg",
        "original_language": "en",
        "original_title": "Star Wars",
        "genre_ids": [
            12,
            28,
            878
        ],
        "backdrop_path": "/4iJfYYoQzZcONB9hNzg0J0wWyPH.jpg",
        "adult": false,
        "overview": "Princess Leia is captured and held hostage by the evil Imperial forces in their effort to take over the galactic Empire. Venturesome Luke Skywalker and dashing captain Han Solo team together with the loveable robot duo R2-D2 and C-3PO to rescue the beautiful princess and restore peace and justice in the Empire.",
        "release_date": "1977-05-25"
    }]
}

struct Results: Codable    {
    let id: Int
    let title: String
    let poster_path: String


struct ItemList: Codable {
    let results: Results
}

}

Ответы [ 2 ]

0 голосов
/ 24 июня 2018

Вы можете создать Swift Struct для этой цели. Вот как ты это делаешь.

import Foundation

struct MovieStruct: Codable {
    let page, totalResults, totalPages: Int?
    let results: [Result]?

    enum CodingKeys: String, CodingKey {
        case page
        case totalResults = "total_results"
        case totalPages = "total_pages"
        case results
    }
}

struct Result: Codable {
    let voteCount, id: Int?
    let video: Bool?
    let voteAverage: Double?
    let title: String?
    let popularity: Double?
    let posterPath, originalLanguage, originalTitle: String?
    let genreIDS: [Int]?
    let backdropPath: String?
    let adult: Bool?
    let overview, releaseDate: String?

    enum CodingKeys: String, CodingKey {
        case voteCount = "vote_count"
        case id, video
        case voteAverage = "vote_average"
        case title, popularity
        case posterPath = "poster_path"
        case originalLanguage = "original_language"
        case originalTitle = "original_title"
        case genreIDS = "genre_ids"
        case backdropPath = "backdrop_path"
        case adult, overview
        case releaseDate = "release_date"
    }
}

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

func getMovieByName(completion: @escaping (Bool, Any?, Error?) -> Void) {
    guard let url = URL(string:"https://api.themoviedb.org/3/search/movie?api_key=4cb1eeab94f45affe2536f2c684a5c9e&query='star") else { return }

    let session = URLSession.shared
    let task = session.dataTask(with: url) { (data, _, _) in
        guard let data = data else { return  }
        do {
            let items = try? JSONDecoder().decode(MovieStruct.self, from: jsonData)

            DispatchQueue.main.async {
                completion(true, items, nil)
            }
        } catch {
            DispatchQueue.main.async {
                completion(false, nil, error)
            }
        }
    }
    task.resume()
}

Примечание. Я создал структуру с JSON, который вы указали. Надеюсь, это поможет.

0 голосов
/ 24 июня 2018
func getMovieByName(completion: @escaping (Bool, Any?, Error?) -> Void) {
    guard let url = URL(string:"https://api.themoviedb.org/3/search/movie?api_key=4cb1eeab94f45affe2536f2c684a5c9e&query='star") else { return }

    let session = URLSession.shared
    let task = session.dataTask(with: url) { (data, _, _) in
        guard let data = data else { return  }
        do {
            let items = try JSONDecoder().decode(Result.self, from: data)

            DispatchQueue.main.async {
                completion(true, items, nil)
            }
        } catch {
            DispatchQueue.main.async {
                completion(false, nil, error)
            }
        }
    }
    task.resume()
}

Структура результатов содержит содержимое "результатов"

struct Result: Codable {
    var results: [Movie]
}

Добавление переменных, соответствующих полям элемента

struct Movie: Codable {
    var id: Int
    var vote_count: Int
    var title: String

    //etc..
}
...