SQLite et json

Bonjour,


 


Je voudrais stocker un json dans ma base de donnée sqlite pour pouvoir l'interpreter par la suite mais je n'y arrive tout simplement pas quand je l'envoie dans la base de donnée il bloque et me renvoie sur le main.m xcode me donne aucune indication sur le problème pour lui tout compile mais il passe pas quand je l'execute il me dit toujours


 



 


-[__NSCFString bytes]: unrecognized selector sent to instance 0x182bf400


2014-07-31 12:25:59.485 melanie[3370:289918] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString bytes]: unrecognized selector sent to instance 0x182bf400'


*** First throw call stack:


(0x289c4777 0x35aa2d13 0x289c9ac9 0x289c79df 0x288fa578 0x296ba437 0x296ba339 0x296ba281 0xfed8b 0x2c0d37df 0x2c0d354d 0x2c25c85d 0x2c17c6c7 0x2c17c4cd 0x2c17c461 0x2c0d0d65 0x2bb020cd 0x2bafdab5 0x2bafd93d 0x2bafd321 0x2bafd125 0x2baf6ffd 0x2898afb5 0x28988673 0x28988a7b 0x288d7a21 0x288d7833 0x2fec7111 0x2c132edd 0xfda5d 0x36027aaf)


libc++abi.dylib: terminating with uncaught exception of type NSException



 


j'ai essayer plusieurs chose le metre en blob dans ma bdd le metre en text mais rien y fait il ne passe pas je vous montre la façon dont je il est récupérer


 



 


