Error : catch / json

busterTheobusterTheo Membre
juin 2018 modifié dans API UIKit #1

Bonjour,
d'après un code que j'ai récupéré et adapté (si peu !), concernant un envoi de mail, et qui fonctionne parfaitement, j'ai juste un pb pour récupérer (lord) la error...

Voici d'abord le print dans ma console
Failed to load : Impossible de lire les données car le format n’est pas correct.

Qu'en pensez-vous ?

Puis le code :

let task = URLSession.shared.dataTask(with: request as URLRequest) {
            data, response, error in

            if error != nil {
                print("\nerror=\(error)")
                return
            }

            do {
                if let json = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String:AnyObject] {
                    print("\njson = \(json)")
                } else {
                    print("\nPas de json")
                }
            } catch let error as NSError {
                print("\nFailed to load : \(error.localizedDescription)") // C'EST ICI LE PRINT
            }
        }

        task.resume()

Merci d'avance

Mots clés:

Réponses

  • LarmeLarme Membre

    Je n'ai pas compris si tu demandes pourquoi ton JSONSerialization renvoie une erreur ou si tu veux récupérer cette fameuse erreur ?

    D'ailleurs .allowFragments est à utiliser que très rarement.

  • Merci pour ta réponse.
    En fait je veux comprendre pour quoi le format n’est pas correct, et si c'est important.

  • LarmeLarme Membre

    Ah.

    let jsonString = String(data: data, encoding: .utf8)
    print("jsonString:\n \(jsonString))
    

    Copies/colle ce résultat dans un JSON validator (y'en a plein online) et dis-nous s'il passe le test.

    Note qu'un JSON doit obligatoirement commencer par { ou [ (ça peut être juste un string, mais c'est un cas étrange et peu fréquent).

  • LarmeLarme Membre
    juin 2018 modifié #6

    Si JSONSerialization dit que le JSON n'est pas valide, je ne pense du tout que SwiftyJSON fasse des miracles, car quand on voit dans leur code:

    public init(data: Data, options opt: JSONSerialization.ReadingOptions = []) throws {
        let object: Any = try JSONSerialization.jsonObject(with: data, options: opt)
        self.init(jsonObject: object)
    }
    

    Ils n'ont pas réinventé la roue en créant leur propre parsers comme d'autres, ils utilisent le basique fourni par Apple.
    Ce qu'ils ont fait c'est surtout un moyen de faire comme en Objective-C qui ne se soucie guère de faire: monJSON[Index1]["Clé2"]["Clé3"][Index4]["Clé5"], il te fait confiance.

  • Joanna CarterJoanna Carter Membre, Modérateur

    Comment as-tu créé le JSON ? Tu peux nous montrer un exemple ?

  • Google est ton ami également pour tester des données structurées :smiley:

    https://search.google.com/structured-data/testing-tool?hl=fr

  • Ah d'accord, vos réponses, et merci pour elles, me confirment que je suis bien chez les pros, groupe duquel je ne ferais à mon grand désespoir jamais partie.

    Dans un premier temps, excuses moi xyloweb, mais google n'est certainement pas mon ami. Je sais que tu cites la blague bien connue de presque tous les terriens. Je n'en dirais pas plus et je te remercie de ton aide.

    Ceci dit : comment j'ai créé mon jSon : je n'en sais rien, je n'ai fait qu'adapter (le mot est fort) un code pris sur le web. Honte à moi !

    Enfin, je met quand même ma fonction complète, bien que j'en avais mis le plus important plus haut (if let json = try...)

    Encore merci pour vos efforts car je sais que la tâche demande du courage et surtout du temps que vous me consacrez. Je ne serais jamais assez reconnaissant envers cocoaCafe.

    La fonction...

    // MARK: - ENVOI MAIL

    func declencheEnvoiMailTrace(action: String) {
        let chainePostString = "action=" + action + "&" + postAString
        envoiMailTrace(chaine: chainePostString)
    }
    
    func envoiMailTrace(chaine: String) {
        let myURL: NSURL! = NSURL(string: "https://www.magnitude-6.net/envoiMailTrace.php")
    
        let request: NSMutableURLRequest = NSMutableURLRequest(url: myURL! as URL)
        request.httpMethod = "POST"
    
        request.httpBody = chaine.data(using: String.Encoding.utf8)
    
        let task = URLSession.shared.dataTask(with: request as URLRequest) {
            data, response, error in
    
            if error != nil {
                print("\nerror=\(String(describing: error))")
                return
            }
    
            do {
                if let json = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String:AnyObject] {
                    print("\njson = \(json)")
                } else {
                    print("\nPas de json")
                }
            } catch let error as NSError {
                print("\nFailed to load : \(error.localizedDescription)")
            }
        }
    
        task.resume()
    
        print("envoiMailTrace : \(chaine)")
    }
    
  • Swift 3 ou + non ?
    Alors let myURL: URL = URL(string: "https://...") et let request: URLRequest = URLRequest(url: myURL!) plutôt. Cela t'évitera en plus un autre cast.

    De plus, print error entièrement, pas que la localizedDescription (et donnes-la nous), et tu n'as pas répondu à ma question. L'erreur te dit que le JSON n'est pas correct. Pourrais-tu vérifier qu'il est bon comme je te l'ai demandé ?
    Ou au moins nous le montrer ?

  • Ah Larme, merci.
    Cool pour le cast évité.

    Je n'ai pas testé ton code car je ne sais pas trop comment, et je ne voulais pas t'ennuyer d'avantage avec cela - Je ne peux donc pas vérifier si il est bon.
    Et te le montrer, je ne comprend pas ce que je dois te montrer : tu vois la fonction (plus haut), c'est tout ce que j'ai.

    Pour être honnête : j'entrave queDalle d;-)

  • LarmeLarme Membre
    juin 2018 modifié #12

    Remplace ceci:

    print("\nFailed to load : \(error.localizedDescription)") // C'EST ICI LE PRINT
    

    Par :

    print("\nFailed to load : \(error)") // C'EST ICI LE PRINT
    let jsonString = String(data: data, encoding: .utf8)
    print("jsonString:\n \(jsonString))
    

    Et montre nous ce qui est printé.

  • Ah, merci Larme.
    Désolé pour le retard de la réponse.

    J'ai été obligé par xCode de modifier ton code ainsi (String(describing c'est xCode 9) - (data: data! c'est ... Les poneys, je crois !):

    print("\nFailed to load : (error)") // C'EST ICI LE PRINT
    let jsonString = String(data: data!, encoding: .utf8)
    print("jsonString:\n (String(describing: jsonString))")

    Et voici le print tant attendu :

    Sur le simulateur et sur l'iPad.
    Failed to load : Error Domain=NSCocoaErrorDomain Code=3840 "No value." UserInfo={NSDebugDescription=No value.}
    jsonString:
    Optional("")

    Voilà.

  • Tu es censé avoir une réponse ? Parce qu'apparemment tu n'as pas de réponse si en en crois l'erreur.

    N'utilise pas String(describing:), c'est rarement ce qu'on souhaite faire.
    Et les forces unwrapping (le fameux point d'exclamation), c'est très souvent à ne pas faire, mais là, c'est plus du débug pour comprendre pourquoi ça ne marche pas. Et clairement, je ne vais pas faire un_ if let_ just pour ça.

  • Merci tardif pour ta réponse.
    Désolé pour le tracas et surtout le retard.

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