recorrer leer jsonserialization descargar crear con array archivo json xcode swift ios8 nsjsonserialization

jsonserialization - Leer en un archivo JSON usando Swift



recorrer json swift (18)

Realmente estoy luchando con intentar leer un archivo JSON en Swift para poder jugar con él. Pasé la mayor parte de 2 días rebuscando e intentando diferentes métodos, pero aún no tuve suerte, así que me he registrado en StackOverFlow para ver si alguien puede indicarme la dirección correcta ...

Mi archivo JSON se llama test.json y contiene lo siguiente:

{ "person":[ { "name": "Bob", "age": "16", "employed": "No" }, { "name": "Vinny", "age": "56", "employed": "Yes" } ] }

El archivo se almacena directamente en los documentos y accedo al mismo usando el siguiente código:

let file = "test.json" let dirs : String[] = NSSearchPathForDirectoriesInDomains( NSSearchpathDirectory.DocumentDirectory, NSSearchPathDomainMask.AllDomainMask, true) as String[] if (dirs != nil) { let directories: String[] = dirs let dir = directories[0] let path = dir.stringByAppendingPathComponent(file) } var jsonData = NSData(contentsOfFile:path, options: nil, error: nil) println("jsonData /(jsonData)" // This prints what looks to be JSON encoded data. var jsonDict = NSJSONSerialization.JSONObjectWithData(jsonData, options: nil, error: nil) as? NSDictionary println("jsonDict /(jsonDict)") - This prints nil.....

Si alguien me puede dar un empujón en la dirección correcta sobre cómo puedo deserializar el archivo JSON y ponerlo en un objeto Swift accesible, ¡estaré eternamente agradecido!

Saludos cordiales,

Krivvenz.


Swift 3.0, Xcode 8, iOS 10

if let path = Bundle.main.url(forResource: "person", withExtension: "json") { do { let jsonData = try Data(contentsOf: path, options: .mappedIfSafe) do { if let jsonResult = try JSONSerialization.jsonObject(with: jsonData, options: JSONSerialization.ReadingOptions(rawValue: 0)) as? NSDictionary { if let personArray = jsonResult.value(forKey: "person") as? NSArray { for (_, element) in personArray.enumerated() { if let element = element as? NSDictionary { let name = element.value(forKey: "name") as! String let age = element.value(forKey: "age") as! String let employed = element.value(forKey: "employed") as! String print("Name: /(name), age: /(age), employed: /(employed)") } } } } } catch let error as NSError { print("Error: /(error)") } } catch let error as NSError { print("Error: /(error)") } }

Salida:

Name: Bob, age: 16, employed: No Name: Vinny, age: 56, employed: Yes


Aquí está mi solución usando SwiftyJSON

if let path : String = NSBundle.mainBundle().pathForResource("filename", ofType: "json") { if let data = NSData(contentsOfFile: path) { let json = JSON(data: data) } }


Esto funcionó muy bien conmigo

func readjson(fileName: String) -> NSData{ let path = NSBundle.mainBundle().pathForResource(fileName, ofType: "json") let jsonData = NSData(contentsOfMappedFile: path!) return jsonData! }


Esto funcionó para mí con XCode 8.3.3

func fetchPersons(){ if let pathURL = Bundle.main.url(forResource: "Person", withExtension: "json"){ do { let jsonData = try Data(contentsOf: pathURL, options: .mappedIfSafe) let jsonResult = try JSONSerialization.jsonObject(with: jsonData, options: .mutableContainers) as! [String: Any] if let persons = jsonResult["person"] as? [Any]{ print(persons) } }catch(let error){ print (error.localizedDescription) } } }


He usado el código siguiente para buscar JSON del archivo FAQ-data.json presente en el directorio del proyecto.

Estoy implementando en Xcode 7.3 usando Swift.

func fetchJSONContent() { if let path = NSBundle.mainBundle().pathForResource("FAQ-data", ofType: "json") { if let jsonData = NSData(contentsOfFile: path) { do { if let jsonResult: NSDictionary = try NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.MutableContainers) as? NSDictionary { if let responseParameter : NSDictionary = jsonResult["responseParameter"] as? NSDictionary { if let response : NSArray = responseParameter["FAQ"] as? NSArray { responseFAQ = response print("response FAQ : /(response)") } } } } catch { print("Error while parsing: /(error)") } } } } override func viewWillAppear(animated: Bool) { fetchFAQContent() }

Estructura del archivo JSON:

