JSON Parsing en Swift 3

¿Alguien ha podido encontrar una forma de analizar a través de archivos JSON en Swift 3? He podido recuperar los datos pero no tengo éxito cuando se trata de dividir los datos en campos específicos. Publicaba el código de muestra pero he pasado por tantos métodos diferentes sin éxito y no he guardado ninguno. El formato básico que quiero analizar es algo como esto. Gracias por adelantado.

{ "Language": { "Field":[ { "Number":"976", "Name":"Test" }, { "Number":"977", "Name":"Test" } ] } } 

¿Has probado JSONSerialization.jsonObject(with:options:) ?

 var jsonString = "{" + "\"Language\": {" + "\"Field\":[" + "{" + "\"Number\":\"976\"," + "\"Name\":\"Test\"" + "}," + "{" + "\"Number\":\"977\"," + "\"Name\":\"Test\"" + "}" + "]" + "}" + "}" var data = jsonString.data(using: .utf8)! let json = try? JSONSerialization.jsonObject(with: data) 

Swift a veces produce una syntax muy extraña.

 if let number = json?["Language"]??["Field"]??[0]?["Number"] as? String { print(number) } 

Todo en la jerarquía de objetos JSON termina envuelto como opcional (es decir, AnyObject? ). Array subíndice Array devuelve una T no opcional. Para este JSON, que está envuelto en un subíndice de matriz opcional, devuelve Optional . Sin embargo, el subíndice Dictionary devuelve un Optional . Para este JSON, el subíndice devuelve el aspecto muy extraño Optional> (es decir, AnyObject?? ).

  • json es un Optional .
  • json?["Language"] devuelve un Optional> .
  • json?["Language"]??["Field"] devuelve un Optional> .
  • json?["Language"]??["Field"]??[0] devuelve un Optional .
  • json?["Language"]??["Field"]??[0]?["Number"] devuelve un Optional> .
  • json?["Language"]??["Field"]??[0]?["Number"] as? String json?["Language"]??["Field"]??[0]?["Number"] as? String devuelve un Optional .

El Optional es luego utilizado por la syntax if let para producir un String .


Nota final: la iteración de la matriz de campo se ve así.

 for field in json?["Language"]??["Field"] as? [AnyObject] ?? [] { if let number = field["Number"] as? String { print(number) } } 

Swift 4 actualización

