Swift: JSONSerialization.jsonObject не работает для json в json - PullRequest
0 голосов
/ 25 апреля 2018

Я использую этот код для получения данных JSON от URL:

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

 do {           
   let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [String:String]
   completion(json)              
 } catch _ as NSError {
   completion(nil)
 }
}).resume()

Если мой JSON {"error":"true","message":"no"}, он работает нормально

Но если я использую JSON в JSON, это не такработы:

{"error":"true","message":"no","state":{"id":"1","name":"empty"}}

Ответы [ 3 ]

0 голосов
/ 25 апреля 2018

Используя as! [String:String], вы говорите, что все значения в словаре будут иметь тип String, но вложенный JSON, связанный с ключом состояния, очевидно, не является String

, использует as? [String: Any], а затем приводит вашдругие свойства по мере необходимости.result["error"] as String

Использование этого метода затрудняет получение вложенных данных:

if let state = result["state"] as? [String: String] {
    let name = state["name"]
    let value = state["value"]
}

Примечания

  1. При использовании Swift 4 илибольше вы должны использовать Codable Protocol
  2. Вы не должны быть принудительным развертыванием, используйте условное развертывание (as? [String: Any])

РЕДАКТИРОВАТЬ:

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

Код игровой площадки

// you dont need this part, I am not making network request
let jsonData = """
{"error":"true","message":"no","state":{"id":"1","name":"empty"}}
""".data(using: .utf8)

struct ErrorState: Codable
{
    let id: String
    let name: String
}

struct ErrorResponse: Codable
{
    let error: String
    let message: String
    let state: ErrorState
}

guard let data = jsonData else { fatalError() }

let errorResponse = try? JSONDecoder().decode(ErrorResponse.self, from: data)
print(errorResponse?.state.name)
0 голосов
/ 25 апреля 2018

Можете ли вы использовать этот код. Этот код должен работать для вашего ответа json.

let error = json["error"]! as! NSString
print(error) // it prints true

let message = json["message"]! as! NSString
print(message) // it prints no

guard let state = json["state"] as? [String: String],

let id = state["id"],      
let name = state["name"]

else  {
  return
}

print(id)  // it prints 1
print(name) // it prints empty

Если есть другие вопросы, пожалуйста, прокомментируйте меня!

0 голосов
/ 25 апреля 2018

Вы должны использовать кодируемый протокол, как этот

 var json = [String:Any]()

    struct List : Decodable {

        let error : String
        let message : String

        private enum CodingKeys : String, CodingKey { case name = "error", score = "message" }

    }


    var list = [List]()

    let jsonString = """

                      {"error" : "true", "message" : "no"}

                     """

    let data = Data(jsonString.utf8)

    do {
        list = try JSONDecoder().decode([List].self, from: data)
        let error = list.object(forKey: "error") as? String ?? ""
        print(error)
    } 
   catch { print(error) }
...