Как правильно разобрать вложенную строку JSON в правильный JSON?

"{\"event\":\"posted\",\"data\":{\"channel_display_name\":\"\",\"channel_name\":\"e6webbgbt7gp8ryb4yyheiyrcw__jbk5semtk3dhjqzcoscu7g4yhe\",\"channel_type\":\"D\",\"mentions\":\"[\\\"jbk5semtk3dhjqzcoscu7g4yhe\\\"]\",\"post\":\"{\\\"id\\\":\\\"4fu4ey9fwfbyzndnz6brycmcry\\\",\\\"create_at\\\":1516692235168,\\\"update_at\\\":1516692235168,\\\"edit_at\\\":0,\\\"delete_at\\\":0,\\\"is_pinned\\\":false,\\\"user_id\\\":\\\"e6webbgbt7gp8ryb4yyheiyrcw\\\",\\\"channel_id\\\":\\\"6jc3md8ayfycxb87fqz63jphia\\\",\\\"root_id\\\":\\\"\\\",\\\"parent_id\\\":\\\"\\\",\\\"original_id\\\":\\\"\\\",\\\"message\\\":\\\"dd\\\",\\\"type\\\":\\\"\\\",\\\"props\\\":{},\\\"hashtags\\\":\\\"\\\",\\\"pending_post_id\\\":\\\"e6webbgbt7gp8ryb4yyheiyrcw:1516692235123\\\"}\",\"sender_name\":\"bibek\",\"team_id\":\"\"},\"broadcast\":{\"omit_users\":null,\"user_id\":\"\",\"channel_id\":\"6jc3md8ayfycxb87fqz63jphia\",\"team_id\":\"\"},\"seq\":9}"

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

guard let data = text.data(using: .utf8) else {return}
let json = try? JSONSerialization.jsonObject(with: data, options: [])

Я получил:

{
  "event" : "posted",
  "data" : {
    "channel_display_name" : "",
    "channel_name" : "e6webbgbt7gp8ryb4yyheiyrcw__jbk5semtk3dhjqzcoscu7g4yhe",
    "sender_name" : "bibek",
    "post" : "{\"id\":\"4fu4ey9fwfbyzndnz6brycmcry\",\"create_at\":1516692235168,\"update_at\":1516692235168,\"edit_at\":0,\"delete_at\":0,\"is_pinned\":false,\"user_id\":\"e6webbgbt7gp8ryb4yyheiyrcw\",\"channel_id\":\"6jc3md8ayfycxb87fqz63jphia\",\"root_id\":\"\",\"parent_id\":\"\",\"original_id\":\"\",\"message\":\"dd\",\"type\":\"\",\"props\":{},\"hashtags\":\"\",\"pending_post_id\":\"e6webbgbt7gp8ryb4yyheiyrcw:1516692235123\"}",
    "channel_type" : "D",
    "team_id" : "",
    "mentions" : "[\"jbk5semtk3dhjqzcoscu7g4yhe\"]"
  },
  "seq" : 9,
  "broadcast" : {
    "channel_id" : "6jc3md8ayfycxb87fqz63jphia",
    "omit_users" : null,
    "user_id" : "",
    "team_id" : ""
  }
}

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

2 ответа

Есть два способа анализа JSON.

До Свифта 4

До Swift 4 вы могли использовать только класс JSONSerialization (как в вашем примере). Этот метод возвращает объект Any, который можно привести в словарь (тип зависит от данных, которые вы получаете).

Например:

if let dict = try? JSONSerialization.jsonObject(with: data, options: []) as! Dictionary<String,String>{
   do some stuff...
}

Если у вас есть несколько видов данных, вы должны использовать это приведение:

  if let dict = try? JSONSerialization.jsonObject(with: data, options: []) as! Dictionary<String,Any?>{
       do some stuff...
    }

Затем вы можете получить доступ ко всем данным в словаре по ключу и управлять данными (если вы используете Any, не забывайте вводить правильные данные перед их использованием).

Вот некоторая документация: https://developer.apple.com/documentation/foundation/jsonserialization

После Свифта 4

В Swift 4 был представлен новый класс: JSONEncoder и JSONDecoder. Это удивительно, потому что вы можете создать свою модель, анализируя json, и вы получите объект со всеми уже заполненными полями. Обратите внимание, что ваша модель ДОЛЖНА реализовывать протокол Codable (или Encodable and Decodable). Если ваша модель не реализует протокол, вы получите ошибку.

Вот пример:

Это моя модель:

class myClass: Codable{
    var Id: Int
    var Identifier: String
    var Alias: String
    var Revision: Int
    var Title: String
}

И это код для разбора:

let decoder = JSONDecoder()

let myClass = try! decoder.decode(Questionario.self, from: (json?.data(using: .utf8))!)

Теперь моя переменная "myClass" уже содержит все поля, заполненные данными в json.

Вот некоторая документация:

https://developer.apple.com/documentation/swift/codable

https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types

Пытаться

let data = text.data(using: .utf8)
let json = try? JSONSerialization.jsonObject(with: data!, options: [])
if let value = json as? [String:AnyObject]{
if let dict = value["data"] as? NSDictionary{
    let post = dict.value(forKey: "post") as? String
    let data = post!.data(using: .utf8)
    let json1 = try? JSONSerialization.jsonObject(with: data!, options: [])
    print(json1!)
}
}

как я получил сообщение в форме JSON, дайте мне знать для любых исправлений

Другие вопросы по тегам