Lecture dans un fichier JSON à l'aide de Swift

206

J'ai vraiment du mal à essayer de lire un fichier JSON dans Swift afin de pouvoir jouer avec. J'ai passé la majeure partie de 2 jours à rechercher et à essayer différentes méthodes, mais je n'ai pas encore de chance, je me suis donc inscrit à StackOverFlow pour voir si quelqu'un peut m'orienter dans la bonne direction .....

Mon fichier JSON s'appelle test.json et contient les éléments suivants:

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

Le fichier est stocké directement dans les documents et j'y accède en utilisant le code suivant:

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 quelqu'un peut simplement me donner un coup de pouce dans la bonne direction sur la façon dont je peux désérialiser le fichier JSON et le placer dans un objet Swift accessible, je serai éternellement reconnaissant!

Sincères amitiés,

Krivvenz.

Krivvenz
la source
1
utiliser le paramètre d'erreur ...
Matthias Bauch
2
Veuillez publier le code réel et compilable. Tel qu'il est maintenant, pathn'est visible que dans la ifportée et n'est pas résolu lorsque vous l'utilisez dans NSData(contentsOfFile, options, error); vous avez également des fautes de frappe dans les noms d'énumération.
Kreiri
1
Mon API est entièrement mise à jour pour Swift 3: github.com/borchero/WebParsing
borchero
c'est la clé -> "valeurs": "% LOAD VALUE FROM tmclass.json file%" et j'ai besoin d'analyser un autre JSON du fichier alors comment puis-je y parvenir dans SWIFT?
Mayur Shinde

Réponses:

288

Suivez le code ci-dessous:

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

Le tableau "personnes" contiendra toutes les données pour la personne clé. Itérer à travers pour le récupérer.

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
la source
4
Il serait plus utile si vous expliquez pourquoi / comment cela résout le problème décrit dans la question, au lieu de simplement présenter un tas de code.
Martin R
Salut Abhishek - Merci pour votre réponse mais cela ne fonctionne toujours pas. Cela provoque le blocage de l'application avec l'erreur ci-dessous: 2014-06-25 16: 02: 04.146 H & S Capture [4937: 131932] *** Arrêt de l'application en raison d'une exception non interceptée 'NSInvalidArgumentException', raison: '*** - [_NSPlaceholderData initWithContentsOfFile: options: erreur:]: argument de fichier nul '*** Pile du premier appel: Avez-vous des idées sur la raison? Pour les options jsonData: je mets (chemin, options: NSDataReadingOptions.DataReadingMappedIfSafe, erreur: néant)
Krivvenz
Votre chemin de fichier n'est pas correct. En fait, il n'y a pas de fichier nommé test.json au chemin spécifié par vous. Veuillez vérifier l'emplacement correct du fichier
Abhishek
15
"let jsonData = NSData (contentsOfFile: path!)" au lieu de "let jsonData = NSData.dataWithContentsOfFile (path, options: .DataReadingMappedIfSafe, erreur: nil)"
tong
7
Il vaut mieux utiliser les déclarations de garde d'autre ici au lieu de cette pyramide de malheur.
Zonily Jame
140

Si quelqu'un cherche SwiftyJSON Réponse:
Mise à jour:
Pour 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
la source
2
cela m'a transformé en swiftyJSON et carthage! merci :)
Paul Wand
Je ne l'ai utilisé que pour découvrir qu'il manque un mappage d'objets, je vais essayer une autre bibliothèque la prochaine fois
Elazaron
Pour éviter l'erreur de copier-coller dans swift 3: NSData et NSError sont devenus Data and Error.
selva
J'ai essayé quelques méthodes différentes et cela a fonctionné le mieux pour moi dans Swift 3
crobicha
(!) Depuis Mac OS 10.6 / iOS 4 il y a une API url(forResourcedans (NS)Bundlepour éviter l'étape supplémentaire pour créer l'URL
Vadian
102

Swift 4 utilisant 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
la source
9
Cela doit être déplacé vers la nouvelle fonctionnalité de documentation, ou marqué comme la bonne réponse.
système
24

Xcode 8 Swift 3 lit json depuis la mise à jour du fichier:

    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
la source
14

Noms mis à jour pour Swift 3.0

Sur la base de la réponse de Abhishek et la réponse 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
la source
12

Simplifier l'exemple fourni par Peter Kreinz. Fonctionne avec Swift 4.2.

La fonction d'extension:

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

Le modèle d'exemple:

struct Service: Decodable {
  let name: String
}

L'exemple d'utilisation:

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

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

// use output if all good

L'exemple fonctionnera également avec les tableaux:

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

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

// use output if all good

Notez que nous ne fournissons pas de génériques inutiles, nous n'avons donc pas besoin de lancer le résultat de l'analyse.

NeverwinterMoon
la source
10

Réponse de Swift 2.1 (basée sur 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
la source
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)")
        }
    }

Production:

Name: Bob,  age: 16, employed: No
Name: Vinny,  age: 56, employed: Yes
Ashok R
la source
7

Cela a très bien fonctionné avec moi

