почему я получаю эту ошибку при разборе swift JSON? - PullRequest
0 голосов
/ 14 сентября 2018

Почему я получаю ошибку при разборе данных Вот мой код:

import UIKit
struct jsondata: Decodable {
      let id: Int
      let name: String
      let link: String
}

class ViewController: UIViewController {

    override func viewDidLoad() {
          super.viewDidLoad()

        let jsonUrlString = "https://api.letsbuildthatapp.com/jsondecodable/courses_missing_fields"

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

        URLSession.shared.dataTask(with: url) { (data, response, error) in
            guard let data = data else {return}

            do{
                let course = try JSONDecoder().decode([jsondata].self, from: data)
                print(jsondata.link)
            }
            catch let jsonerr{
                print("error serilizing",jsonerr)
            }
        }
    }
}

Ответы [ 2 ]

0 голосов
/ 14 сентября 2018

Если вы просматриваете список элементов, возвращаемых с сервера в массиве JSON, последний элемент имеет единственное имя.Нет доступных полей id, link, imageUrl или number_of_lessons.Чтобы соответствовать этому сценарию, вам необходимо сделать идентификатор и ссылку необязательными, добавив ?.Если вы не много знаете об опционах, я советую вам прочитать эту статью на среднем .

когда вы анализируете JSON и извлекаете массив курсов, вам не нужно получать доступ к данным JSON, которые вы использовали для анализа.Поскольку у вас есть много читаемых объектов курсов внутри массива, просто получите к нему доступ с помощью индекса.Вот для примера, я получил 0-й индекс, набрав print(course[0].link).

Кстати, пожалуйста, не обращайтесь к элементам напрямую, используя индекс в готовом к использованию коде, потому что вы никогда не знаете, сколько элементов было возвращено с сервера.

ваш код должен выглядеть примерно таккак показано ниже.

import UIKit
struct jsondata: Decodable {
    let id: Int?
    let name: String
    let link: String?
}

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let jsonUrlString = "https://api.letsbuildthatapp.com/jsondecodable/courses_missing_fields"

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

        let dataTask = URLSession.shared.dataTask(with: url) { (data, response, error) in
            guard let data = data else {return}

            do{
                let course = try JSONDecoder().decode([jsondata].self, from: data)
                print(course[0].link)
//                print(jsondata.link)
            }
            catch let jsonerr{
                print("error serilizing",jsonerr)
            }
        }

        dataTask.resume()
    }
}
0 голосов
/ 14 сентября 2018

Сделайте опцию параметром в соответствии с требованием:

let id: Int?
let name: String?
let link: String?

А если вы получаете в ответ массив объектов, то

let course = try JSONDecoder().decode([jsondata].self, from: data)
print(course.first.link)

А если вы получаете без массива:

let course = try JSONDecoder().decode(jsondata.self, from: data)
print(course.link)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...