Tengo un archivo JSON, quiero analizar y usar la lista de objetos en la vista de tabla. ¿Alguien puede compartir el código para analizar el archivo JSON rápidamente?
Por ejemplolet jsonData = NSData.dataWithContentsOfFile(filepath, options: .DataReadingMappedIfSafe, error: nil)
Caroline
4
El problema con este enfoque es que terminas con un montón de objetos de base. Es decir, NSString, NSNumber, NSArray, NSDictionary o NSNull. Lo que crea una gran carga de conversión hacia abajo si desea lidiar con Swift nativo escrito más adelante en su código. Especialmente si tiene diccionarios y matrices anidados. ¿Alguien sabe cómo lidiar con esto?
@bubakazouba: Lástima que no pueda rechazar un comentario. Un par de cosas: 1. Caroline ya proporcionó un fragmento para cargar datos desde un archivo (que es lo que OP quería). 2. Su código utiliza codificación ASCII que pierde todos los símbolos Unicode, incluida la compatibilidad con idiomas distintos al inglés.
akashivskyy
43
Realizar la solicitud de API
var request: NSURLRequest = NSURLRequest(URL: url)
var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: false)
Preparándose para la respuesta
Declare una matriz de la siguiente manera
var data: NSMutableData = NSMutableData()
Recibiendo la respuesta
1.
funcconnection(didReceiveResponse: NSURLConnection!, didReceiveResponse response: NSURLResponse!) {
// Received a new request, clear out the data objectself.data = NSMutableData()
}
2.
funcconnection(connection: NSURLConnection!, didReceiveData data: NSData!) {
// Append the received chunk of data to our data objectself.data.appendData(data)
}
3.
funcconnectionDidFinishLoading(connection: NSURLConnection!) {
// Request complete, self.data should now hold the resulting info// Convert the retrieved data in to an object through JSON deserializationvar err: NSErrorvar jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) asNSDictionaryif jsonResult.count>0 && jsonResult["results"].count>0 {
var results: NSArray = jsonResult["results"] asNSArrayself.tableData = results
self.appsTableView.reloadData()
}
}
Cuando NSURLConnectionrecibe una respuesta, podemos esperar que el didReceiveResponsemétodo sea llamado en nuestro nombre. En este punto, simplemente restablecemos nuestros datos diciendo self.data = NSMutableData(), creando un nuevo objeto de datos vacío.
Una vez establecida la conexión, comenzaremos a recibir datos en el método didReceiveData. El argumento de datos que se pasa aquí es de donde proviene toda nuestra jugosa información. Necesitamos aferrarnos a cada fragmento que ingrese, por lo que lo agregamos al objeto self.data que borramos anteriormente.
Finalmente, cuando se realiza la conexión y se han recibido todos los datos, connectionDidFinishLoadingse llama y estamos listos para usar los datos en nuestra aplicación. ¡Hurra!
El connectionDidFinishLoadingmétodo aquí usa la NSJSONSerializationclase para convertir nuestros datos sin procesar en Dictionaryobjetos útiles al deserializar los resultados de su URL.
Con el nuevo xCode 7.3+, es importante agregar su dominio a la lista de excepciones ( ¿Cómo puedo agregar NSAppTransportSecurity a mi archivo info.plist? ), Consulte esta publicación para obtener instrucciones; de lo contrario, obtendrá un error de autoridad de transporte.
Una pregunta sobre su repositorio de Github: ¿cómo ejecuta realmente main.swift? Estoy teniendo problemas para ejecutarlo desde el patio de recreo ya que parece que no puedes referirte a las clases definidas en tu propio proyecto desde el patio de recreo (?!) ¡Gracias!
Janos
He marcado métodos públicos en el último repositorio. Eso hace que el requisito mínimo para Beta4, así que no se olvide de actualizar Xcode antes de intentarlo
dankogai
Ok, gracias, realmente estaba buscando cómo ejecutar exactamente el código de ejemplo. Probé playgroung pero no funcionó porque no pude hacer referencia a la clase JSON (es un problema conocido que no puede referirse a las clases en su proyecto)
Janos
No puedo hacer que funcione :( Esta vez no estoy tratando de usarlo en el patio de recreo, agregué su json.swift a mi proyecto y en otra clase estoy tratando de usarlo. No funciona. Probé el JSON más simple: {"id": "Janos"}, creé el objeto JSON, llamé a su método toString, escupe el contenido del archivo correctamente, sin embargo, cuando llamo a myJson ["id"]. AsString obtengo nil. ¿Qué me estoy perdiendo?
Janos
Estaba tratando de construir un objeto JSON pasando una cadena en el constructor ... He cambiado a cómo lo haces en el ejemplo, ahora funciona de maravilla. La única pregunta es cuál usar ahora, el tuyo o SwiftyJSon :)
Janos
4
Aquí hay un código para realizar las conversiones entre JSON y NSData en Swift 2.0
// Convert from NSData to json objectfuncnsdataToJSON(data: NSData) -> AnyObject? {
do {
returntryNSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers)
} catchlet myJSONError {
print(myJSONError)
}
returnnil
}
// Convert from JSON to nsdatafuncjsonToNSData(json: AnyObject) -> NSData?{
do {
returntryNSJSONSerialization.dataWithJSONObject(json, options: NSJSONWritingOptions.PrettyPrinted)
} catchlet myJSONError {
print(myJSONError)
}
returnnil;
}
En Swift 4+ se recomienda encarecidamente utilizar en Codablelugar de JSONSerialization.
Esto Codableincluye dos protocolos: Decodabley Encodable. Este Decodableprotocolo le permite decodificar Dataen formato JSON a estructuras / clases personalizadas de acuerdo con este protocolo.
Por ejemplo, imagina una situación en la que tenemos este simple Data(matriz de dos objetos)
let data = Data("""
[
{"name":"Steve","age":56},
{"name":"iPhone","age":11}
]
""".utf8)
luego seguir structe implementar el protocoloDecodable
structPerson: Decodable{
let name: Stringlet age: Int
}
ahora puede decodificar su Datamatriz de Personusar JSONDecoderdonde el primer parámetro es conforme al tipo Decodabley este tipo debe Datadecodificarse
do {
let people = tryJSONDecoder().decode([Person].self, from: data)
} catch { print(error) }
... tenga en cuenta que la decodificación debe marcarse con una trypalabra clave ya que, por ejemplo, podría cometer algún error al nombrar y luego su modelo no se puede decodificar correctamente ... por lo que debe ponerlo dentro del bloque do-try-catch
Casos en los que la clave en json es diferente del nombre de la propiedad:
Si la clave está nombrada usando snake_case, puede configurar el decodificador keyDecodingStrategyal convertFromSnakeCaseque cambia la clave de property_namea camelCasepropertyName
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let people = try decoder.decode([Person].self, from: data)
Si necesita un nombre único, puede usar claves de codificación dentro de la estructura / clase donde declara el nombre de la clave
let data = Data("""
{ "userName":"Codable", "age": 1 }
""".utf8)
structPerson: Decodable{
let name: Stringlet age: IntenumCodingKeys: String, CodingKey{
case name = "userName"case age
}
}
También escribí una pequeña biblioteca especializada para el mapeo de la respuesta json en una estructura de objeto. Estoy usando internamente la biblioteca json-swift de David Owens. Quizás sea útil para otra persona.
Luego, para mapear realmente los objetos de la respuesta JSON, solo tiene que pasar los datos a la clase EmployeeContainer como parámetro en el constructor. Crea automáticamente su modelo de datos.
var baseWebservice:BaseWebservice = BaseWebservice();
var urlToJSON = "http://prine.ch/employees.json"var callbackJSON = {(status:Int, employeeContainer:EmployeeContainer) -> () infor employee in employeeContainer.employees {
println("Firstname: \(employee.firstname) Lastname: \(employee.lastname) age: \(employee.age)")
}
}
baseWebservice.get(urlToJSON, callback:callbackJSON)
La salida de la consola tiene el siguiente aspecto:
Firstname: JohnLastname: Doe age: 26Firstname: AnnaLastname: Smith age: 30Firstname: PeterLastname: Jones age: 45
Perdona mi ignorancia. ¿Cuáles son las ventajas de usar su biblioteca sobre una como SwiftyJSON?
Levi Roberts
6
Inicialmente, construí esto porque no me gustaba la idea de operadores / símbolos de piratería de idiomas. Además, lo construí para familiarizarme con Swift. Por curiosidad, ejecuté un punto de referencia y descubrí que SwiftyJSON tiene una velocidad superior (~ 2 a 7 veces más rápida). He actualizado el archivo README del repositorio para admitirlo.
Mike Rapadas
Gracias por tu respuesta.
Levi Roberts
¿Puede mostrar un ejemplo de cómo cargaría una matriz de datos desde JSON (varios elementos esencialmente con un bucle, etc.)
Joseph Astrahan
2
Analizar JSON en Swift es un trabajo excelente para la generación de código. Creé una herramienta en http://www.guideluxe.com/JsonToSwift para hacer precisamente eso.
Usted proporciona un objeto JSON de muestra con un nombre de clase y la herramienta generará una clase Swift correspondiente, así como cualquier clase Swift subsidiaria necesaria, para representar la estructura implícita en el JSON de muestra. También se incluyen los métodos de clase utilizados para poblar objetos Swift, incluido uno que utiliza el método NSJSONSerialization.JSONObjectWithData. Se proporcionan las asignaciones necesarias de los objetos NSArray y NSDictionary.
A partir del código generado, solo necesita proporcionar un objeto NSData que contenga JSON que coincida con la muestra proporcionada a la herramienta.
Lo siento, estaba pegando la URL JSON directamente, funciona bien pegando la respuesta JSON. Sin embargo, sería fabuloso tener la URL pegada directamente. Pero trabajo brillante para esta utilidad. Gracias.
ioopl
La herramienta que ha creado es simplemente asombrosa. Estoy usando esta herramienta desde los últimos 6 meses. Pero de repente, desde los últimos 3 días, no se puede acceder a su sitio web y el navegador responde con este mensaje "No se puede acceder a este sitio". Entonces, ¿cuál es la razón detrás de esto?
Respuestas:
No podría ser más simple:
import Foundation let jsonData: Data = /* get your json data */ let jsonDict = try JSONSerialization.jsonObject(with: jsonData) as? NSDictionary
Dicho esto, recomiendo encarecidamente utilizar las API codificables introducidas en Swift 4.
fuente
let jsonData = NSData.dataWithContentsOfFile(filepath, options: .DataReadingMappedIfSafe, error: nil)
NSData(contentsOfFile: path)
. Ver developer.apple.com/library/ios/documentation/Cocoa/Reference/… :Realizar la solicitud de API
var request: NSURLRequest = NSURLRequest(URL: url) var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: false)
Preparándose para la respuesta
Declare una matriz de la siguiente manera
var data: NSMutableData = NSMutableData()
Recibiendo la respuesta
1.
func connection(didReceiveResponse: NSURLConnection!, didReceiveResponse response: NSURLResponse!) { // Received a new request, clear out the data object self.data = NSMutableData() }
2.
func connection(connection: NSURLConnection!, didReceiveData data: NSData!) { // Append the received chunk of data to our data object self.data.appendData(data) }
3.
func connectionDidFinishLoading(connection: NSURLConnection!) { // Request complete, self.data should now hold the resulting info // Convert the retrieved data in to an object through JSON deserialization var err: NSError var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary if jsonResult.count>0 && jsonResult["results"].count>0 { var results: NSArray = jsonResult["results"] as NSArray self.tableData = results self.appsTableView.reloadData() } }
Cuando
NSURLConnection
recibe una respuesta, podemos esperar que eldidReceiveResponse
método sea llamado en nuestro nombre. En este punto, simplemente restablecemos nuestros datos diciendoself.data = NSMutableData()
, creando un nuevo objeto de datos vacío.Una vez establecida la conexión, comenzaremos a recibir datos en el método
didReceiveData
. El argumento de datos que se pasa aquí es de donde proviene toda nuestra jugosa información. Necesitamos aferrarnos a cada fragmento que ingrese, por lo que lo agregamos al objeto self.data que borramos anteriormente.Finalmente, cuando se realiza la conexión y se han recibido todos los datos,
connectionDidFinishLoading
se llama y estamos listos para usar los datos en nuestra aplicación. ¡Hurra!El
connectionDidFinishLoading
método aquí usa laNSJSONSerialization
clase para convertir nuestros datos sin procesar enDictionary
objetos útiles al deserializar los resultados de su URL.fuente
Acabo de escribir una clase llamada JSON, que hace que el manejo de JSON en Swift sea tan fácil como el objeto JSON en ES5.
Convierte tu objeto rápido en JSON así:
let obj:[String:AnyObject] = [ "array": [JSON.null, false, 0, "",[],[:]], "object":[ "null": JSON.null, "bool": true, "int": 42, "double": 3.141592653589793, "string": "a α\t弾\n𪚲", "array": [], "object": [:] ], "url":"http://blog.livedoor.com/dankogai/" ] let json = JSON(obj) json.toString()
... o cuerda ...
let json = JSON.parse("{\"array\":[...}")
... o URL.
let json = JSON.fromURL("http://api.dan.co.jp/jsonenv") Tree Traversal
Simplemente atraviesa elementos a través del subíndice:
json["object"]["null"].asNull // NSNull() // ... json["object"]["string"].asString // "a α\t弾\n𪚲" json["array"][0].asNull // NSNull() json["array"][1].asBool // false // ...
Al igual que SwiftyJSON , no se preocupa si la entrada con subíndice no existe.
if let b = json["noexistent"][1234567890]["entry"].asBool { // .... } else { let e = json["noexistent"][1234567890]["entry"].asError println(e) }
Si está cansado de los subíndices, agregue su esquema así:
//// schema by subclassing class MyJSON : JSON { init(_ obj:AnyObject){ super.init(obj) } init(_ json:JSON) { super.init(json) } var null :NSNull? { return self["null"].asNull } var bool :Bool? { return self["bool"].asBool } var int :Int? { return self["int"].asInt } var double:Double? { return self["double"].asDouble } var string:String? { return self["string"].asString } }
Y tu vas:
let myjson = MyJSON(obj) myjson.object.null myjson.object.bool myjson.object.int myjson.object.double myjson.object.string // ...
Espero que te guste.
Con el nuevo xCode 7.3+, es importante agregar su dominio a la lista de excepciones ( ¿Cómo puedo agregar NSAppTransportSecurity a mi archivo info.plist? ), Consulte esta publicación para obtener instrucciones; de lo contrario, obtendrá un error de autoridad de transporte.
fuente
Aquí hay un código para realizar las conversiones entre JSON y NSData en Swift 2.0
// Convert from NSData to json object func nsdataToJSON(data: NSData) -> AnyObject? { do { return try NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers) } catch let myJSONError { print(myJSONError) } return nil } // Convert from JSON to nsdata func jsonToNSData(json: AnyObject) -> NSData?{ do { return try NSJSONSerialization.dataWithJSONObject(json, options: NSJSONWritingOptions.PrettyPrinted) } catch let myJSONError { print(myJSONError) } return nil; }
fuente
Codificable
En Swift 4+ se recomienda encarecidamente utilizar en
Codable
lugar deJSONSerialization
.Esto
Codable
incluye dos protocolos:Decodable
yEncodable
. EsteDecodable
protocolo le permite decodificarData
en formato JSON a estructuras / clases personalizadas de acuerdo con este protocolo.Por ejemplo, imagina una situación en la que tenemos este simple
Data
(matriz de dos objetos)let data = Data(""" [ {"name":"Steve","age":56}, {"name":"iPhone","age":11} ] """.utf8)
luego seguir
struct
e implementar el protocoloDecodable
struct Person: Decodable { let name: String let age: Int }
ahora puede decodificar su
Data
matriz dePerson
usarJSONDecoder
donde el primer parámetro es conforme al tipoDecodable
y este tipo debeData
decodificarsedo { let people = try JSONDecoder().decode([Person].self, from: data) } catch { print(error) }
... tenga en cuenta que la decodificación debe marcarse con una
try
palabra clave ya que, por ejemplo, podría cometer algún error al nombrar y luego su modelo no se puede decodificar correctamente ... por lo que debe ponerlo dentro del bloque do-try-catchCasos en los que la clave en json es diferente del nombre de la propiedad:
Si la clave está nombrada usando snake_case, puede configurar el decodificador
keyDecodingStrategy
alconvertFromSnakeCase
que cambia la clave deproperty_name
a camelCasepropertyName
let decoder = JSONDecoder() decoder.keyDecodingStrategy = .convertFromSnakeCase let people = try decoder.decode([Person].self, from: data)
Si necesita un nombre único, puede usar claves de codificación dentro de la estructura / clase donde declara el nombre de la clave
let data = Data(""" { "userName":"Codable", "age": 1 } """.utf8) struct Person: Decodable { let name: String let age: Int enum CodingKeys: String, CodingKey { case name = "userName" case age } }
fuente
También escribí una pequeña biblioteca especializada para el mapeo de la respuesta json en una estructura de objeto. Estoy usando internamente la biblioteca json-swift de David Owens. Quizás sea útil para otra persona.
https://github.com/prine/ROJSONParser
Ejemplo Employees.json
{ "employees": [ { "firstName": "John", "lastName": "Doe", "age": 26 }, { "firstName": "Anna", "lastName": "Smith", "age": 30 }, { "firstName": "Peter", "lastName": "Jones", "age": 45 }] }
Como siguiente paso, debe crear su modelo de datos (EmplyoeeContainer y Employee).
Employee.swift
class Employee : ROJSONObject { required init() { super.init(); } required init(jsonData:AnyObject) { super.init(jsonData: jsonData) } var firstname:String { return Value<String>.get(self, key: "firstName") } var lastname:String { return Value<String>.get(self, key: "lastName") } var age:Int { return Value<Int>.get(self, key: "age") } }
EmployeeContainer.swift
class EmployeeContainer : ROJSONObject { required init() { super.init(); } required init(jsonData:AnyObject) { super.init(jsonData: jsonData) } lazy var employees:[Employee] = { return Value<[Employee]>.getArray(self, key: "employees") as [Employee] }() }
Luego, para mapear realmente los objetos de la respuesta JSON, solo tiene que pasar los datos a la clase EmployeeContainer como parámetro en el constructor. Crea automáticamente su modelo de datos.
var baseWebservice:BaseWebservice = BaseWebservice(); var urlToJSON = "http://prine.ch/employees.json" var callbackJSON = {(status:Int, employeeContainer:EmployeeContainer) -> () in for employee in employeeContainer.employees { println("Firstname: \(employee.firstname) Lastname: \(employee.lastname) age: \(employee.age)") } } baseWebservice.get(urlToJSON, callback:callbackJSON)
La salida de la consola tiene el siguiente aspecto:
Firstname: John Lastname: Doe age: 26 Firstname: Anna Lastname: Smith age: 30 Firstname: Peter Lastname: Jones age: 45
fuente
SwiftJSONParse : Analiza JSON como un rudo
¡Muy simple y fácil de leer!
Ejemplo: obtener el valor
"mrap"
denicknames
como una cadena de esta respuesta JSON{ "other": { "nicknames": ["mrap", "Mikee"] }
Toma sus datos json
NSData
tal como están, sin necesidad de preprocesarlos.let parser = JSONParser(jsonData) if let handle = parser.getString("other.nicknames[0]") { // that's it! }
Descargo de responsabilidad: hice esto y espero que ayude a todos. ¡Siéntete libre de mejorarlo!
fuente
Analizar JSON en Swift es un trabajo excelente para la generación de código. Creé una herramienta en http://www.guideluxe.com/JsonToSwift para hacer precisamente eso.
Usted proporciona un objeto JSON de muestra con un nombre de clase y la herramienta generará una clase Swift correspondiente, así como cualquier clase Swift subsidiaria necesaria, para representar la estructura implícita en el JSON de muestra. También se incluyen los métodos de clase utilizados para poblar objetos Swift, incluido uno que utiliza el método NSJSONSerialization.JSONObjectWithData. Se proporcionan las asignaciones necesarias de los objetos NSArray y NSDictionary.
A partir del código generado, solo necesita proporcionar un objeto NSData que contenga JSON que coincida con la muestra proporcionada a la herramienta.
Aparte de Foundation, no hay dependencias.
Mi trabajo se inspiró en http://json2csharp.com/ , que es muy útil para proyectos .NET.
A continuación, se explica cómo crear un objeto NSData a partir de un archivo JSON.
let fileUrl: NSURL = NSBundle.mainBundle().URLForResource("JsonFile", withExtension: "json")! let jsonData: NSData = NSData(contentsOfURL: fileUrl)!
fuente
Nota: si está buscando esto, también existe una alta probabilidad de que no sepa cómo instalar
swifty
. Siga las instrucciones aquí .sudo gem install cocoapods cd ~/Path/To/Folder/Containing/ShowTracker
Luego ingrese este comando:
pod init
Esto creará un valor predeterminado
Podfile
para su proyecto. AquíPodfile
es donde define las dependencias en las que se basa su proyecto.Escriba este comando para abrir
Podfile
usandoXcode
para editar:open -a Xcode Podfile
Agregue el
Swifty
en el podfileplatform :ios, '8.0' use_frameworks! target 'MyApp' do pod 'SwiftyJSON', '~> X.X.X' end
var mURL = NSURL(string: "http://api.openweathermap.org/data/2.5/weather?q=London,uk&units=metric") if mURL == nil{ println("You are stupid") return } var request = NSURLRequest(URL: mURL!) NSURLConnection.sendAsynchronousRequest( request, queue: NSOperationQueue.mainQueue(), completionHandler:{ ( response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in if data != nil { var mJSON = JSON(data: data!) if let current_conditions = mJSON["weather"][0]["description"].string { println("Current conditions: " + current_conditions) } else { println("MORON!") } if let current_temperature = mJSON["main"]["temp"].double { println("Temperature: "+ String(format:"%.f", current_temperature) + "°C" } else { println("MORON!") } } })
fuente
Todo el controlador de vista que muestra datos en la vista de recopilación utilizando dos métodos de json parsig
@IBOutlet weak var imagecollectionview: UICollectionView! lazy var data = NSMutableData() var dictdata : NSMutableDictionary = NSMutableDictionary() override func viewDidLoad() { super.viewDidLoad() startConnection() startNewConnection() // Do any additional setup after loading the view, typically from a nib. } func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return dictdata.count } func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCellWithReuseIdentifier("CustomcellCollectionViewCell", forIndexPath: indexPath) as! CustomcellCollectionViewCell cell.name.text = dictdata.valueForKey("Data")?.valueForKey("location") as? String let url = NSURL(string: (dictdata.valueForKey("Data")?.valueForKey("avatar_url") as? String)! ) LazyImage.showForImageView(cell.image, url:"URL return cell } func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize { let kWhateverHeightYouWant = 100 return CGSizeMake(self.view.bounds.size.width/2, CGFloat(kWhateverHeightYouWant)) } func startNewConnection() { let url: URL = URL(string: "YOUR URL" as String)! let session = URLSession.shared let request = NSMutableURLRequest(url: url as URL) request.httpMethod = "GET" //set the get or post according to your request // request.cachePolicy = NSURLRequest.CachePolicy.ReloadIgnoringCacheData request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData let task = session.dataTask(with: request as URLRequest) { ( data, response, error) in guard let _:NSData = data as NSData?, let _:URLResponse = response, error == nil else { print("error") return } let jsonString = NSString(data: data!, encoding:String.Encoding.utf8.rawValue) as! String } task.resume() } func startConnection(){ let urlPath: String = "your URL" let url: NSURL = NSURL(string: urlPath)! var request: NSURLRequest = NSURLRequest(URL: url) var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: false)! connection.start() } func connection(connection: NSURLConnection!, didReceiveData data: NSData!){ self.data.appendData(data) } func buttonAction(sender: UIButton!){ startConnection() } func connectionDidFinishLoading(connection: NSURLConnection!) { do { let JSON = try NSJSONSerialization.JSONObjectWithData(self.data, options:NSJSONReadingOptions(rawValue: 0)) guard let JSONDictionary :NSDictionary = JSON as? NSDictionary else { print("Not a Dictionary") // put in function return } print("JSONDictionary! \(JSONDictionary)") dictdata.setObject(JSONDictionary, forKey: "Data") imagecollectionview.reloadData() } catch let JSONError as NSError { print("\(JSONError)") } }
fuente
Usando el marco ObjectMapper
if let path = Bundle(for: BPPView.self).path(forResource: jsonFileName, ofType: "json") { do { let data = try Data(contentsOf: URL(fileURLWithPath: path), options: NSData.ReadingOptions.mappedIfSafe) let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) self.levels = Mapper<Level>().mapArray(JSONArray: (json as! [[String : Any]]))! print(levels.count) } catch let error as NSError { print(error.localizedDescription) } } else { print("Invalid filename/path.") }
Antes, debe preparar el conjunto de objetos mapeables apropiados para analizarlos
import UIKit import ObjectMapper class Level: Mappable { var levelName = "" var levelItems = [LevelItem]() required init?(map: Map) { } // Mappable func mapping(map: Map) { levelName <- map["levelName"] levelItems <- map["levelItems"] }
import UIKit import ObjectMapper class LevelItem: Mappable { var frontBackSide = BPPFrontBack.Undefined var fullImageName = "" var fullImageSelectedName = "" var bodyParts = [BodyPart]() required init?(map: Map) { } // Mappable func mapping(map: Map) { frontBackSide <- map["frontBackSide"] fullImageName <- map["fullImageName"] fullImageSelectedName <- map["fullImageSelectedName"] bodyParts <- map["bodyParts"] }}
fuente
Swift 3
let parsedResult: [String: AnyObject] do { parsedResult = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [String:AnyObject] } catch { // Display an error or return or whatever }
datos: es el tipo de datos (estructura) (es decir, devuelto por alguna respuesta del servidor)
fuente
Este analizador usa genéricos para convertir JSON a tipos Swift, lo que reduce el código que necesita escribir.
https://github.com/evgenyneu/JsonSwiftson
struct Person { let name: String? let age: Int? } let mapper = JsonSwiftson(json: "{ \"name\": \"Peter\", \"age\": 41 }") let person: Person? = Person( name: mapper["name"].map(), age: mapper["age"].map() )
fuente
A continuación se muestra un ejemplo de Swift Playground:
import UIKit let jsonString = "{\"name\": \"John Doe\", \"phone\":123456}" let data = jsonString.data(using: .utf8) var jsonObject: Any do { jsonObject = try JSONSerialization.jsonObject(with: data!) as Any if let obj = jsonObject as? NSDictionary { print(obj["name"]) } } catch { print("error") }
fuente
Rápido 4
Crear un proyecto
Diseño de StoryBoard con un botón y una UITableview
Crear TableViewCell VC
En la acción del botón Inserte los siguientes códigos
Recuerde este código para obtener una matriz de datos en una API
import UIKit class ViewController3: UIViewController,UITableViewDelegate,UITableViewDataSource { @IBOutlet var tableView: UITableView! var displayDatasssss = [displyDataClass]() override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } func numberOfSections(in tableView: UITableView) -> Int { return 1 } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return displayDatasssss.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell1") as! TableViewCell1 cell.label1.text = displayDatasssss[indexPath.row].email return cell } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } @IBAction func gettt(_ sender: Any) { let url = "http://jsonplaceholder.typicode.com/users" var request = URLRequest(url: URL(string: url)!) request.httpMethod = "GET" let configuration = URLSessionConfiguration.default let session = URLSession(configuration: configuration, delegate: nil, delegateQueue: OperationQueue.main) let task = session.dataTask(with: request){(data, response,error)in if (error != nil){ print("Error") } else{ do{ // Array of Data let fetchData = try JSONSerialization.jsonObject(with: data!, options: .mutableLeaves) as! NSArray for eachData in fetchData { let eachdataitem = eachData as! [String : Any] let name = eachdataitem["name"]as! String let username = eachdataitem["username"]as! String let email = eachdataitem["email"]as! String self.displayDatasssss.append(displyDataClass(name: name, username: username,email : email)) } self.tableView.reloadData() } catch{ print("Error 2") } } } task.resume() } } class displyDataClass { var name : String var username : String var email : String init(name : String,username : String,email :String) { self.name = name self.username = username self.email = email } }
Esto es para obtener datos del diccionario
import UIKit class ViewController3: UIViewController,UITableViewDelegate,UITableViewDataSource { @IBOutlet var tableView: UITableView! var displayDatasssss = [displyDataClass]() override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } func numberOfSections(in tableView: UITableView) -> Int { return 1 } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return displayDatasssss.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell1") as! TableViewCell1 cell.label1.text = displayDatasssss[indexPath.row].email return cell } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } @IBAction func gettt(_ sender: Any) { let url = "http://jsonplaceholder.typicode.com/users/1" var request = URLRequest(url: URL(string: url)!) request.httpMethod = "GET" let configuration = URLSessionConfiguration.default let session = URLSession(configuration: configuration, delegate: nil, delegateQueue: OperationQueue.main) let task = session.dataTask(with: request){(data, response,error)in if (error != nil){ print("Error") } else{ do{ //Dictionary data Fetching let fetchData = try JSONSerialization.jsonObject(with: data!, options: .mutableLeaves) as! [String: AnyObject] let name = fetchData["name"]as! String let username = fetchData["username"]as! String let email = fetchData["email"]as! String self.displayDatasssss.append(displyDataClass(name: name, username: username,email : email)) self.tableView.reloadData() } catch{ print("Error 2") } } } task.resume() } } class displyDataClass { var name : String var username : String var email : String init(name : String,username : String,email :String) { self.name = name self.username = username self.email = email } }
fuente
Ejemplo de solicitud de API de Swift 4
Hacer uso de
JSONDecoder().decode
Vea este video Análisis JSON con Swift 4
struct Post: Codable { let userId: Int let id: Int let title: String let body: String }
URLSession.shared.dataTask(with: URL(string: "https://jsonplaceholder.typicode.com/posts")!) { (data, response, error) in guard let response = response as? HTTPURLResponse else { print("HTTPURLResponse error") return } guard 200 ... 299 ~= response.statusCode else { print("Status Code error \(response.statusCode)") return } guard let data = data else { print("No Data") return } let posts = try! JSONDecoder().decode([Post].self, from: data) print(posts) }.resume()
fuente
Swift 2 iOS 9
let miadata = NSData(contentsOfURL: NSURL(string: "https://myWeb....php")!) do{ let MyData = try NSJSONSerialization.JSONObjectWithData(miadata!, options: NSJSONReadingOptions.MutableContainers) as? NSArray print(".........\(MyData)") } catch let error as NSError{ // error.description print(error.description) }
fuente