Leer en un archivo JSON usando Swift

206

Realmente estoy luchando por tratar de leer un archivo JSON en Swift para poder jugar con él. He pasado la mayor parte de 2 días volviendo a buscar y probando diferentes métodos, pero todavía no he tenido suerte, así que me he registrado en StackOverFlow para ver si alguien puede señalarme en 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 en los documentos directamente y accedo 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 puede darme 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

Krivvenz
fuente
1
use el parámetro de error ...
Matthias Bauch
2
Por favor, publique el código compilable real. Tal como está ahora, pathsolo es visible en su ifalcance y no está resuelto cuando lo usa NSData(contentsOfFile, options, error); También tiene errores tipográficos en los nombres de enumeración.
Kreiri
1
Mi API está completamente actualizada para Swift 3: github.com/borchero/WebParsing
borchero
esta es la clave -> "valores": "% LOAD VALUE FROM tmclass.json file%" y necesito analizar otro JSON del archivo, ¿cómo puedo lograr esto en SWIFT?
Mayur Shinde

Respuestas:

288

Sigue 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 de la persona clave. Iterar a través 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
      }
}
Abhishek
fuente
44
Sería más útil si explicara por qué / cómo esto resuelve el problema descrito en la pregunta, en lugar de simplemente presentar un montón de código.
Martin R
Hola Abhishek: gracias por tu respuesta, pero todavía no funciona. Eso hace que la aplicación se bloquee con el siguiente error: 2014-06-25 16: 02: 04.146 H & S Capture [4937: 131932] *** Finalización de la aplicación debido a la excepción no detectada 'NSInvalidArgumentException', razón: '*** - [_NSPlaceholderData initWithContentsOfFile: opciones: error:]: argumento de archivo nulo '*** Pila de llamadas de primer lanzamiento: ¿Alguna idea de por qué es esto? Para las opciones de jsonData: puse (ruta, opciones: NSDataReadingOptions.DataReadingMappedIfSafe, error: nil)
Krivvenz
Su ruta de archivo no es correcta. En realidad, no hay un archivo llamado test.json en la ruta especificada por usted. Verifique la ubicación correcta del archivo
Abhishek
15
"let jsonData = NSData (contentsOfFile: ruta!)" en lugar de "let jsonData = NSData.dataWithContentsOfFile (ruta, opciones: .DataReadingMappedIfSafe, error: nil)"
tong
77
Sin embargo, es mejor usar las declaraciones de guardia más en lugar de esta pirámide de la fatalidad.
Zonily Jame
140

Si alguien está buscando SwiftyJSON Respuesta:
Actualización:
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.")
}
Aks
fuente
2
¡Esto me convirtió en JSON y Carthage! gracias :)
Paul Wand
Lo usé solo para descubrir que carece de mapeo de objetos, la próxima vez probaré una biblioteca diferente
Elazaron
Para evitar el error de copiar y pegar en swift 3: NSData y NSError se convirtieron en Datos y Error.
selva
Probé
(!) Desde MacOS 10.6 / iOS 4 hay una API url(forResourcede (NS)Bundleevitar el paso adicional para crear la URL
Vadian
102

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
}
Yarlg
fuente
9
Esto debe trasladarse a la nueva función de documentación o marcarse como la respuesta correcta.
sistema
24

Xcode 8 Swift 3 lee json de 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 {}
    }
ben
fuente
14

Nombres actualizados para Swift 3.0

Sobre la base de 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
}
Nick Graham
fuente
12

Simplificando el ejemplo proporcionado por Peter Kreinz. Funciona con Swift 4.2.

La función de extensión:

extension Decodable {
  static func parse(jsonFile: String) -> Self? {
    guard let url = Bundle.main.url(forResource: jsonFile, withExtension: "json"),
          let data = try? Data(contentsOf: url),
          let output = try? JSONDecoder().decode(self, from: data)
        else {
      return nil
    }

    return output
  }
}

El modelo de ejemplo:

struct Service: Decodable {
  let name: String
}

El ejemplo de uso:

/// service.json
/// { "name": "Home & Garden" }

guard let output = Service.parse(jsonFile: "service") else {
// do something if parsing failed
 return
}

// use output if all good

El ejemplo también funcionará con matrices:

/// services.json
/// [ { "name": "Home & Garden" } ]

guard let output = [Service].parse(jsonFile: "services") else {
// do something if parsing failed
 return
}

// use output if all good