Swift 4 hace todo esto mucho más fácil de tratar. Nuevamente comenzaremos con sus datos de prueba ( """ hace mucho mejor”).

 let data = """ { "Language": { "Field":[ { "Number":"976", "Name":"Test" }, { "Number":"977", "Name":"Test" } ] } } """.data(using: .utf8)! 

Luego podemos definir clases alrededor de los objetos usados ​​en su JSON.

 struct Object: Decodable { let language: Language enum CodingKeys: String, CodingKey { case language="Language" } } struct Language: Decodable { let fields: [Field] enum CodingKeys: String, CodingKey { case fields="Field" } } struct Field: Decodable { let number: String let name: String enum CodingKeys: String, CodingKey { case number="Number"; case name="Name" } } 

La enumeración de CodingKeys es cómo se mapean las propiedades de estructura a las cadenas de miembros de objeto JSON. Este mapeo se hace automágicamente por Decodable .


Analizar el JSON ahora es simple.

 let object = try! JSONDecoder().decode(Object.self, from: data) print(object.language.fields[0].name) for field in object.language.fields { print(field.number) } 

En Xcode 8 y Swift 3 id ahora importa como Any lugar de AnyObject

Esto significa que JSONSerialization.jsonObject(with: data) devuelve Any . Entonces debe convertir los data json a un tipo específico como [String:Any] . Lo mismo se aplica a los siguientes campos en el json.

 var jsonString = "{" + "\"Language\": {" + "\"Field\":[" + "{" + "\"Number\":\"976\"," + "\"Name\":\"Test1\"" + "}," + "{" + "\"Number\":\"977\"," + "\"Name\":\"Test2\"" + "}" + "]" + "}" + "}" var data = jsonString.data(using: .utf8)! if let parsedData = try? JSONSerialization.jsonObject(with: data) as! [String:Any] { let language = parsedData["Language"] as! [String:Any] print(language) let field = language["Field"] as! [[String:Any]] let name = field[0]["Name"]! print(name) // ==> Test1 } 

En la práctica, es probable que desee un campo específico enterrado en el json. Supongamos que es el campo Name del primer elemento de la matriz de Field . Puede usar una cadena de desenvolvimientos como esta para acceder de forma segura al campo:

 var data = jsonString.data(using: .utf8)! if let json = try? JSONSerialization.jsonObject(with: data) as? [String:Any], let language = json?["Language"] as? [String:Any], let field = language["Field"] as? [[String:Any]], let name = field[0]["Name"] as? String, field.count > 0 { print(name) // ==> Test1 } else { print("bad json - do some recovery") } 

También es posible que desee comprobar Apple Swift Blog Trabajar con JSON en Swift

Empujar JSON en una cuerda manualmente es una pita. ¿Por qué no pones el JSON en un archivo y lo lees?

Swift 3:

 let bundle = Bundle(for: type(of: self)) if let theURL = bundle.url(forResource: "response", withExtension: "json") { do { let data = try Data(contentsOf: theURL) if let parsedData = try? JSONSerialization.jsonObject(with: data) as! [String:Any] { grok(parsedData) } } catch { print(error) } } 
  override func viewDidLoad() { super.viewDidLoad() let url=URL(string:"http://api.androidhive.info/contacts/") do { let allContactsData = try Data(contentsOf: url!) let allContacts = try JSONSerialization.jsonObject(with: allContactsData, options: JSONSerialization.ReadingOptions.allowFragments) as! [String : AnyObject] if let arrJSON = allContacts["contacts"] { for index in 0...arrJSON.count-1 { let aObject = arrJSON[index] as! [String : AnyObject] names.append(aObject["name"] as! String) contacts.append(aObject["email"] as! String) } } print(names) print(contacts) self.tableView.reloadData() } catch { } } 

Usar la librería swiftjson, creo que es una manera muy fácil de analizar

 let count: Int? = json["Field"].array?.count if let ct = count { for index in 0...ct-1{ let number = json ["Field"][index]["number"].string let name = json ["Field"][index]["name"].string 

….

Me gusta esto .

JSON Parsing en swift 4 usando el protocolo decodificable:

Creo un archivo mocky usando su objeto json:

http://www.mocky.io/v2/5a280c282f0000f92c0635e6

Aquí está el código para analizar el JSON:

Creación del modelo:

 import UIKit struct Item : Decodable { // Properties must be the same name as specified in JSON , else it will return nil var Number : String var Name : String } struct Language : Decodable { var Field : [Item] } struct Result : Decodable { var Language : Language } 

Puede usar opcional en el modelo si no está seguro de que algo pueda faltar en el archivo JSON.

Esta es la lógica de análisis:

 class ViewController: UIViewController { let url = "http://www.mocky.io/v2/5a280c282f0000f92c0635e6" private func parseJSON() { guard let url = URL(string: url) else { return } let session = URLSession.shared.dataTask(with: url) { (data, response, error) in guard let data = data else { return } guard let result = try? JSONDecoder().decode(Result.self, from: data) else { return } print("\n\nResult : \(result)") } session.resume() } override func viewDidLoad() { super.viewDidLoad() parseJSON() } } 

La salida de impresión:

  Result : Result(Language: JSON_Parsing.Language(Field: [JSON_Parsing.Item(Number: "976", Name: "Test"), JSON_Parsing.Item(Number: "977", Name: "Test")])) 

Este es el enlace del Proyecto github. Puedes comprobar.

Análisis JSON usando Swift 4 en Simple WAY

  let url = URL(string: "http://mobileappdevelop.co/TIPIT/webservice/get_my_groups?user_id=5") URLSession.shared.dataTask(with:url!, 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:Any] print(json) let posts = json["Field"] as? [[String: Any]] ?? [] print(posts) } catch let error as NSError { print(error) } }).resume() } 
  dict = { message = "Login successfully."; status = 1; "user_details" = ( { dob = "1900-11-18"; email = "rizwan@gmail.com"; gender = male; name = Rizwan; nickname = Shaikh; "profile_pic" = "1483434421.jpeg"; "social_id" = ""; "user_id" = 2; } ); } We can parse above json in swift 3 as var dict2 = dict as! [String : Any] print(dict); let demoStr = dict2["message"] as! String print(demoStr) let demoArray = dict2["user_details"] as! [Any] let demoDict = demoArray[0] as! [String:Any] print(demoDict["dob"]!)