Récupérer la valeur d'un json

Zim513201Zim513201 Membre
mai 2021 modifié dans Objective-C, Swift, C, C++ #1

Salut à tous, me revoilà, j'avance doucement, mais sûrement sur ma petit app perso ( pour mon exploitation agricole en fait).
Voila mon nouveau problème , j'ai un serveur Arduino qui renvoie une réponse (l'état d'un relai) en json. Tout fonctionne, aussi bien sur le serveur que du coté de la réponse.
voici le code coté serveur Arduino :

      if (c == '\n' && currentLineIsBlank) {

      // send a standard http response header
      client.println("HTTP/1.1 200 OK");
      client.println("Content-Type: application/json");
      client.println("Connection: close");  // the connection will be closed after completion of the response
      //client.println("Refresh: 5");  // refresh the page automatically every 5 sec
      client.println();

       // Puis on commence notre JSON par une accolade ouvrante
        client.println("{");
        // On envoie la première clé : "etat cloture"
        client.print("\t\"etatcloture\": ");
        // Puis la valeur de la cloture
        if (cloture1Allume == 1) {
        client.print("Allumee");}
        if (cloture1Allume == 0) {
        client.print("Eteinte");}

et en testant sur navigateur web, ou via Postman je reçois bien ma réponse json en fonction de l'état du relai :

Maintenant en testant mon code via Xcode je n'ai aucune réponse dans la console :

      class ClotureService {

private static let clotureUrl = URL (string: "http://192.168.1.177:90" )!

static func getCloture (){
    var request = URLRequest(url : clotureUrl)
    request.httpMethod = "POST"

    let body = "Content-Type=application/json"
    request.httpBody = body.data(using: .utf8)

    let session = URLSession(configuration: .default)
    let task = session.dataTask(with: request){ ( data, response, error ) in
        if let data = data, error == nil {
            if let response = response as? HTTPURLResponse, response.statusCode ==  200 {
                if let responseJSON = try? JSONDecoder().decode([String: String].self, from: data),
                   let text = responseJSON ["etatcloture"]{

                        print (text)}



       }
    }
    }
    task.resume()

}

}

uniquement cela quand je teste ( print (response)

Merci d'avance si vous voyez ou se situe le soucis

Réponses

  • CéroceCéroce Membre, Modérateur
    mai 2021 modifié #2

    Je pense qu'il faut que la session soit "retenue". En effet, quand l'exécution sort de getCloture(), session qui a une portée locale est libérée. Pour cela, je te conseille de déclarer let session: URLSession et de la fixer à l'init. getCloture() ne devra plus être static pour pouvoir y accéder.

    Utiliser print() pour déboguer atteint vite ses limites. Mets des breakpoints (points d'arrêts) en cliquant dans la marge de gauche. Tu pourras alors inspecter les variables. Voir la doc de Xcode.

  • PyrohPyroh Membre

    request.httpMethod = "POST" pour une requête qui devrait utiliser la méthode GET ?

  • > @Pyroh a dit :
    > request.httpMethod = "POST" pour une requête qui devrait utiliser la méthode GET ?

    Oui, mais lorsque je fait un GET j’ai un message d’erreur dans la console
  • LarmeLarme Membre
    mai 2021 modifié #5

    Allumee doit être entre guillemets. Ton JSON n'est pas valid, donc JSONSerialization ne fonctionne pas.

    Copie/colle ta réponse (de POSTMAN) dans un validateur JSON (il y a en plein en ligne).

    Tu l'aurais vu si tu n'avais pas fait l'erreur de débutant suivante : ignorer les erreurs !

    if let responseJSON = try? JSONDecoder().decode([String: String].self, from: data)
    

    Ici, tu fais try?. Cela revient à dire : « Si tu vas rater, et que donc tu pourrais renvoyer une erreur (throw), je m'en fiche, je ne veux rien savoir. Cette erreur si je l'attrapais, elle pourrait me donner des infos sur le pourquoi du ratage ? Non, mais j'ai dit que je ne voulais pas savoir ! »

    Je suppose que c'est ton erreur, il y a peut-être d'autres, MAIS faire un try?, c'est rédhibitoire, surtout quand ça ne marche pas.

    Fais un do/try/catch:

    do {
        let responseJSON = try JSONDecoder().decode([String: String].self, from: data)
        print("Got response: \(responseJSON)")
        if let text = responseJSON["etatcloture"] as? String {
            print("text: \(text)")
        } else {
            print("responseJSON["etatcloture"]: \(responseJSON["etatcloture"]) is either nil or not a String")
        }
    } catch {
        print("Got error while decoding: \(error) and response as UTF8 string is: \(String(data: data, encoding:.utf8))")
    }
    

    Ce que j'ai fait :
    - do{try}catch{}: regarder les erreurs
    - ajouter du contexte au print. TOUJOURS en mettre, car sinon, tu ne sauras pas de quel print un message dans la console vient. Je dis ça car en réalité, des breakpoints et autres qui sont d'un niveau un peu plus avancé feront l'affaire en debug, mais en réalité, savoir d'où viennent les logs, c'est important (surtout quand y'a de l'asynchrone qu'on ne comprend pas).

    En survolant le reste de ton code :

    • Est-ce vraiment un POST ? POSTMAN dit que c'est un "GET" (enfin que ça fonctionne en GET)
    • Tu mets une valeur qui devrait être dans les headers dans le body. Habituellement Content-Type, c'est dans les headers de la requête.
    • Et ne print pas que response, print aussi \(String(data: data, encoding:.utf8)), cela éclaire souvent pourquoi ça foire (notamment quand tu as des réponses différentes en cas d'erreurs: nombre de fois où je vois des questions sur StackOverflow, où la personne tombe sur une 404 avec un text HTML, ou une erreur en XML, etc et pas ce à quoi il/elle s'attendait).

    Fix rapide côte Arduino:

    if (cloture1Allume == 1)
    {
        client.print("Allumee");
    }
    if (cloture1Allume == 0) 
    {
        client.print("Eteinte");
    }
    

    =>

    if (cloture1Allume == 1)
    {
        client.print("\"Allumee\"");
    }
    if (cloture1Allume == 0) 
    {
        client.print("\"Eteinte\"");
    }
    
  • Merci beaucoup pour vos remarques, le simple fait de modifier mon json coté Arduino et j'ai une réponse !

    :p :p :p :p Vraiment merci ! bon je continue mon avancé

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