Observe cómo no proporcionamos genéricos innecesarios, por lo tanto, no necesitamos emitir el resultado del análisis.

NeverwinterMoon
fuente
10

Respuesta rápida de 2.1 (basada en la de 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 {}
    }
kjm
fuente
10

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
Ashok R
fuente
7

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!
}
Abdulaziz Noor
fuente
7

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)

    }
}
will.fiset
fuente
7
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
}

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

uso 👇🏻

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

Maciej Banasiewicz
fuente
Esto funcionó para mí. Necesitaba codificar una lista de medicamentos de búsqueda en una aplicación. Obtuve el archivo json de la base de datos mySQL. Dejé caer el archivo json en mi proyecto XCODE ejecutándose arriba en viewDidLoad y bam ¡¡Tenía mi diccionario json !!!
Brian
5

Estoy proporcionando otra respuesta porque ninguno de los que están aquí están orientados a cargar el recurso desde el paquete de prueba. Si está consumiendo un servicio remoto que emite JSON y desea realizar una prueba unitaria analizando los resultados sin acceder al servicio real, debe tomar una o más respuestas y colocarlas en archivos en 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.

Robar
fuente
5

Swift 4: prueba mi solución:

test.json

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

RequestCodable.swift

import Foundation

struct RequestCodable:Codable {
    let person:[PersonCodable]
}

PersonCodable.swift

import Foundation

struct PersonCodable:Codable {
    let name:String
    let age:String
    let employed:String
}

Decodable + FromJSON.swift

import Foundation

extension Decodable {

    static func fromJSON<T:Decodable>(_ fileName: String, fileExtension: String="json", bundle: Bundle = .main) throws -> T {
        guard let url = bundle.url(forResource: fileName, withExtension: fileExtension) else {
            throw NSError(domain: NSURLErrorDomain, code: NSURLErrorResourceUnavailable)
        }

        let data = try Data(contentsOf: url)

        return try JSONDecoder().decode(T.self, from: data)
    }
}

Ejemplo:

let result = RequestCodable.fromJSON("test") as RequestCodable?

result?.person.compactMap({ print($0) }) 

/*
PersonCodable(name: "Bob", age: "16", employed: "No")
PersonCodable(name: "Vinny", age: "56", employed: "Yes")
*/
Peter Kreinz
fuente
1
fromJSONLanza su función de extensión, pero en el ejemplo lo llama sin la trypalabra clave. Este código no se compilará.
NeverwinterMoon
Además, fromJSONsi utiliza una extensión Decodable, no utiliza ninguna información del tipo Decodable, sino que proporciona genéricos adicionales (completamente inútiles).
NeverwinterMoon
3

El último swift 3.0 funciona 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
    }
Khushboo
fuente
3

Swift 4 JSONto Classwith Decodable- para aquellos que prefieren las clases

Defina las clases de la siguiente manera:

class People: Decodable {
  var person: [Person]?

  init(fileName : String){
    // url, data and jsonData should not be nil
    guard let url = Bundle.main.url(forResource: fileName, withExtension: "json") else { return }
    guard let data = try? Data(contentsOf: url) else { return }
    guard let jsonData = try? JSONDecoder().decode(People.self, from: data) else { return }

    // assigns the value to [person]
    person = jsonData.person
  }
}

class Person : Decodable {
  var name: String
  var age: String
  var employed: String
}

Uso, bastante abstracto:

let people = People(fileName: "people")
let personArray = people.person

Esto permite que los métodos para tanto Peopley Personclases, variables (atributos) y métodos también se marca como privatesi fuera necesario.

Marco Leong
fuente
3

El siguiente código me funciona. Estoy usando Swift 5

let path = Bundle.main.path(forResource: "yourJSONfileName", ofType: "json")
var jsonData = try! String(contentsOfFile: path!).data(using: .utf8)!

Luego, si su estructura de persona (o clase) es decodificable (y también todas sus propiedades), simplemente puede hacer:

let person = try! JSONDecoder().decode(Person.self, from: jsonData)

Evité todo el código de manejo de errores para que el código sea más legible.

Abraham Simpson
fuente
2

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)
        }
    }
}

ingrese la descripción de la imagen aquí

iAj
fuente
2

Swift 5.1, Xcode 11

Puedes usar esto:


struct Person : Codable {
    let name: String
    let lastName: String
    let age: Int
}

