traitement de données json

Bonjour,
Je cherche à récupérer des données à partir d'un base d'une données pour intégrer à un labelView ou autres controller.
Pour l'instant, j'arrive à récupérer les données dans une variable String avec un fichier php.
adressePhp: String = "http://.../extract_liste_livres.php"

[{"id":"0","Titre":"le cinqui\u00e8me cavalier","Auteur":"Dominique Lapierre","Genre":"Thriller","Commentaires":""},{"id":"1","Titre":"Apn\u00e9e noire","Auteur":"Claire Favan","Genre":"Thriller","Commentaires":""},{"id":"2","Titre":"Tous les diamants du ciel","Auteur":"Claro","Genre":"Roman","Commentaires":""},{"id":"3","Titre":"L'amour au temps des solitudes - Le condottiere","Auteur":"Max Gallo","Genre":"Histoire","Commentaires":""},{"id":"4","Titre":"Steve Jobs","Auteur":"Walter Isaacson","Genre":"Biographie","Commentaires":""}]

ou également créer un fichier du type "liste_livres.json"
let adressePhp: String = "http://.../liste_livres.json"

Je pense que le plus simple est de créer ensuite des tableaux avec les différentes données.
Je n'ai, par contre, pas bien résolu la façon de traiter correctement le problème.
Mon autre question est de savoir si un TableView supporte une liste de 200 ou 300 lignes, voire plus.
Merci pour votre aide.