{ "status": "00", "msg": "FAQ List ", "responseParameter": { "FAQ": [ { "question": “Question No.1 here”, "answer": “Answer goes here”, "id": 1 }, { "question": “Question No.2 here”, "answer": “Answer goes here”, "id": 2 } . . . ] } }


Nombres actualizados para Swift 3.0

Basado en la respuesta de Abhishek y la respuesta de Druva

func loadJson(forFilename fileName: String) -> NSDictionary? { if let url = Bundle.main.url(forResource: fileName, withExtension: "json") { if let data = NSData(contentsOf: url) { do { let dictionary = try JSONSerialization.jsonObject(with: data as Data, options: .allowFragments) as? NSDictionary return dictionary } catch { print("Error!! Unable to parse /(fileName).json") } } print("Error!! Unable to load /(fileName).json") } return nil }


Proporciono otra respuesta porque ninguno de los que están aquí está orientado a cargar el recurso del paquete de prueba. Si está consumiendo un servicio remoto que emite JSON y desea probar la unidad analizando los resultados sin acceder al servicio real, debe tomar una o más respuestas y colocarlas en los archivos de la carpeta Pruebas de su proyecto.

func testCanReadTestJSONFile() { let path = NSBundle(forClass: ForecastIOAdapterTests.self).pathForResource("ForecastIOSample", ofType: "json") if let jsonData = NSData(contentsOfFile:path!) { let json = JSON(data: jsonData) if let currentTemperature = json["currently"]["temperature"].double { println("json: /(json)") XCTAssertGreaterThan(currentTemperature, 0) } } }

Esto también usa SwiftyJSON pero la lógica central de obtener el paquete de prueba y cargar el archivo es la respuesta a la pregunta.


SWIFTYJSON VERSIÓN SWIFT 3

func loadJson(fileName: String) -> JSON { var dataPath:JSON! if let path : String = Bundle.main.path(forResource: fileName, ofType: "json") { if let data = NSData(contentsOfFile: path) { dataPath = JSON(data: data as Data) } } return dataPath }


Según la respuesta de Abhishek , para iOS 8 esto sería:

let masterDataUrl: NSURL = NSBundle.mainBundle().URLForResource("masterdata", withExtension: "json")! let jsonData: NSData = NSData(contentsOfURL: masterDataUrl)! let jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(jsonData, options: nil, error: nil) as! NSDictionary var persons : NSArray = jsonResult["person"] as! NSArray


Si alguien está buscando SwiftyJSON responda:
Actualizar:
Para Swift 3/4 :

if let path = Bundle.main.path(forResource: "assets/test", ofType: "json") { do { let data = try Data(contentsOf: URL(fileURLWithPath: path), options: .alwaysMapped) let jsonObj = try JSON(data: data) print("jsonData:/(jsonObj)") } catch let error { print("parse error: /(error.localizedDescription)") } } else { print("Invalid filename/path.") }


Siga el siguiente código:

if let path = NSBundle.mainBundle().pathForResource("test", ofType: "json") { if let jsonData = NSData(contentsOfFile: path, options: .DataReadingMappedIfSafe, error: nil) { if let jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.MutableContainers, error: nil) as? NSDictionary { if let persons : NSArray = jsonResult["person"] as? NSArray { // Do stuff } } } }

La matriz "personas" contendrá todos los datos para la persona clave. Iterar a través de para buscarlo.

Swift 4.0:

if let path = Bundle.main.path(forResource: "test", ofType: "json") { do { let data = try Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe) let jsonResult = try JSONSerialization.jsonObject(with: data, options: .mutableLeaves) if let jsonResult = jsonResult as? Dictionary<String, AnyObject>, let person = jsonResult["person"] as? [Any] { // do stuff } } catch { // handle error } }


Swift 2.1 respuesta (basado en Abhishek):

if let path = NSBundle.mainBundle().pathForResource("test", ofType: "json") { do { let jsonData = try NSData(contentsOfFile: path, options: NSDataReadingOptions.DataReadingMappedIfSafe) do { let jsonResult: NSDictionary = try NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.MutableContainers) as! NSDictionary if let people : [NSDictionary] = jsonResult["person"] as? [NSDictionary] { for person: NSDictionary in people { for (name,value) in person { print("/(name) , /(value)") } } } } catch {} } catch {} }


También podría recomendar el Swift JSON Tutorial de Ray Wenderlich (que también cubre la increíble alternativa de SwiftyJSON, Gloss ). Un extracto (que, por sí solo, no responde completamente al póster, pero el valor agregado de esta respuesta es el enlace, por lo que no hay -1 para eso):

En Objective-C, analizar y deserializar JSON es bastante sencillo:

NSArray *json = [NSJSONSerialization JSONObjectWithData:JSONData options:kNilOptions error:nil]; NSString *age = json[0][@"person"][@"age"]; NSLog(@"Dani''s age is %@", age);

En Swift, analizar y deserializar JSON es un poco más tedioso debido a las opciones opcionales de Swift y la seguridad de tipo [pero como] parte de Swift 2.0, la declaración de guard se introdujo para ayudar a deshacerse de declaraciones if anidadas:

var json: Array! do { json = try NSJSONSerialization.JSONObjectWithData(JSONData, options: NSJSONReadingOptions()) as? Array } catch { print(error) } guard let item = json[0] as? [String: AnyObject], let person = item["person"] as? [String: AnyObject], let age = person["age"] as? Int else { return; } print("Dani''s age is /(age)")

Por supuesto, en XCode 8.x, solo toca dos veces la barra espaciadora y dice "Oye, Siri, deserializa este JSON para mí en Swift 3.0 con espacio / tabulaciones".


Último swift 3.0 trabajando absolutamente

func loadJson(filename fileName: String) -> [String: AnyObject]? { if let url = Bundle.main.url(forResource: fileName, withExtension: "json") { if let data = NSData(contentsOf: url) { do { let object = try JSONSerialization.jsonObject(with: data as Data, options: .allowFragments) if let dictionary = object as? [String: AnyObject] { return dictionary } } catch { print("Error!! Unable to parse /(fileName).json") } } print("Error!! Unable to load /(fileName).json") } return nil }


Actualizado para Swift 3 con la forma más segura

private func readLocalJsonFile() { if let urlPath = Bundle.main.url(forResource: "test", withExtension: "json") { do { let jsonData = try Data(contentsOf: urlPath, options: .mappedIfSafe) if let jsonDict = try JSONSerialization.jsonObject(with: jsonData, options: .mutableContainers) as? [String: AnyObject] { if let personArray = jsonDict["person"] as? [[String: AnyObject]] { for personDict in personArray { for (key, value) in personDict { print(key, value) } print("/n") } } } } catch let jsonError { print(jsonError) } } }


Swift 4 usando Decodable

struct ResponseData: Decodable { var person: [Person] } struct Person : Decodable { var name: String var age: String var employed: String } func loadJson(filename fileName: String) -> [Person]? { if let url = Bundle.main.url(forResource: fileName, withExtension: "json") { do { let data = try Data(contentsOf: url) let decoder = JSONDecoder() let jsonData = try decoder.decode(ResponseData.self, from: data) return jsonData.person } catch { print("error:/(error)") } } return nil }

Swift 3

func loadJson(filename fileName: String) -> [String: AnyObject]? { if let url = Bundle.main.url(forResource: fileName, withExtension: "json") { do { let data = try Data(contentsOf: url) let object = try JSONSerialization.jsonObject(with: data, options: .allowFragments) if let dictionary = object as? [String: AnyObject] { return dictionary } } catch { print("Error!! Unable to parse /(fileName).json") } } return nil }


Xcode 8 Swift 3 lee json desde la actualización del archivo:

if let path = Bundle.main.path(forResource: "userDatabseFakeData", ofType: "json") { do { let jsonData = try NSData(contentsOfFile: path, options: NSData.ReadingOptions.mappedIfSafe) do { let jsonResult: NSDictionary = try JSONSerialization.jsonObject(with: jsonData as Data, options: JSONSerialization.ReadingOptions.mutableContainers) as! NSDictionary if let people : [NSDictionary] = jsonResult["person"] as? [NSDictionary] { for person: NSDictionary in people { for (name,value) in person { print("/(name) , /(value)") } } } } catch {} } catch {} }


fileprivate class BundleTargetingClass {} func loadJSON<T>(name: String) -> T? { guard let filePath = Bundle(for: BundleTargetingClass.self).url(forResource: name, withExtension: "json") else { return nil } guard let jsonData = try? Data(contentsOf: filePath, options: .mappedIfSafe) else { return nil } guard let json = try? JSONSerialization.jsonObject(with: jsonData, options: .allowFragments) else { return nil } return json as? T }

👆🏻 copiar y pegar listo, solución independiente de marco de terceros.

uso 👇🏻

let json:[[String : AnyObject]] = loadJSON(name: "Stations")!