NSString *post =[[NSString alloc] initWithFormat:@login=%@&;pwd=%@",[self.takeEmailAuth text],[self.takePasswdAuth text]];


        NSLog(@PostData: %@",post);


            


        NSURL *url=[NSURL URLWithString:@"http://xxxxxxx/xxxxxxxx/"];


        


        NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];


        


        NSString *postLength = [NSString stringWithFormat:@%lu, (unsigned long)[postData length]];


        


        NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];


        [request setURL:url];


        [request setHTTPMethod:@POST];


        [request setValue:postLength forHTTPHeaderField:@Content-Length];


        [request setValue:@application/json forHTTPHeaderField:@Accept];


        [request setValue:@application/x-www-form-urlencoded forHTTPHeaderField:@Content-Type];


        [request setHTTPBody:postData];


        NSError *error = [[NSError alloc] init];


        NSHTTPURLResponse *response = nil;


        NSData *urlData=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];


            


        NSLog(@Response code: %ld, (long)[response statusCode]);


        


        if ([response statusCode] == 200)


        {


            NSString *responseData = [[NSString alloc]initWithData:urlData encoding:NSUTF8StringEncoding];


            NSLog(@Response ==> %@", responseData);


            NSError *error = nil;


            NSMutableArray *jsonData = [NSJSONSerialization JSONObjectWithData:urlData options:NSJSONReadingMutableContainers error:&error];


            [downloadForm formToBdd:jsonData:responseData];


            success = YES;



 


Je fait d'abord un premier traitement. pour récupere des info et dans une des case je stock la totalité de la requete 


c'est avec cette ligne que je l'envoie a ma BDD : [downloadForm formToBdd:jsonData:responseData];


 


Et voila comment je la save


 



 


+ (void) formToBdd:(NSMutableArray *)downloadArray : (NSString *)brute {


    DBAccess *dba = [[DBAccess alloc] init];


    int i = 0;


    while (i < [downloadArray count])


    {


        NSString *checkRequete = [NSString stringWithFormat: @SELECT * FROM listForm WHERE %@='%@'",


                                  [NSString stringWithFormat:@cmp_id],


                                  [NSString stringWithFormat:@%@", [downloadArray[i] objectForKey:@cmp_id]]];


        NSLog(@%@ Value exist", checkRequete);


        if ([dba checkValueBdd: checkRequete] == 0)


        {


            NSString *commande =  [NSString stringWithFormat: @INSERT INTO listForm (title, properties, cmp_id) VALUES ('%@', '%@', '%@')",


                                   [NSString stringWithFormat:@%@", [downloadArray[i] objectForKey:@cmp_title]],


                                   brute,


                                   [NSString stringWithFormat:@%@", [downloadArray[i] objectForKey:@cmp_id]]];


            [dba cmdToBdd: commande];


        }


        i++;


    }


}



 


je n'y comprend rien il me la stock correctement mais quand derrière je veut encore la traiter il plante :/


pourtant j'utilise le meme code de traitement 


 



 


NSError *error = nil;


    NSMutableArray *jsonData = [NSJSONSerialization JSONObjectWithData:form.cmpProperties options:NSJSONReadingMutableContainers error:&error];



 


il sort a ce moment la et me renvoie vers main.m avec l'erreur sitée plus haut 


Encore une fois je comprend pas j'ai essayer pas mal de chose mais rien y fait :/


 


Merci d'avance, Cordialement 


Réponses

  • form.cmpProperties, c'est quoi exactement ?


    D'après le message d'erreur, j'aurais tendance à  dire que c'est un NSString.


    Alors que lorsque tu appelles JSONObjectWithData:options:error qui s'attend à  un NSData, comme la première fois que tu l'appelles.


  • Oui effectivement c'est un string j'ai essayer de le passer en DATA mais javais le meme type d'erreur 


    PS: Emma Roberts <3333333


  • LarmeLarme Membre
    juillet 2014 modifié #4

    Essaye avec:



    NSMutableArray *jsonData = [NSJSONSerialization JSONObjectWithData:[form.cmpProperties dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers error:&error]; 

    C'est un truc que j'ai déjà  eu à  faire pour dépanner un collègue qui recevait des reports JSON alors qu'il aurait aimé comparer avec mes données qui étaient reformatées dans un truc plus sympa : CSV.


  • KiraxKirax Membre
    juillet 2014 modifié #5

    En fait il me faut le json pour l'interpreter et l'afficher (dedans chaque bloque correspond a un objet)


     


    Donc j'ai besoin de réinterperter bloque par bloque mais vu que le nombre d'argument dans ces bloque est variable je ne peut les stoker directement en dur dans la BDD


  • KiraxKirax Membre
    juillet 2014 modifié #6

    il me dit 



     


    41:92: No visible @interface for 'NSData' declares the selector 'dataUsingEncoding:'



    donc je pence que j'ai un problème au niveau de mon objet :/


     




     


    Donc je l'est repasser en String donc ta commande passe mais il me donne un tableau null :/


  • dataUsingEncoding: est une méthode de la classe NSString.


    En fait, ton problème, c'est que tu mets dans form.cmpProperties, un NSString, alors que ça devrait être un NSData. Je suppose que dans ta classe, cmpProperties est déclaré comme étant un NSData.


    Donc, vérifie quand tu fais form.cmpProperties = ou [form setCmpProperties: ce que tu mets réellement dedans. Agis ensuite en fonction.


  • KiraxKirax Membre
    août 2014 modifié #8

    Effectivement ca doit etre un NSString vu qu'il sort de ma BDD


     


    Par contre pour passer d'un NSString a un NSData j'ai essayer 1000truc et rien :/




  • Par contre pour passer d'un NSString a un NSData j'ai essayer 1000truc et rien :/




     


    Fais voir la chaine de caractère et comment tu fais. 


    Normalement un truc de genre doit marcher :



    NSString *aStr = @tests;
    NSData *data = [aStr dataUsingEncoding:NSUTF8StringEncoding];
  • KiraxKirax Membre
    août 2014 modifié #10

    il me renvoie <3534> au passage en NSData :/


     


    Et la il me sort une nouvelle error 


    No visible @interface for 'NSData' declares the selector 'dataUsingEncoding:'


     


    Logique :P


     


    Donc il a pas l'aire de passer en NSData


  • Ben oui tu es toujours dans la même erreur, tu mélanges entre les NSData et les NSString. 


     


    De coup je ne sais plus ce que tu veux faire réellement et c'est quoi exactement ton problème :)


     


    En résumé :


     


    Tu arrives à  récupérer ton text de ton serveur ( même si la méthode que tu utilise n'est pas la bonne, puisque tu fais un requête synchrone et ça te bloque le main thread ... mais bon on verra ça plus tard quand que tu postera "Mon application bloque ..." :)).


     


    Tu arrive à  stocker le text dans ta base SQLite. 


     


    Quand tu récupère le texte de la base, ça crash.


     


    Si c'est ça, montre le code qui récupère le texte et le traitement que tu fais avec.


  • en faite je stock mon json brut dans ma BDD (string dans la bdd) puis après je le récupère normalement la il est en NSString mais je voudrais le repasser en mode normale genre le repasser comme si je venais de le recevoir :/


  • Tu as essayé avec ce code ? (et montre ton code comment tu fais.)



    NSString *aStr = @tests;
    NSData *data = [aStr dataUsingEncoding:NSUTF8StringEncoding];
  • KiraxKirax Membre
    août 2014 modifié #14

     


    DBAccess *dba = [[DBAccess alloc] init];


        NSString *Requete = [NSString stringWithFormat: @SELECT * FROM listForm WHERE %@='%@'",


                            [NSString stringWithFormat:@cmp_id],


                            [NSString stringWithFormat:@%@", form.cmpId]];


        NSMutableArray *cache = [dba getDataSQL: Requete];


        NSError *error = nil;


        NSData *data = [[[cache objectAtIndex:0]objectAtIndex:1] dataUsingEncoding:NSUTF8StringEncoding];


        NSMutableArray *jsonData = [NSJSONSerialization JSONObjectWithData:[[data dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers error:&error];


        NSLog(@%@", jsonData);



    Voila


     


     


    le retour de ma requete me donne donc dans [[cache: ObjectAtIndex:0] objectAtIndex:1]



     


        items =     (


                    {


                key = choice;


                properties =             {


                    "default_value" = "";


                    elements =                 (


                    );


                    mandatory = 0;


                    title = Choix;


                };


            },


                    {


                key = datetime;


                properties =             {


                    "default_date" = "";


                    "default_hour" = "";


                    title = "Date et Heure";


                    type = datetime;


                };


            }


        );


        nbrSoumission = infinity;


        publish = 1;


        title = "toto cmp";


    }



    ce que je voudrais bien passer en json classic


     


     


     dans data j'ai :



     


    <7b0a2020 20206974 656d7320 3d202020 2020280a 20202020 20202020 20202020 20202020 7b0a2020 20202020 20202020 20206b65 79203d20 63686f69 63653b0a 20202020 20202020 20202020 70726f70 65727469 6573203d 20202020 20202020 20202020 207b0a20 20202020 20202020 20202020 20202022 64656661 756c745f 76616c75 6522203d 2022223b 0a202020 20202020 20202020 20202020 20656c65 6d656e74 73203d20 20202020 20202020 20202020 20202020 280a2020 20202020 20202020 20202020 2020293b 0a202020 20202020 20202020 20202020 206d616e 6461746f 7279203d 20303b0a 20202020 20202020 20202020 20202020 7469746c 65203d20 43686f69 783b0a20 20202020 20202020 2020207d 3b0a2020 20202020 20207d2c 0a202020 20202020 20202020 20202020 207b0a20 20202020 20202020 2020206b 6579203d 20646174 6574696d 653b0a20 20202020 20202020 20202070 726f7065 72746965 73203d20 20202020 20202020 20202020 7b0a2020 20202020 20202020 20202020 20202264 65666175 6c745f64 61746522 203d2022 223b0a20 20202020 20202020 20202020 20202022 64656661 756c745f 686f7572 22203d20 22223b0a 20202020 20202020 20202020 20202020 7469746c 65203d20 22446174 65206574 20486575 7265223b 0a202020 20202020 20202020 20202020 20747970 65203d20 64617465 74696d65 3b0a2020 20202020 20202020 20207d3b 0a202020 20202020 207d0a20 20202029 3b0a2020 20206e62 72536f75 6d697373 696f6e20 3d20696e 66696e69 74793b0a 20202020 7075626c 69736820 3d20313b 0a202020 20746974 6c65203d 2022746f 746f2063 6d70223b 0a7d>



     


    et a la ligne du NSMutableArray il me dit 


     



     


    No visible @interface for 'NSData' declares the selector 'dataUsingEncoding:'



  • AliGatorAliGator Membre, Modérateur
    août 2014 modifié #15
    Perso il m'est impossible de lire un code qui :
    1) N'est pas formatté dans des balises [code]
    2) Ne respecte pas les conventions de nommage (c'est plus fort que moi, quand je vois "Requete" avec une majuscule, comme tout développeur ObjC qui se respecte, moi je vois une classe et pas une instance, du coup le code n'a pas de sens.

    Tu m'étonnes qu'après tu n'arrives pas à  t'y retrouver et ne sache plus ce que tu manipules.

    Et sinon, samir t'a déjà  donné la solution à  ton problème.

    Tu confonds NSData et NSString, tu ne sais pas trop ce que tu manipules. Pourtant c'est juste sous tes yeux. Tu as un NSData* data, si cette variable est bien effectivement un NSData, pourquoi voudrais-tu appeler dataUsingEncoding: dessus (qui est une méthode de NSString pour transformer une NSString en NSData, alors que toi tu as déjà  des NSData manifestement) ?

    A lire ton code on a l'impression que tu as copier/coller des bouts de code trouvé ça et là  (ou qu'on t'a dit d'utiliser sans connaà®tre le contexte)... sans toi-même comprendre vraiment ce que tu fais avec ce code...
  • KiraxKirax Membre
    août 2014 modifié #16

    effectivement erreur de ma par quand je vire mon  dataUsingEncoding:NSUTF8StringEncoding


     


    NSMutableArray *jsonData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];


     


    il me revoie un jsonData vide.


     


    Temps qu'a ma façon de nommer je m'y retrouve correctement je l'est nomme comme ca du a mon héritage du C :/


     



     


        DBAccess *dba = [[DBAccess alloc] init];


        NSString *requete = [NSString stringWithFormat: @SELECT * FROM listForm WHERE %@='%@'",


                            [NSString stringWithFormat:@cmp_id],


                            [NSString stringWithFormat:@%@", form.cmpId]];


        NSMutableArray *cache = [dba getDataSQL: requete];


        NSError *error = nil;


        NSData *data = [[[cache objectAtIndex:0]objectAtIndex:1] dataUsingEncoding:NSUTF8StringEncoding];


        NSMutableArray *jsonData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];


        NSLog(@%@", jsonData);



     


    j'ai changer le nom de "Requete" si tu préfère inci 


     


    Par contre mon jsonData est toujours a (null) :/


  • Dans ce cas il faut que tu suives les étapes une par une et la tu verras ou ça foire. C'est un programme séquentiel, donc :


     


    Il faut vérifier NSString *requete si elle est bonne.


    Si requête est Ok pour toi, dans ce cas il faut tester  la variable cache NSMutableArray *cache =..    


    ....

  • AliGatorAliGator Membre, Modérateur
    Et puis y'a un paramètre error pour récupérer l'erreur, faudrait p'tet l'utiliser aussi, et te mettre à  déboguer un peu pas à  pas, plutôt que laisser samir faire tout le boulot pour toi ?
  • KiraxKirax Membre
    août 2014 modifié #19

    Ha ta raison c'est pas mal --"


     



     


     


    Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn't be completed. (Cocoa error 3840.)" (No string key for value in object around character 6.) UserInfo=0x17655c20 {NSDebugDescription=No string key for value in object around character 6.}


     Visiblement il lui manque une key donc je vais l'intégrer 


  • AliGatorAliGator Membre, Modérateur
    Ah ben voilà  tu l'as donc ta raison. Ton JSON n'est pas valide il y a une erreur de syntaxe JSON au caractère 6.

    Tu peux utiliser des outils en ligne comme http://jsonlint.com/ pour valider tes JSON et mieux comprendre quelle est l'erreur de syntaxe dans ton JSON. Mais au final il faudra corriger le problème sur ton serveur (celui qui t'envoie le JSON à  l'origine) car s'il t'envoie de la m*rde, tu vas pas pouvoir en faire grand chose ;)
  • non en faite le serveur m'envoie un truc propre mais c'est de ma faute quand je l'ajoute dans ma BDD je lui dit de prendre la valeur de data et du coup il met juste ca valeur en faite c'est logique mais a diagnostiquer c'est chaud fin bref pour cette erreur la c'est bon mais il m'en donne d'autre mdr


     



     


    Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn't be completed. (Cocoa error 3840.)" (JSON text did not start with array or object and option to allow fragments not set.) UserInfo=0x1663e610 {NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.}



     


    ca va surment finir par passer donc je les résous une par une

  • AliGatorAliGator Membre, Modérateur
    août 2014 modifié #22
    Mouais, je vois pas trop en quoi c'est chaud à  diagnostiquer ^^ les erreurs sont plutôt claires ;)

    1) En faisant du debug tout ce qu'il y a de plus classique (breakpoint, pas à  pas, ...) tu peux voir tout de suite ce qui cloche (genre ta variable n'est pas du type que tu penses, ou n'a pas le contenu auquel tu t'attendais, etc).

    2) Les warnings sont aussi là  pour quelque chose, il faut les lire et surtout les corriger.
    Là  clairement vu le code que tu avais, il n'y avait même pas besoin de lancer l'appli pour voir que ça allait crasher, tu avais forcément un warning qui te disait que "dataUsingEncoding:" n'était pas une méthode qui pouvait être appliqué à  ta variable data de type NSData.
    Donc commence par corriger tous tes warnings, ils ne sont pas là  pour rien et ils sont importants et t'indiquent bien souvent toutes les erreurs classique.

    3) En lançant le Static Analyzer de Xcode (Menu Product->Analyze ou [Commande-Maj-B]) Xcode te détectera même encore + de choses, t'indiquant les problèmes potentiels que tu pourrais avoir dans ton code. Et ce toujours avant même de compiler et de te rendre compte après-coup que ça crash, mais plutôt en te les signalant avant pendant que tu codes.


    Si avec tous ces outils-là  tu ne t'en sors pas pour des bugs aussi triviaux... j'imagine mm pas le jour où tu rencontreras une RaceCondition dans du code Multi-Thread :D
  • KiraxKirax Membre
    août 2014 modifié #23

    Ouais je vais regarder une par une mais je me demandais si cetait pas plus simple de transformer la case que je veut en json la stoquer et faire passer apres un pars dessus :/


     


    20min plus tard ...


     


    P..ain j'aurais du faire cela dès le début !


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