Probleme de format JSON

#swift 5

Bonjour à tous,

Je cherche à faire une requête sur une url avec Alamofire et cela me renvoie cette erreur : JSON could not be serialized because of error:\nThe data couldn’t be read because it isn’t in the correct format.
je ne comprend pas trop pourquoi. Il s’agit d’un Json classique qui s’affiche correctement dans postman. Avez vous déjà rencontrer ce type d’erreur ? Comment identifier précisément le format ?
Toutefois on me dit dans l’oreillette qu’il s’agit d’un json tout ce qu’il y a de plus classique.

Merci d’avance de vous être penché sur le sujet

Visiblement je dois vérifier le bon format de mon JSon avec ''try? JSONSerialization.jsonObject(with: testData, options: .allowFragments)" mais jusqu’ici je n’ai jamais eu à le faire. Vous savez pourquoi ?

En général s’il te demande d’ajouter cette option c’est que ton JSON est invalide : il ne possède peut être pas de conteneur racine. Le fait que Postman soit capable de l’afficher ne garantis pas qu’il soit valide.

Sans voir ton JSON c’est difficile de t’aider plus :slight_smile:

Bonjour Maxime !
Merci pour ta réponse, c’est super sympa de revenir vers moi !

Désolé mais qu’est ce que tu entends par un conteneur racine, stp ?

Voici le json sur lequel je bosse :

{
    "erreurs": [],
    "success": [],
    "type": "getElementById",
    "livreur": {
        "id_livr": "3",
        "dajout_livr": "",
        "timestamp_livr": "0000-00-00 00:00:00",
        "daccept_livr": "",
        "nom_livr": "Marley",
        "prenom_livr": "Bob",
        "jnaiss_livr": "6",
        "mnaiss_livr": "02",
        "anaiss_livr": "1945",
        "email_livr": "t*******s@gmail.com",
        "emailok_livr": "1",
        "tel_livr": "061145454545",
        "passe_livr": "",
        "societe_livr": "The Wailers's corporation",
        "add_livr": "",
        "addcomp_livr": "",
        "cp_livr": "75000",
        "ville_livr": "paris",
        "pays_livr": "France",
        "add2_livr": "",
        "addcomp2_livr": "",
        "cp2_livr": "",
        "ville2_livr": "",
        "addfac_livr": "0",
        "siren_livr": "",
        "numtva_livr": "",
        "devise_livr": "",
        "stripe-account_livr": "",
        "commentconnu_livr": "0",
        "type_livr": "0",
        "etat_livr": "",
        "test_livr": "0",
        "demo_livr": "0"
    }
}  

Merci pour ton aide

Vincent

Tu as bien un conteneur racine ici (les accolades du début et de la fin), donc le problème est ailleurs. Est-ce que tu es certain à 100% que c’est le texte que tu envoies à ton parser JSON ?
Pour vérifier fait un print ou utilise le debugger pour copier la valeur, depuis la ligne située juste avant l’appel du parser.

Merci de nouveau pour ton retour !

Oui je pense. Je fais comme d’habitude. Voici mon fichier où je récupère la data :

struct RequestDeliverResult: Decodable {
    //let erreurs: [Any?]
    //let success: [Any?]
    let type: String
    let deliver: Deliver
}

    // MARK: - Livreur
