Как решить JSON декодируемое плохое исключение, используя Swift 4.2? - PullRequest
0 голосов
/ 16 февраля 2019

Мой сценарий, я пытаюсь получить data из JSON и загружаю в tableView.В то время как compile время я получаю badexception от процесса JSON decodable.ниже ответа JSON, который я использую, я не могу получить точное значение issues.Пожалуйста, предоставьте некоторые предложения

Мой ответ JSON

{
  "status": true,
  "status_code": 1,
  "data": [
    {
      "cat_id": "1",
      "cat_name": "Food",
      "cat_parentid": "2",
      "name": "guru",
      "year": "3000",
      "fullname": {
        "firstname": "jio",
        "lastname": "jack"
      },
      "address": {
        "city": "sanfrancisco",
        "state": "california"
      },
      "ship": {
        "captian": "mojo",
        "time": "12.30.01"
      }
    }
   ]
}

Мой декодируемый

struct Root: Decodable {
    let catID, catName, catParentid, name, year: String?

    private enum CodingKeys: String, CodingKey {
        case catID = "cat_id"
        case catName = "cat_name"
        case catParentid = "cat_parentid"
        case name, year
    }
}

Мой код JSON

func parseJSON() {

        let url = URL(string: "https://...")

        let task = URLSession.shared.dataTask(with: url!) {(data, response, error) in

        guard error == nil else {
            print("returning error")
            return
        }

        guard let content = data else {
            print("not returning data")
            return
        }

        guard let json = (try? JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableContainers)) as? [String: Any] else {
            print("Error")
            return
        }

            do {
                let content = json["data"] as! [[String:String]]
                let staData = try JSONSerialization.data(withJSONObject:content,options:[])
                self.tableArray = try JSONDecoder().decode([Root].self, from:staData)
            }
            catch {
                print(error)
            }

        print(self.tableArray)

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

        }
        task.resume()
    }

Моя проблема

issue screen

Ответы [ 3 ]

0 голосов
/ 16 февраля 2019

Я сгенерировал Codable протокол из ЗДЕСЬ и он будет выглядеть так:

struct Root: Codable {
    let status: Bool
    let statusCode: Int
    let data: [Datum]

    enum CodingKeys: String, CodingKey {
        case status
        case statusCode = "status_code"
        case data
    }
}

struct Datum: Codable {
    let catID, catName, catParentid, name: String
    let year: String
    let fullname: Fullname
    let address: Address
    let ship: Ship

    enum CodingKeys: String, CodingKey {
        case catID = "cat_id"
        case catName = "cat_name"
        case catParentid = "cat_parentid"
        case name, year, fullname, address, ship
    }
}

struct Address: Codable {
    let city, state: String
}

struct Fullname: Codable {
    let firstname, lastname: String
}

struct Ship: Codable {
    let captian, time: String
}

Теперь я проверил его на игровой площадке с вашим JSON, который выглядит ниже:

let jsonData = """
{
  "status": true,
  "status_code": 1,
  "data": [
    {
      "cat_id": "1",
      "cat_name": "Food",
      "cat_parentid": "2",
      "name": "guru",
      "year": "3000",
      "fullname": {
        "firstname": "jio",
        "lastname": "jack"
      },
      "address": {
        "city": "sanfrancisco",
        "state": "california"
      },
      "ship": {
        "captian": "mojo",
        "time": "12.30.01"
      }
    }
   ]
}
""".data(using: .utf8)!

И вы можете проанализировать его следующим образом:

let root = try? JSONDecoder().decode(Root.self, from: jsonData)

Теперь вы можете получить массив данных из root объекта с

let content = root?.data //here your crash will resolve

contentэто тип [Datum]

0 голосов
/ 16 февраля 2019

Прежде всего используйте структуры, предоставленные Гереоном.

Затем замените свою функцию на

func parseJSON() {

    let url = URL(string: "https://...")

    let task = URLSession.shared.dataTask(with: url!) {(data, response, error) in

        if let error = error { print("returning error", error); return }

        do {
            let result = try JSONDecoder().decode(Root.self, from:data!)
            self.tableArray = result.data
            print(self.tableArray)
        } catch {
            print(error)
            self.tableArray = []
        }
        DispatchQueue.main.async {
            self.tableView.reloadData()
        }

    }
    task.resume()
}
0 голосов
/ 16 февраля 2019

Вам нужно будет написать свои структуры, чтобы они точно соответствовали структуре ваших данных JSON, например:

struct Root: Codable {
    let status: Bool
    let statusCode: Int
    let data: [Datum]

    enum CodingKeys: String, CodingKey {
        case status
        case statusCode = "status_code"
        case data
    }
}

struct Datum: Codable {
    let catID, catName, catParentid, name: String
    let year: String
    let fullname: Fullname
    let address: Address
    let ship: Ship

    enum CodingKeys: String, CodingKey {
        case catID = "cat_id"
        case catName = "cat_name"
        case catParentid = "cat_parentid"
        case name, year, fullname, address, ship
    }
}

struct Address: Codable {
    let city, state: String
}

struct Fullname: Codable {
    let firstname, lastname: String
}

struct Ship: Codable {
    let captian, time: String
}

С ними вы можете просто использовать JSONDecoder без необходимости JSONSerialization

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...