func readjson(fileName: String) -> NSData{

    let path = NSBundle.mainBundle().pathForResource(fileName, ofType: "json")
    let jsonData = NSData(contentsOfMappedFile: path!)

    return jsonData!
}
Abdulaziz Noor
la source
7

Voici ma solution en utilisant SwiftyJSON

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

        let json = JSON(data: data)

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

👆🏻 Prêt à copier-coller, solution indépendante du cadre tiers.

utilisation 👇🏻

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

Maciej Banasiewicz
la source
cela a fonctionné pour moi. J'avais besoin de coder en dur une liste consultable de médicaments dans une application. J'ai obtenu le fichier json de la base de données mySQL. J'ai déposé le fichier json dans mon projet XCODE en cours d'exécution ci-dessus dans viewDidLoad et bam j'avais mon dictionnaire json !!!
Brian
5

Je fournis une autre réponse car aucune de celles-ci n'est destinée à charger la ressource à partir du bundle de test. Si vous consommez un service distant qui émet du JSON et que vous souhaitez effectuer un test unitaire en analysant les résultats sans atteindre le service réel, vous prenez une ou plusieurs réponses et les placez dans des fichiers dans le dossier Tests de votre projet.

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

Cela utilise également SwiftyJSON mais la logique de base pour obtenir le bundle de test et charger le fichier est la réponse à la question.

Rob
la source
5

Swift 4: Essayez ma solution:

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
}

Décodable + 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)
    }
}

Exemple:

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
la source
1
Votre fromJSONfonction d'extension lance, mais dans l'exemple que vous appelez sans le trymot - clé. Ce code ne se compilera pas.
NeverwinterMoon
De plus, pour fromJSONvous utilisez une extension décodable, vous n'utilisez cependant aucune information du type décodable mais fournissez des génériques supplémentaires (complètement inutiles).
NeverwinterMoon
3

La dernière swift 3.0 fonctionne parfaitement

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
la source
3

Swift 4 JSONà Classwith Decodable- pour ceux qui préfèrent les cours

Définissez les classes comme suit:

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
}

Utilisation, assez abstraite:

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

Ceci permet à des méthodes pour les deux Peopleet les Personclasses, les variables (attributs) et les méthodes peuvent également marquées comme privatesi nécessaire.

Marco Leong
la source
3

Le code suivant fonctionne pour moi. J'utilise Swift 5

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

Ensuite, si votre structure de personne (ou classe) est décodable (et également toutes ses propriétés), vous pouvez simplement faire:

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

J'ai évité tout le code de gestion des erreurs pour le rendre plus lisible.

Abraham Simpson
la source
2

Mis à jour pour Swift 3 avec le moyen le plus sûr

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

entrez la description de l'image ici

iAj
la source
2

Swift 5.1, Xcode 11

Vous pouvez utiliser ceci:


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
la source
1

D'après la réponse d'Abhishek , pour iOS 8, ce serait:

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
la source
Utilisez-vous Swift 2.0? Alors oui, ce serait le cas. Cela a été répondu avant la version 2.0.
David Poxon
1

Cela a fonctionné pour moi avec 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
la source
1

Swift 4.1 Xcode 9.2 mis à jour

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
la source
3
Il n'y a rien de nouveau, bien au contraire: ne l'utilisez pas NSDatadans Swift 3+, et .allowFragmentsest inutile dans ce cas.
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)")
    }
}

ASHISH RANJAN
la source
0

J'ai utilisé le code ci-dessous pour récupérer le JSON du fichier FAQ-data.json présent dans le répertoire du projet.

J'implémente dans Xcode 7.3 en utilisant 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()
    }

Structure du fichier 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
la source
0

Je pourrais également recommander le didacticiel Swift JSON de Ray Wenderlich (qui couvre également la superbe alternative SwiftyJSON, Gloss ). Un extrait (qui a accordé, en soi, ne répond pas entièrement à l'affiche, mais la valeur ajoutée de cette réponse est le lien, donc pas de -1 pour cela, s'il vous plaît):

Dans Objective-C, l'analyse et la désérialisation de JSON est assez simple:

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

Dans Swift, l'analyse et la désérialisation de JSON est un peu plus fastidieuse en raison des options de Swift et de la sécurité de type [mais dans le cadre de Swift 2.0, l' guardinstruction a été introduite pour aider à se débarrasser des ifinstructions imbriquées :

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

Bien sûr, dans XCode 8.x, il vous suffit d'appuyer deux fois sur la barre d'espace et de dire "Hé, Siri, veuillez désérialiser ce JSON pour moi dans Swift 3.0 avec des espaces / tabulations".

AmitaiB
la source
0

VERSION SWIFTYJSON 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
la source
0

Créez d'abord un Struc codable comme ceci:

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

Déclarez maintenant la variable

 var jzdosList = [JuzgadosList]()

Lire à partir du répertoire 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.")
        }
    }

Lire sur le 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
la source
0

Utilisez cette fonction générique

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
}

avec cette ligne de code:

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

pour ce type:

struct Model: Codable {
    let tall: Int
}
Khaled Annajar
la source