func loadJson(fileName: String) -> Person? {
   let decoder = JSONDecoder()
   guard
        let url = Bundle.main.url(forResource: fileName, withExtension: "json"),
        let data = try? Data(contentsOf: url),
        let person = try? decoder.decode(Person.self, from: data)
   else {
        return nil
   }

   return person
}
Gonzer
fuente
1

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
David Poxon
fuente
¿Estás usando Swift 2.0? Entonces sí, ese sería el caso. Esto fue respondido antes de 2.0.
David Poxon
1

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)
        }
    }
}
anoop4real
fuente
1

Swift 4.1 actualizado Xcode 9.2

if let filePath = Bundle.main.path(forResource: "fileName", ofType: "json"), let data = NSData(contentsOfFile: filePath) {

     do {
      let json = try JSONSerialization.jsonObject(with: data as Data, options: JSONSerialization.ReadingOptions.allowFragments)        
        }
     catch {
                //Handle error
           }
 }
Saranjith
fuente
3
No hay nada nuevo, todo lo contrario: no lo use NSDataen Swift 3+, y no .allowFragmentstiene sentido en este caso.
vadian
1
//change type based on your struct and right JSON file

let quoteData: [DataType] =
    load("file.json")

func load<T: Decodable>(_ filename: String, as type: T.Type = T.self) -> T {
    let data: Data

    guard let file = Bundle.main.url(forResource: filename, withExtension: nil)
        else {
            fatalError("Couldn't find \(filename) in main bundle.")
    }

    do {
        data = try Data(contentsOf: file)
    } catch {
        fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
    }

    do {
        let decoder = JSONDecoder()
        return try decoder.decode(T.self, from: data)
    } catch {
        fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")
    }
}

RANJAN CENIZO
fuente
0

He usado el siguiente código para obtener 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
            }
            . . .
        ]
    }
}
Jayprakash Dubey
fuente
0

También podría recomendar el Tutorial Swift JSON de Ray Wenderlich (que también cubre la increíble alternativa 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, por favor):

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 de Swift y la seguridad de tipos [pero como] parte de Swift 2.0, la guarddeclaración se introdujo para ayudar a deshacerse de las ifdeclaraciones 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 "Hola, Siri, deserialice este JSON para mí en Swift 3.0 con espacios / tabulaciones".

AmitaiB
fuente
0

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
}
Ahmed Safadi
fuente
0

Primero cree un Struc codificable como este:

  struct JuzgadosList : Codable {
    var CP : Int
    var TEL : String
    var LOCAL : String
    var ORGANO : String
    var DIR : String
}

Ahora declara la variable

 var jzdosList = [JuzgadosList]()

Leer desde el directorio principal

func getJsonFromDirectory() {

        if let path = Bundle.main.path(forResource: "juzgados", ofType: "json") {
            do {
                let data = try Data(contentsOf: URL(fileURLWithPath: path), options: .alwaysMapped)
                let jList = try JSONDecoder().decode([JuzgadosList].self, from: data)
                self.jzdosList = jList

                DispatchQueue.main.async() { () -> Void in
                    self.tableView.reloadData()
                }

            } catch let error {
                print("parse error: \(error.localizedDescription)")
            }
        } else {
            print("Invalid filename/path.")
        }
    }

Leer desde la web

func getJsonFromUrl(){

        self.jzdosList.removeAll(keepingCapacity: false)

        print("Internet Connection Available!")

        guard let url = URL(string: "yourURL")  else { return }

        let request = URLRequest(url: url, cachePolicy: URLRequest.CachePolicy.reloadIgnoringLocalCacheData, timeoutInterval: 60.0)
        URLSession.shared.dataTask(with: request) { (data, response, err) in
            guard let data = data else { return }
            do {
                let jList = try JSONDecoder().decode([JuzgadosList].self, from: data)
                self.jzdosList = jList

                DispatchQueue.main.async() { () -> Void in
                    self.tableView.reloadData()
                }
            } catch let jsonErr {
                print("Error serializing json:", jsonErr)
            }
        }.resume()
    }
Oscar Castellon
fuente
0

Usa esta función genérica

func readJSONFromFile<T: Decodable>(fileName: String, type: T.Type) -> T? {
    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(T.self, from: data)
            return jsonData
        } catch {
            print("error:\(error)")
        }
    }
    return nil
}

con esta línea de código:

let model = readJSONFromFile(fileName: "Model", type: Model.self)

para este tipo:

struct Model: Codable {
    let tall: Int
}
Khaled Annajar
fuente