Web Services avec WSMakeStubs

syncsync Membre
04:43 modifié dans API AppKit #1
Bonjour,

Je suis actuellement sur un essai de projet d'interaction entre un webservice et une petite application en cocoa. J'utilise l'utilitaire fourni par apple dans son répertoire /Developer/Tools nommé WSMakeStubs pour générer 4 fichiers permettant de créer.

Quelqu'un aurait-il déjà  joué avec cet utilitaire et surtout aurait-il intégré les fichiers générés dans son propre projet ?

Je n'arrive pas à  utiliser les fichiers générés par WSMakeStubs.

Je les intègre dans la petite app, j'ajoute le framework CoreService, ensuite je place sur mon nib un bouton permettant d'exécuter une action. Et là  je suis bloqué dans mon action du bouton j'aimerai bien appeler mon webservice et récupèrer les données pour commencer juste en affichant le NSDictionnary dans un log.

Quelqu'un aurait-il l'âme assez généreuse pour donner une petite explication???

<3 <3 <3 <3 <3 <3 <br />
Merci d'avance et bonne journée

Réponses

  • BruBru Membre
    04:43 modifié #2
    Basiquement, l'appel à  un webservice se fait de la manière (grosso-modo, et de mémoire) suivante :

    <br />NSURL *url;<br />NSString *methode;<br />WSMethodInvocationRef ws;<br />NSDictionary *parametres, *resultat;<br /><br />// création du webservice<br />url=[NSURL URLWithString:@&quot;http://www.domaine.com/webservice/service.asmx&quot;];<br />methode=@&quot;UneMethode&quot;;<br />ws=WSMethodInvocationCreate((CFURLRef)url, (CFStringRef)methode, kWSSOAP2001Protocol);<br /><br />// mise en place des paramètres<br />parametres=[NSDictionary dictionaryWithObjectsAndKeys:@&quot;valeur&quot;, @&quot;param1&quot;, nil];<br />WSMethodInvocationSetParameters(ws, (CFDictionaryRef)parametres, NULL);<br /><br />// exécution du webservice<br />resultat=(NSDictionary *)WSMethodInvocationInvoke(ws)<br /><br />// analyse du résultat<br />if (WSMethodResultIsFault((CFDictionaryRef)resultat))<br />{<br />&nbsp; &nbsp; // erreur... affichage de l&#39;erreur<br />&nbsp; &nbsp; NSLog(@&quot;erreur :%@&quot;, [resultat objectForKey:(CFStringRef)kWSFaultString]);<br />}<br />else<br />{<br />&nbsp; &nbsp; // pas d&#39;erreur, affichage du resultat<br />&nbsp; &nbsp; NSLog(@&quot;résultat : %@&quot;, [resultat objectForKey:(CFStringRef)kWSMethodInvocationResult]);<br />}
    


    Dans l'exemple, le webservice a une une méthode nommée UneMethode. Cette méthode accepte un argument de type chaà®ne et de nom param1 (ici, on passe la chaà®ne "valeur" dans ce paramètre). Un résultat est renvoyé.

    A toi de tester et développer cet exemple.

    .
  • syncsync Membre
    juillet 2006 modifié #3
    Waou !!!  <3 <br />
    Merci beaucoup pour la réponse...

    Anthony
  • AliGatorAliGator Membre, Modérateur
    juillet 2006 modifié #4
    Si c'est pour récupérer ça dans un NSTableView, il n'y a aucun intérêt à  réagencer tes données comme ça. Il te suffit de bien écrire tes méthodes de dataSource.
    - (int)numberOfRowsInTableView:(NSTableView *)aTableView<br />{<br />  // On prend un des tableaux, et on compte le nombre d&#39;éléments<br />  return [[resultOfService objectForKey: @&quot;OutputCodeAdresseTable&quot;] count];<br />}<br /><br />- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex<br />{<br />  return [[resultOfService objectForKey: [aTableColumn identifier]] objectAtIndex: row];<br />  // au lieu de faire si tu avais modifié la structure de ton tableau un truc comme :<br />  // return [[resultOfService objectAtIndex:row] objectForKey: [aTableColumn identifier]];<br />}
    
    Donc il suffit juste au moment où tu dois fournir la bonne donnée pour une rangée et une colonne donnée, avec cette méthode, de le faire dans le bon ordre qui correspond à  la façon dont ton tableau résultat resultOfService est agencé.


    Bien sûr (mais ça que ce soit dans un cas comme dans l'autre, quelle que soit ta structure de dictionnaire utilisé pour nourir ta TableView), il faut que tu définisses pour chaque colonne (de ta TableView à  3 colonnes) dans IB les bon identifiers pour tes colonnes, donc respectivement "OutputCodeAdresseTable", "OutputPrenomAdresseTable" et "OutputNomAdresseTable".
    Là  je t'ai décrit comment faire dans l'éventualité où tu utilises des DataSource et pas les bindings, mais bon le principe est là  de toute façon.



    PS : Dans ton exemple plus haut j'imagine que tu voulais dire que ce qui est retourné c'est [tt]OutputNomAdresseTable = (Walterys, Walterys)[/tt] et [tt]OutputPrenomAdresseTable = (Henri, David)[/tt] et non pas l'inverse ;)

    [EDIT]Arf ben je vois que tu as édité ton post pour enlever ta question de comment inverser l'agencement de ton tableau reçu en résultat, donc ma réponse ne correspond plus à  rien :)[/EDIT]
  • syncsync Membre
    04:43 modifié #5
    Je voulais le réécrire mieux....

    C'est génial merci beaucoup pour la réponse...

    Anthony  bientot le week end :p
  • syncsync Membre
    juillet 2006 modifié #6
    Bonjour,

    Suite de l'épisode sur les WebServices...

    Je cherche à  faire des tests  sur les valeurs retournées pour afficher certaines valeures ou pas mais j'ai un problème d'encodage ????

    Dans la partie serveur webservice aucunes valeurs nulles ne sont retournées au client, je les remplace par "essai" (pour l'exemple), et donc j'essai de récupérer ces valeurs en faisant de la sorte:

          //Essai pour voir quel est le texte retourné<br />	NSString *string = [[resultOfService objectForKey:@&quot;OutputCodeAdresseTable&quot;] objectAtIndex:0];<br />	NSLog(@&quot;Valeur de string: %@&quot;, string);<br />	NSLog(@&quot;Valeur de string: %c&quot;, string);<br />	NSLog(@&quot;Valeur de string: %C&quot;, string);<br />	NSLog(@&quot;Valeur de string: %s&quot;, string);<br />	NSLog(@&quot;Valeur de string: %S&quot;, string);
    


    Dans le log ce qui est retourné:

    Valeur de string: Essai<br />Valeur de string: @<br />Valeur de string: ?<br />Valeur de string: `à„??<br />Valeur de string: ????R
    

    (Les caractères ne passent pas sur le forum)

    Afin d'y utiliser pour un test if mais true n'est jamais retrourné genre si je fais

    if (string == @essai)

    Toujours sur false comme string ne vaud pas @essai il doit être encodé d'une certaine façon!

    Mes questions ne sont jamais très claires mais j'espère que quelqu'un pourra me donner une solution.

    Merci déjà  pour tout !!!

    Bonne journée  :o
  • fouffouf Membre
    juillet 2006 modifié #7
    Je ne connais rien aux WebServices donc je pourrais pas t'aider sur ce point là  mais, il ya deja une erreure de code dans la comparaison : tu fais if (string == @essai) ce qui entraine non pas un test sur la chaine de caractère mais sur les pointeurs vers string d'une part et vers @essai de l'autre. Je pense que ca marchera mieux en utilisant if ([string isEqualTo:@essai]). Heu, autre petit détail, le log te retourne Essai et pas essai ;)
    Enfin, les 4 derniers log ne servent à  rien parce que string est un objet de type NSString* et pas un char* (une chaine de caractères C).
  • syncsync Membre
    04:43 modifié #8
    Merci beaucoup ça marche!  :adios!:
  • syncsync Membre
    04:43 modifié #9
    Bonjour,

    Encore un nouvel épisode dans la série Web Service.

    Aujourd'hui, la question que je me pose est comment récupérer des images à  travers un Web Service, ça parait un petit peu plus compliqué, étant donné que le serveur qui fournit les webservices encode en base64 les images dans un texte.

    Bonne journée

    Anthony
  • AliGatorAliGator Membre, Modérateur
    04:43 modifié #10
    J'ai jamais essayé mais n'aurais-tu pas la réponse en posant ta question ?
    Essaye de faire du décodage base64 des données reçues (ça c'est pas méchant) puis d'interpréter cette image comme une image bitmap, ou PNG, ...

    (Souvent le MIME-TYPE est précisé il me semble donc tu dois savoir de quel type de format d'image il s'agit, non ?)
    J'ai pas de code à  te proposer sous la main, mais l'idée est de faire un décodage Base64 (y'a sûrement de quoi faire ça) puis destocker le résultat décodé dans une ImageRep ayant le format adéquat en recopiant les bits décodés...
  • syncsync Membre
    04:43 modifié #11
    J'étais justement entrain d'explorer cette voie...

    J'ai trouvé 2 pages intéressantes:

    http://www.dribin.org/dave/blog/archives/2006/03/12/base64_cocoa/

    et

    http://www.cocoadev.com/index.pl?BaseSixtyFour
    (avec base exemple)

  • Eddy58Eddy58 Membre
    04:43 modifié #12
    Dans le code du SSCrypto framework, tu as le nécessaire (classe base64). :)
  • syncsync Membre
    04:43 modifié #13
    Bonjour,

    Suite de feuilleton des webServices...

    Le problème est le suivant:

    J'exécute une requête à  mon web service, la requête me retourne le fichier xml de la réponse avec comme contenu "principal":

    <outPictureBlob xsi:type="xsd:base64Binary">
    iVBORw0KGgoAAAANSUhEUgAAAGMAAABvCAIAAAB3m+m5AAAABGdBTUEAANkD... etc

    C'est donc une image en base64 que j'essaie de récupérer donc je fais un:

    NSData *imageData = [imgResult objectForKey:@outPictureBlob];
    (imgResult est le dictonnaire retourné suite à  la requête au service web)

    Et pour continuer j'aimerai convertir le NSData imageData en string afin de le passer dans la méthode de décodage de base64 et de l'insérer à  nouveau dans une image.

    Le problème c'est que je ne sais pas quel encodage utiliser lors de la conversion du NSData imageData, j'ai essayé ceci:

    NSString *photoString = [[NSString alloc] initWithBytes:[mesDatas bytes] length:[mesDatas length] encoding:NSASCIIStringEncoding];

    Mais la méthode de décode de base64 n'arrive pas à  récupérer l'image quelqu'un connaitrait-il la solution? Je suspecte NSASCIIStringEncoding qui n'est pas le bon type d'encodage.

    Merci beaucoup et bonne journée

    Anthony


  • BruBru Membre
    04:43 modifié #14
    Essaie d'utiliser NSUTF8StringEncoding à  la place de NSASCIIStringEncoding (ce dernier ignore le 8ème bit des caractères).

    .
  • syncsync Membre
    04:43 modifié #15
    Merci pour la réponse. Après un bref test avec un NSUTF8StringEncoding j'obtiens un string nulle...

    >:D :-\\
  • BruBru Membre
    04:43 modifié #16
    Es-tu sûr que ton NSData est correct ?
    En effet, pour moi, tu devrais plutôt récupérer un NSString du dictionnaire du résultat...

    De toute façon, pour que [NSString alloc] init] renvoie NULL, c'est que ton NSData est tout pourri.
    As tu fait un [tt]NSLog(@%@ %@", [imageData className], imageData);[/tt] pour voir ce qu'est/contient l'objet imageData (ou mesDatas, puisque dans l'exemple pas clair, tu utilises ces 2 objets) ?

    .
  • syncsync Membre
    04:43 modifié #17
    Pour le log ça donne NSCFData ce qui veut donc dire que c'est un NSData....

    Oui effectivement je devrais plutôt récupérer une string de mon dictonnaire de résultat mais je ne sais pas vraiment comment faire....

    J'utilise uniquement imageData.
  • syncsync Membre
    septembre 2006 modifié #18
    De plus lorsque j'utlise NSASCIIStringEncoding le log me retourne ceci ‰‰PNG (avec point d'interrogation devant et derrière à  l'envers), l'image envoyé par mon web Service est bien au format png il doit y avoir quelque chose que je loupe....


    Ci-joint un log de:

    NSLog(@&quot;imgResult: %@&quot;, imgResult);
    


    et de:

    NSData *imageData = [imgResult objectForKey:@&quot;outPictureBlob&quot;];<br />NSLog(@&quot;image png en data: %@&quot;, imageData);
    



    [Fichier joint supprimé par l'administrateur]
  • BruBru Membre
    04:43 modifié #19
    Attends là , il me semble que ton NSData imgResult n'est pas en mime...
    Donc, peut-être  point besoin de le démimer !

    Essaie directement de faire :
    <br />NSImage *img;<br />img=[[NSImage alloc] initWithData:imgResult]<br />
    

    pour voir...

    .
  • syncsync Membre
    04:43 modifié #20
    ça marche très bien merci beaucoup pour le suivi de ce sujet ça fait vraiment plaisir...

    Bonne journée

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