struct Deliver:Decodable {
    let _idDeliver:String               //let id_livr    int(11) Incrément automatique
    let _dateSignInDeliver:String       //let dajout_livr    varchar(50)
    let _timeStamp:String                //timestamp_livr    timestamp [current_timestamp()]
    let _authorizationSellDeliver:Bool  //daccept_livr    varchar(50)
    let _firstNameDeliver:String        //nom_livr    varchar(255)
    let _lastNameDeliver:String         //prenom_livr    varchar(255)
    let _dayOfBirthDeliver:String       //jnaiss_livr    varchar(255)
    let _monthOfBirthDeliver:String     //mnaiss_livr    varchar(255)
    let _yearOfBirthDeliver:String      //anaiss_livr    varchar(255)
    let _emailDeliver:String            //email_livr    varchar(255)
    let _emailOptinDeliver:Bool         //emailok_livr    int(11) [0]
    let _phoneNumberDeliver:String      //tel_livr    varchar(255)
    let _passwordDeliver:String         //passe_livr    varchar(255)
    let _companyDeliver:String          //societe_livr    varchar(255)
    let _addressCompanyDeliver:String   //add_livr    varchar(255)
    let _complementaryAdressDeliver:String //addcomp_livr    varchar(255)
    let _postalCodeDeliver:String        //cp_livr    varchar(255)
    let _cityDeliver:String              //ville_livr    varchar(255)
    let _countryDeliver:String           //pays_livr    varchar(255)
    //add2_livr    varchar(255)
    //addcomp2_livr    varchar(255)
    //cp2_livr    varchar(255)
    //ville2_livr    varchar(255)
    let adressPaymentDeliver:String      //addfac_livr    int(11) [0]
    let sirenDeliver:String              //siren_livr    varchar(255)
    let TVANumberDeliver:String          //numtva_livr    varchar(255)
    let currencyDeliver:String           //devise_livr    varchar(255)
    let stripeAccountDeliver:String      //stripe-account_livr    varchar(255)
    let howYouKnowUsDeliver:String       //commentconnu_livr    int(11) [0]
    let typeDeliveryPersonDeliver:String //type_livr    int(11) [0]
    //etat_livr    varchar(100)
    //test_livr    int(11)
    //demo_livr    int(11)

}

et voici ma requête :

func getRequestBdd(action:Action, id: String, completionHandler: @escaping(Bool, RequestDeliverResult?) -> Void) {
        guard let urlProd = URL(string: constructUrlWithToken(action:action, id: id)) else {return}
        print("urlProd getRequestBdd \(urlProd)")
        requestApiSession.requestFromBDD(url: urlProd) { response in
            guard response.response?.statusCode == 200 else {
                print("error status code 200")
                completionHandler(false, nil)
                print(response.error?.localizedDescription as Any)
                //print(response.error.customMirror)
                return
            }
            guard let data = response.data, response.error == nil else {
                print("error : response.data, response.error")
                completionHandler(false, nil)
                return
            }
            guard let requestDeliverResult = try? JSONDecoder().decode(RequestDeliverResult.self, from: data) else {
             //guard let requestDeliverResult = try? JSONDecoder().decode(RequestDeliverResult.self, from: data) else {
                print("RequestIndoDeliverResult pb JSOnDecoder")
                completionHandler(false, nil)
                return
            }
            print("=========== Request OK =============")
            completionHandler(true, requestDeliverResult)
            print("requestDeliverResult.deliver._firstNameDeliver\(requestDeliverResult.type)")
            print("requestDeliverResult.deliver._firstNameDeliver\(requestDeliverResult.deliver._firstNameDeliver)")
            //print("requestDeliverResult.deliver._firstNameDeliver\(requestDeliverResult.livreur._lastNameDeliver)")
        }
    }

De ce que je vois, les clés de ton json ne correspondent pas aux noms des variables de tes struct en Swift. Apple fournit un playground avec plusieurs exemples de parsing du JSON, regarde comment faire correspondre les clés JSON au nom de tes variables : https://developer.apple.com/documentation/foundation/archives_and_serialization/using_json_with_custom_types?language=objc

Tu peux aussi utiliser le try-catch au lieu du guard qui ne te donne aucune info sur la raison de l’erreur :

do {
 let myObject = try JSONDecoder().decode(RequestDeliverResult.self, from: data)
} catch {
 print("json error: \(error.localizedDescription)")
}
1 J'aime

Merci pour ton aide !

Je reviens vers toi dans tous les cas

Vincent