7
votes

iPhone - Données JPEG corrompues pour l'image reçues sur http

Je reçois une image sur http, à l'aide de NsurlConnection, comme suit -

NSMutableData *receivedData;

- (void)getImage {
    self.receivedData = [[NSMutableData alloc] init];
    NSURLConnection *theConnection = // create connection
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {    
   [receivedData appendData:data];
}

-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
   [connection release];

   UIImage *theImage = [UIImage imageWithData:receivedData];
}


3 commentaires

J'ai téléchargé de nombreuses images et je n'ai pas encore vu cela. Est-ce que tu es image extrêmement grande? Est-ce que cela se produit sur d'autres périphériques (ordinateur, simulateur)?


Ce n'est pas particulièrement grand, non. Et je le vois sur l'iPhone et le simulateur (mais pas en frappant l'image via un navigateur Web).


Veuillez vérifier également vos connexions Internet.


5 Réponses :


9
votes

Votre code HTTP a l'air correct. Vous voudrez peut-être enregistrer la taille de la réceptionData une fois que cela a fait le chargement et la comparer à la taille attendue de l'image sur le serveur. Si c'est la taille attendue, alors peut-être que l'image elle-même est corrompue sur le serveur.


6 commentaires

Merci, cela a beaucoup aidé beaucoup. En faisant cela, j'ai réalisé que c'était ma propre erreur de programmation (je fusionné accidentellement la demande deux fois).


Je faisais la même chose que BPAPA. Il semble que vous lanciez 2 nsurlConnections différentes sur la même URL, le résultat final sera corrompu des données.


J'ai exactement le même problème, et c'était vraiment à partir de la même cause: 2 connexions à la même image.


L'erreur est créée car les deux connexions partageent la même source de données. Lorsque vous construisez des applications dans lesquelles des tâches spécifiques doivent tirer simultanément (que vous avez faites par inadvertance, il semble :)), vous devez avoir une source de données unique pour chaque connexion (un à un) ou créer un sémaphore pour que vos données mutables soient nécessaires. La source n'est pas sérialisée avec les résultats de plusieurs connexions à la fois (conditions de course). Le résultat final est la création de données corrompues ou incomplètes! (Que vous avez vécu).


@bpapa - où exactement dans votre code étiez-vous en train de tirer la demande deux fois? Basé sur ma sortie de journal, je pense que je fais de même, mais je ne comprends pas pourquoi seules certaines photos seraient appelées deux fois.


Je n'ai plus accès à ce code, mais je pense que c'était juste que je fais des erreurs étranges en tant que développeur iOS inexpérimenté en 09. :)



1
votes

Je l'ai vu aussi. Si vous enregistrez les données dans un fichier, puis lisez les données dans une image, cela fonctionne parfaitement. Je soupçonne qu'il y a des informations d'en-tête HTTP dans les données d'image JPEG.

J'espère que quelqu'un trouve une solution à cela car la solution de contournement de fichier Sauvegarde est suce. P>

// problem

UIImage *newImage = [UIImage imageWithData:receivedData];

// crappy workaround

[receivedData writeToFile:[NSString stringWithFormat:@"a.jpg"] atomically:NO];
UIImage *newImage = [UIImage imageWithContentsOfFile:@"a.jpg"];


1 commentaires

Essayé et ça ne change rien



3
votes

ASI-HTTP peut résoudre ce problème.

- (void)imageRecieved:(ASIHTTPRequest *)response
{
    UIImage *myImage = [UIImage imageWithData:[response responseData]];
}


0 commentaires

2
votes

J'ai corrigé ce problème en utilisant un nsmutmédictionnel.

NSMutableData *theReceivedData = [dataDictionary objectForKey:[connection description]];
[theReceivedData setLength:0];


1 commentaires

J'utilise la même méthode. Fonctionne très bien. Assurez-vous qu'Alloc et init l'objet de données dans le dictionnaire avant d'envoyer la demande cependant. Sinon, vous finirez avec la même erreur



0
votes

Copier le contenu Nsdata à l'aide de reçusData = [nsdata DatawithBytes: reçusData.bytes Longueur: reçusData.length] peut être utile également (et il est plus efficace que d'économiser et de lire à partir du disque). < / p>

Une raison éventuelle de ceci est que l'objet original reçusData ne conserve pas son contenu (par exemple, lors de la création de [nsdata DatawithBytesnocopy: longueur:] ) et que vous essayez de les lire après leur libération.

Ceci est probable lorsque vous rencontrez ce problème sur un autre thread du fil qui a créé l'objet nsdata .


0 commentaires