upload lent
Jijo
Membre
Bonjour,
J'ai une fonction qui envoie une image encodée en base 64 par le biais d'une requête xml-rpc.
Cela fonctionne trés bien, le seul problème c'est que cela est lent.
Voici ci-dessous ma fonction:
- (void)upload:(NSString*)session Epath:(NSString*)path Efilename:(NSString*)filename {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
// URL du serveur
NSURL * url=[NSURL URLWithString:@"http://url-server"];
// methode appelée
NSString * methode=@methode;
// création du webservice
WSMethodInvocationRef webservice = WSMethodInvocationCreate ((CFURLRef) url, (CFStringRef) methode, kWSXMLRPCProtocol);
// création du dictionnaire contenant la structure
NSMutableDictionary * member =[[NSMutableDictionary alloc] init];
NSData * myData = [NSData dataWithContentsOfFile:path];
// remplissage de ce dictionnaire
[member setObject:@12345a12345b12345c12345d forKey:@key];
[member setObject:session forKey:@session];
[member setObject:myData forKey:@data];
[member setObject:filename forKey:@filename];
// création du dictionnaire contenant les paramètres du web service
NSDictionary * params=[NSDictionary dictionaryWithObject:member forKey:@inutile];
[member release];
// mise en place des paramètres dans l'appel au web service
WSMethodInvocationSetParameters(webservice, (CFDictionaryRef)params, NULL);
// utilisation du flag de debug pour observer le xml généré
//WSMethodInvocationSetProperty(webservice, kWSDebugOutgoingBody, kCFBooleanTrue);
// exécution du web service
NSDictionary * resultat =(NSDictionary *)WSMethodInvocationInvoke(webservice);
[pool release];
}
Request format
<?xml version="1.0" encoding="UTF-8"?>
<methodCall>
<methodName>methode</methodName>
<params>
<param>
<value><struct>
<member><name>key</name>
<value><string>12345a12345b12345c12345d</string></value>
</member>
<member><name>session</name>
<value><string>0f16a26a812a1621b673211123501af9</string></value>
</member>
<member><name>data</name>
<value><base64>binary data</base64></value>
</member>
<member><name>ï¬lename</name>
<value><string>ï¬lename.jpg</string></value>
</member>
</struct></value>
</param>
</params>
</methodCall>
Je ne sais pas si on peut accélérer la fonction ou si on peut effectuer des threads pour envoyé plusieurs photos en même temps.
Merci
J'ai une fonction qui envoie une image encodée en base 64 par le biais d'une requête xml-rpc.
Cela fonctionne trés bien, le seul problème c'est que cela est lent.
Voici ci-dessous ma fonction:
- (void)upload:(NSString*)session Epath:(NSString*)path Efilename:(NSString*)filename {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
// URL du serveur
NSURL * url=[NSURL URLWithString:@"http://url-server"];
// methode appelée
NSString * methode=@methode;
// création du webservice
WSMethodInvocationRef webservice = WSMethodInvocationCreate ((CFURLRef) url, (CFStringRef) methode, kWSXMLRPCProtocol);
// création du dictionnaire contenant la structure
NSMutableDictionary * member =[[NSMutableDictionary alloc] init];
NSData * myData = [NSData dataWithContentsOfFile:path];
// remplissage de ce dictionnaire
[member setObject:@12345a12345b12345c12345d forKey:@key];
[member setObject:session forKey:@session];
[member setObject:myData forKey:@data];
[member setObject:filename forKey:@filename];
// création du dictionnaire contenant les paramètres du web service
NSDictionary * params=[NSDictionary dictionaryWithObject:member forKey:@inutile];
[member release];
// mise en place des paramètres dans l'appel au web service
WSMethodInvocationSetParameters(webservice, (CFDictionaryRef)params, NULL);
// utilisation du flag de debug pour observer le xml généré
//WSMethodInvocationSetProperty(webservice, kWSDebugOutgoingBody, kCFBooleanTrue);
// exécution du web service
NSDictionary * resultat =(NSDictionary *)WSMethodInvocationInvoke(webservice);
[pool release];
}
Request format
<?xml version="1.0" encoding="UTF-8"?>
<methodCall>
<methodName>methode</methodName>
<params>
<param>
<value><struct>
<member><name>key</name>
<value><string>12345a12345b12345c12345d</string></value>
</member>
<member><name>session</name>
<value><string>0f16a26a812a1621b673211123501af9</string></value>
</member>
<member><name>data</name>
<value><base64>binary data</base64></value>
</member>
<member><name>ï¬lename</name>
<value><string>ï¬lename.jpg</string></value>
</member>
</struct></value>
</param>
</params>
</methodCall>
Je ne sais pas si on peut accélérer la fonction ou si on peut effectuer des threads pour envoyé plusieurs photos en même temps.
Merci
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
C'est bien ma fonction qui est longue à encoder un fichier en base 64 et à l'envoyer.
Base64 encoding in Cocoa
Je bosse beaucoup avec gsoap, je peux te dire que si je m'amusais à encoder / décoder tous les blobs en base-64 ça serait la mort
Je ne connais pas trop les threads mais cela peut il résoudre mon probléme pour la vitesse, en envoyant des photos en simultanées par exemple?
Car comparé à d'autre plugin d'iPhoto je suis lent.
Merci
Tu peux pré-traiter plusieurs images à la fois en les convertissant via des threads... mais en envoyer plusieurs à la fois ça risque d'être plus le bazar qu'autre chose !
Du coup avec cette fonction je ne peux pas utiliser ton raisonnement .
J'ai posté un exemple de ma fonction pour le montrer.
Collez mon code dans le main.m d'une appli cocoa.
Ensuite il suffit de remplacer à la ligne NSString *path = @/Users/nomUSER/Desktop/test.png"; nomUSER par votre nom de session et de créer une image du nom test.png sur votre bureau. Créez en une petite de préférence.
Je ne sais pas si je peux retravailler ma fonction ou si je dois tout recommencer afin d'encoder et ensuite envoyé la requête.
PS: Ne vous inquiétez pas pour la méthode et l'url du serveur qui n'ont rien à voir avec ce que je fais. C'est juste que pour générer une requête xml-rpc il faut une url valide.
// URL du serveur
NSURL * url=[NSURL URLWithString:@"http://betty.userland.com/RPC2"];
// methode appelée
NSString * methode=@maMethode;
Ma fonction elle encode qu'a l'envoie de la requête.
Je n'arrive pas à refaire pour mon cas.
:crackboom:-
Il utilise des catégories, ce qui permet de rajouter en l'occurence les méthodes [tt]encodeBase64[/tt] et [tt]encodeBase64WithNewlines:[/tt] directement dans la classe NSData de Cocoa.
Du coup quand tu as un [tt]NSData* d[/tt] que tu veux encoder en Base64 (dans ton cas le NSData représentant ton image), il suffit de faire [tt]NSString* base64encoded = [d encodeBase64];[/tt] pour récupérer la chaà®ne base64 correspondant à tes NSData.
Pourtant j'ai mis les includes comme tu m'a dis pour openssl
#include <openssl/bio.h>
#include <openssl/evp.h>
voici les erreurs
Ce ne sont pas des erreurs de compilation mais de "linking". Autrement dit, le code est correct, et est déjà compilé, mais les différents morceaux de codes compilés ne peuvent être liés les uns aux autres car il en manque des bouts.
Exemple : grâce à tes headers, tu dis au *compilateur* "je vais utiliser telles fonctions, dont les prototypes sont les suivants". Le compilateur te croit sur parole, et génère du code prêt à appeler ces fonctions (il sait comment gérer la pile pour les différents types de paramètres prévus pour ces fonctions, même s'il ne sait pas encore où trouver les fonctions en question).
Mais au moment de finaliser l'exécutable, il doit réaliser les liens, c'est-à -dire qu'à chaque appel de fonction, il doit aller chercher la véritable addresse de la fonction, dans le bon module, et insérer cette addresse à l'endroit prévu.
Dans ton exemple, il te manque un lien vers une bibliothèque de OpenSSL.
S'il existait un "framework OpenSSL" sous MacOS, il suffirait de glisser ce framework dans les dépendances de ton projets, et ce serait fait automatiquement. Mais bon, OpenSSL est distribué sous forme de bibliothèques dans /usr/lib.
Dans ton exemple, il te manque libcrypto.dylib
Pour la rajouter, spécifie -lcrypto dans les "Other Linker flags" de ta target.
Au passage, libcrypto étant standard sous MacOS (elle "fait partie" de l'OS), tu peux linker tranquillement avec la libcrypto de base, qu'il trouvera tout seul dans /usr/lib, et que tu n'as pas besoin d'embarquer dans ton appli. Ce serait différent pour une bibliothèque non standard.
J'ai été disert, mais ça fait pas de mal :-)
+
Chacha
Cela marche nikel.
Cependant je me suis rendu compte que toute valeur de type NSData est encodée en base 64 lors de la génération et l'envoie de la requête.
Du coup inévitablement mon image de type NSData est encodée lors de l'envoie.
Ensuite j'ai essayé un framework XMLRPC open source. Mais là aussi c'est la même chose.
Ne pouvant donc par remédier à ce problème je voudrai savoir si quelqu'un savais obtenir le nombre d'octet envoyé pour donner un sentiment de vitesse à l'utilisateur.
exemple pour le plugin flikR
Si non, ça manque...
NSString *path = @/Users/nomUser/Desktop/image.png;
// récupération du fichier
NSData * data = [NSData dataWithContentsOfFile:path];
// encodage en base 64
NSString * base64encoded =[data encodeBase64];
// conversion de NSString en NSData
const char * utfString = [base64encoded UTF8String];
NSData * Data = [NSData dataWithBytes: utfString length: strlen(utfString)];
Mais cela est inutile car Data sera réencodé à l'envoie. Au final le fichier envoyé sera encodé 2 fois en base 64.
L'upload est désormais rapide.
Cela dit j'aimerai bien compter les octets envoyés ou avoir un pourcentage sur la progression de l'upload. Par contre je n'ai aucune idée pour le faire.