Réponses

  • LarmeLarme Membre
    26 janv. modifié #2

    Je n'ai, par contre, pas bien résolu la façon de traiter correctement le problème.

    Tu n'as pas compris comment lire parser du JSON, ou c'est les UITableView ton souci ?
    Il faut que tu utilise (NS)JSONSerialization pour retransformer ton JSON Stringifié en (NS)Data, de là, tu pourras le transformer en (NS)Dictionary/(NS)Array pour le parser, et/ou utiliser Codable (nouveauté Swift 4).
    Personnellement, si c'est la première fois que tu utilises du JSON, je conseillerais dans un premier temps de n'utiliser que JSONSerialization et des objets customs, pas Codable (que tu pourras rajouter par la suite sur tes objects customs). Je vois trop de questions sur StackOverflow concernant le JSON et iOS là-dessus pour conseiller cette approche, en comprenant la structure du JSON.

    Mon autre question est de savoir si un TableView supporte une liste de 200 ou 300 lignes, voire plus.

    Une UITableView "reuse" ses cellules. C'est à dire qu'elle en crée au besoin, mais dès qu'elles partes de l'écran, elles sont « en attente », et si elle a besoin d'une cellule d'un certain type et qu'il y en a une en attente, elle récupère celle en attente plutôt que d'en créer une autre. Donc une liste de 200 ou 300 row, c'est gérable.

  • C'est de lire et parser à partir du json

  • et s'il est plus simple de les gérer directement ou de passer par la création d'un fichier .json

  • LarmeLarme Membre

    Pardon, j'ai édité ma réponse entre temps.

    C'est de lire et parser à partir du json

    Est-ce que toi, tu comprends sa structure ? Si je te demandais d'écrire manuellement avec les équivalents Swift le JSON (enfin, son interprétation), en serais-tu capable ?

    En bref, si je te dis de créer let extract_liste_livres, qui imiterait ton JSON, tu ferais quoi ?

  • La variable ne risque-t-elle pas d'être un peu longue avec 200 à 300 lignes ?

  • Tu veux dire cela:
    0
    id "0"
    Titre "le cinquième cavalier"
    Auteur "Dominique Lapierre"
    Genre "Thriller"
    Commentaires ""
    1
    id "1"
    Titre "Apnée noire"
    Auteur "Claire Favan"
    Genre "Thriller"
    Commentaires ""

  • LarmeLarme Membre

    Non, je voulais dire quelque chose de ce style-là:

    let item0 = ["id":"0","Titre": "le cinquieme cavalier", "Auteur": "Dominique Lapierre", "Genre": "Thriller", "Commentaires": ""]
    
  • je pense que oui.
    j'avais aussi créer une classe Livre (mais à partir de là je suis moins sûr de moi)

    class Livre: NSObject {
    var Titre: String?
    var Auteur: String?
    var Genre: String?
    var Commentaires: String?

    init(Titre: String, Auteur: String, Genre: String, Commentaires: String) {
        self.Titre = Titre
        self.Auteur = Auteur
        self.Genre = Genre
        self.Commentaires = Commentaires
    }
    
  • L’id n’est pas utilisé dans ta classe Livre ? C’est juste une information interne au fichier JSON ?

  • non c'est un oubli

  • LarmeLarme Membre
    26 janv. modifié #12

    C'est pas très Swift (il faudrait des lowercase pour le début des var, des introductions aux arguments de la fonction, etc.), mais c'est plutôt bien (voire même très bien) de vouloir créer une custom classe (ou struct), c'est quelque chose que certains débutants ne font malheureusement pas.

    Dans mon exemple précédent, j'ai créé let item0.
    Es-tu capable de recréer entièrement le JSON que tu as montré précédemment, avec uniquement des Dictionary, Array, String?

    À partir de ça, es-tu capable de créer un ensemble d'objets de classe Livre avec les données qui vont bien ?

    Je sais, ça fait un peu exercice de maths : Montrer que, déduire que, etc, mais le dév', c'est beaucoup ça. Faire un plan avec ce qu'on a et ce qu'on veut faire au final, essayer de trouver les moyens intermédiaires qu'on sait faire, ceux qu'on ne sait pas faire mais se dire que y'a peut-être un moyen (ou alors remplacer la logique de cette étape là), ensuite réessayer de découper ce qu'on ne sait pas faire pour essayer d'y trouver des p'tits bouts qu'on sait faire, etc.

    Donc le but de ces deux questions, c'est de savoir si tu sais utiliser les Array/Dictionaries (itération, récupération de données spécifiques, etc.), savoir faire la différence entre les deux (index-value vs key-value) et donc savoir quand utiliser l'un ou l'autre (on est tous les jours amené à en utiliser l'un ou l'autre). Et la première question cherches également à vérifier que tu as compris la structure du JSON.

  • DrakenDraken Membre
    26 janv. modifié #13

    @jean-luc a dit :
    je pense que oui.
    j'avais aussi créer une classe Livre (mais à partir de là je suis moins sûr de moi)

    class Livre: NSObject {
    var Titre: String?
    var Auteur: String?
    var Genre: String?
    var Commentaires: String?

    init(Titre: String, Auteur: String, Genre: String, Commentaires: String) {
    self.Titre = Titre
    self.Auteur = Auteur
    self.Genre = Genre
    self.Commentaires = Commentaires
    }

    Petite remarque technique : les noms des variables doivent commencer par des minuscules, pas des Majuscules !

    class Livre: NSObject {
    var titre: String?
    var auteur: String?
    var genre: String?
    var commentaires: String?
    }

  • Joanna CarterJoanna Carter Membre, Modérateur
    26 janv. modifié #14

    Ou, tu peux utiliser le protocol Codable :

    enum Genre : String, Codable
    {
      case unknown
      case thriller = "Thriller"
      case mystery = "Mystery"
    }
    
    struct Livre : Codable
    {
      var id: Int = 0
      var titre = ""
      var auteur = ""
      var genre = Genre.unknown
      var commentaires = ""
    }
    
    
      {
        var livres = [Livre]()
    
        var livre = Livre()
    
        livre.id = 0
    
        livre.titre = "le cinquième cavalier"
    
        livre.auteur = "Dominique Lapierre"
    
        livre.genre = .thriller
    
        livres.append(livre)
    
        livre.id = 1
    
        livre.titre = "le secret de la licorne"
    
        livre.auteur = "Hergé"
    
        livre.genre = .mystery
    
        livres.append(livre)
    
        do
        {
          let encoder = JSONEncoder()
    
          var jsonData = try encoder.encode(livres)
    
          let json = try JSONSerialization.jsonObject(with: jsonData)
    
          jsonData = try JSONSerialization.data(withJSONObject: json)
    
          let decoder = JSONDecoder()
    
          let decodedLivres = try decoder.decode(Array<Livre>.self, from: jsonData)
    
          print(decodedLivres)
        }
        catch
        {
    
        }
      }
    
  • DrakenDraken Membre
    26 janv. modifié #15

    Nounours, une collection de livres doit forcément avoir un genre fantasy. C’est une loi fondamentale de la littérature.

    enum Genre : String, Codable
    {
      case unknown
      case thriller = "Thriller"
      case mystery = «Mystery"
      case fantasy = « Fantasy"
    }
    
  • Joanna CarterJoanna Carter Membre, Modérateur

    @Draken a dit :
    Nounours, une collection de livres doit forcément avoir un genre fantasy. C’est une loi fondamentale de la littérature.

    enum Genre : String, Codable
    {
      case unknown
      case thriller = "Thriller"
      case mystery = «Mystery"
      case fantasy = « Fantasy"
    }
    

    Oups ! Et, en plus, j'ai édité le code pour faire l'aller d'un array de Livres vers du JSON et le retour

  • Merci Larme pour ton commentaire détaillé.
    Les exercices de maths étaient plutôt ma tasse de thé, mais je suis loin de maîtriser les concepts du language informatique. La découverte du (ou des) languages informatiques pour des non-initiés comme moi est assez complexe, voire même parfois "ésotérique". D'autant plus que je ne travaille pas dessus de façon permanente.
    mais c'est bon pour le cerveau ... :)
    Je continue ....
    Merci

  • LarmeLarme Membre

    @Joanna Carter
    Je ne voulais pas utiliser Codable dans un premier temps, car ce sont des réponses toutes faites.
    Je préfère enseigner la structure du JSON, faire comprendre que ce ne sont que des Dictionary/Array, faire comprendre les itérations à chaque sous-niveau nécessaires et JSONSerialization est très adéquate pour ça.
    Que si on sait faire ça, on peut gérer tous les JSON, qu'il n'y a rien de magique derrière.
    Une fois compris, le Codable est très rapidement compris, mais pour passer beaucoup de temps sur SO, les réponses en Codable directement écrites, et sans explications à part "Mais tu vois pas que c'est un array (ou un dict) ton JSON à tel level", ce n'est pas utile.

  • CéroceCéroce Membre, Modérateur

    @Larme je suis d'accord. Codable marche tout seul la plupart du temps, mais quand le service en face présente un JSON seulement un peu inhabituel, Codable pose de nouveaux problèmes, et il est bon de savoir comment ça fonctionne.

  • Joanna CarterJoanna Carter Membre, Modérateur

    Tu peux convertir le json en Data, puis extraire le dictionnaire pour le vérifier. Ou tu peux prendre le même Data et le decoder vers Codable après que tu l’as vérifié.

Connectez-vous ou Inscrivez-vous pour répondre.