Download d'image depuis un serveur => Image JPEG corrompue....

LeChatNoirLeChatNoir Membre, Modérateur
Slt,

Je me heurte à  un nouveau pb... Pfffff, le dev n'est pas un long fleuve tranquille !

Je download des images depuis un serveur. En wifi ou avec une connexion Edge ou 3G correcte, no problemo.
Seulement voilà ...
Quand je suis dans le train et que je passe par des zones perturbées, la connexion rame puis le download fini par se terminer correctement.

Seulement voilà , l'image JPEG est corrompue. Je le vois de 2 manières : l'image en elle même est soit tronquée, soit toute difforme.
Et le 2eme phénomène est que le debugger me remonte une erreur : Corrupt JPEG data: premature end of data segment...

Le pb, c'est que je met mes images en cache... Et comme il détecte pas d'erreur ben c'est bien naze :-(

La question est donc la suivante : y a t il moyen de détecter une corruption dans une image ?
De manière plus large, je ne comprend pas pourquoi aucune erreur n'est remontée ! Ca me donne du coup moyennement confiance en iOS... A moins que ce ne soit mon code ? Mais bon, j'ai qques doutes...

Merci de me rassurer :-)





Réponses

  • DrakenDraken Membre
    23:10 modifié #2
    Tu peux faire un cheksum de l'image pour vérifier son intégrité. Ceci dis je pense comme toi, c'est curieux que iOS ne vérifie pas la bonne qualité du téléchargement.

  • LeChatNoirLeChatNoir Membre, Modérateur
    23:10 modifié #3
    ah je tiens peut être un truc là ...
    J'ai pas de méthode didReceiveResponse...
    Or, quand iOS a commencé à  télécharger, il sollicite didReceiveData et c'est là  dedans que j'append mes data. Mais il semblerait que dans des zones ou le réseau déconne, il perd la connexion et la relance ensuite et recommence... Or, comme j'ai pas de didReceiveResponse, je réinitialise pas mes datas... Du coup, je me retrouve avec des fichiers foireux...

    Je teste ça demain. Ben c'est ballot comme tests ! Obligé d'attendre d'être en train  :P
  • LeChatNoirLeChatNoir Membre, Modérateur
    23:10 modifié #4
    Ah merde....

    C'était une bonne piste mais en fait nan...  :'(

    J'arrive en fait à  reproduire le bug même chez moi "grâce" au death grip de l'iphone 4 (je le serre dans ma main et la connexion se fige....).

    Donc même ave ma modif, c'est ko.... Le didresponse n'est appelé qu'une seule fois...

    Chiotte !!!!
  • LeChatNoirLeChatNoir Membre, Modérateur
    23:10 modifié #5
    Personne n'a d'idée ?
    J'ai lu qu'on pouvait vérifier les 2 premiers et les 2 derniers octets du fichier pour tester si c'est bien un début et une fin de jpeg...
    Mais bon, ça m'inquiète cette histoire...
    C'est quand même étrange qu'à  aucun moment je ne sois prévenu d'une quelconque corruption....
    :'( :'( :'( :'(
  • FKDEVFKDEV Membre
    juillet 2011 modifié #6
    Tu peux déjà  vérifier la taille reçu.
    Il y a une property qui te donne la taille attendu sur la response.

  • FKDEVFKDEV Membre
    23:10 modifié #7
    C'est quand meme bizarre que tu n'es pas d'erreur avec NSURLConnection quand ton download s'arrête.

    As-tu vérifié ton système de cache ?
    Es-tu certain de bien enregistrer tous les octets reçus ?
    Il pourrait y avoir un problème dans le calcul de la taille du fichier.
  • LeChatNoirLeChatNoir Membre, Modérateur
    23:10 modifié #8
    En désespoir de cause, je suis passé à  ASIHTTP...
    J'en suis bien content car le système de cache est béton mais...
    1 - j'ai pu reproduire le bug de la connexion foireuse... Un coup de death grip et hop, une image corrompue !
    2 - ASIHTTP récupère la taille du fichier avant téléchargement. Ca permet d'avoir une progressView ce qui est plutot bien. Mais.... ca marche qu'en wiFi ! Par mon opérateur (Bouygue), le progressView ne se fait pas ; après recherche sur le sujet, il s'avère que les opérateurs te font passer par des proxi et tu récupères pas le header HTTP de base du coup...

    Pffffffffff, le download sous iOs, c'est la galère !
    Au fur et à  mesure que j'avance, je me décourage....
    Quand la connexion est bonne, pas de soucis mais sinon.... galère ...

    Bon, je vais me résoudre à  l'imperfection....
    1 - je garde ASIHTTP pour son sytème de cache
    2 - je testerai si connexion wifi => progressview déterminée, sinon, progressView indéterminée
    3 - j'ajouterai un bouton pour vider le cache ou recharger les images dans le cas où ce genre de corruption arriverait....

    Voilà . Toujours décevant d'en arriver là .... Au départ, je pensais que mon code était fautif. La, avec ASIHTTP, je pense pas....

    :(
  • AliGatorAliGator Membre, Modérateur
    23:10 modifié #9
    Y'a une propriété dans ASIHTTPRequest pour demander une progress précise (me souviens plus de son nom, là  comme ça). Bon je crois qu'elle est à  YES par défaut, mais bon, ça vaut le coup d'aller vérifier
  • FKDEVFKDEV Membre
    23:10 modifié #10
    Question idiote : as-tu bien utilisé didFailWithError dans ton delegate ?

    - (void)connection:(NSURLConnection *)connection<br />&nbsp; didFailWithError:(NSError *)error<br />{<br />&nbsp; &nbsp; NSLog(@&quot;Connection failed! Error - %@ %@&quot;,<br />&nbsp; &nbsp; &nbsp; &nbsp;  [error localizedDescription],<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [[error userInfo] objectForKey:NSErrorFailingURLStringKey]);<br />}
    



    Voici un exemple d'utilisation de NSURLConnection, on y voit notamment l'utilisation de "expectedContentLength" (attention la taille attendue n'est pas systématiquement disponible, voir l'aide)

    -(NSURLRequest *)connection:(NSURLConnection *)connection<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; willSendRequest:(NSURLRequest *)request<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  redirectResponse:(NSURLResponse *)redirectResponse<br />{<br />&nbsp; &nbsp; [self resetData:redirectResponse];<br />&nbsp; &nbsp; return request;<br />}<br /><br />- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response<br />{<br />&nbsp; &nbsp; // this method is called when the server has determined that it<br />&nbsp; &nbsp; // has enough information to create the NSURLResponse<br />&nbsp; &nbsp; // it can be called multiple times, for example in the case of a<br />&nbsp; &nbsp; // redirect, so each time we reset the data.<br />	[self resetData:response];<br />}<br /><br />- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data<br />{<br />&nbsp; &nbsp; [self appendData:data];<br />}<br /><br />-(void)resetData:(NSURLResponse*)response<br />{<br />	fileSize = [response expectedContentLength];<br />	[receivedData setLength:0];<br />}<br />
    

  • LeChatNoirLeChatNoir Membre, Modérateur
    23:10 modifié #11
    Oui, oui, tout à  fait.
    Elle est bien positionnée.
    Quand je suis en WiFi, c'est nickel ! La progressBar progresse.
    Mais en 3G, niette, nada...

    D'autres ont ce pb et c'est lié soit à  la redirection de requêtes, soit à  un proxi que l'opérateur telecom paramètre par défaut.

    Au final, pas de solution, à  part un hack qui récupérerai la taille de l'image et qui initialiserai la taille attendue dans ASIHTTP.

    Mais bon, je préfère faire comme j'ai dit, tant pis...

  • LeChatNoirLeChatNoir Membre, Modérateur
    23:10 modifié #12
    oui oui, j'utilisais didFailWithError.
    Mais ça n'est pas appelé....
Connectez-vous ou Inscrivez-vous pour répondre.