2009-06-30 8 views
7

sto ottenendo un'immagine su HTTP, utilizzando NSURLConnection, come segue -iPhone - dati corrotti JPEG per l'immagine ricevuti su HTTP

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]; 
} 

Di solito funziona bene, ma a volte sto vedendo questo ottenere registrato -: Dati JPEG corrotti: fine prematura del segmento di dati

A questo punto, l'immagine non viene visualizzata completamente. Ne vedrò forse il 75%, e poi l'angolo in basso a destra è una scatola grigia.

Qualche idea su come affrontare questo problema? Sto costruendo la mia immagine in modo improprio?

+0

mi sono state scaricando molte immagini e non hanno ancora visto questo. L'immagine è estremamente grande? Succede su altri dispositivi (computer, simulatore)? –

+0

Non è particolarmente grande, no. E lo vedo sia sull'iPhone che sul simulatore (ma non colpendo l'immagine tramite un browser web). – bpapa

+0

Si prega di controllare anche le connessioni Internet. –

risposta

9

Il tuo codice HTTP sembra corretto. È possibile che si desideri registrare la dimensione dei dati ricevuti una volta terminato il caricamento e confrontarli con le dimensioni previste dell'immagine sul server. Se è la dimensione prevista, allora forse l'immagine stessa è danneggiata sul server.

+7

Grazie, questo ha aiutato molto. Così facendo ho capito che era un mio errore di programmazione (stavo accidentalmente spegnendo la richiesta due volte). – bpapa

+1

Stavo facendo la stessa cosa di bpapa. Sembra che se si lanciano 2 diverse NSURLConnections sullo stesso URL, il risultato finale saranno dati corrotti. – CornPuff

+1

Ho avuto lo stesso identico problema, ed era effettivamente dalla stessa causa: 2 connessioni alla stessa immagine. –

1

Ho visto anche questo. Se si salvano i dati in un file e poi si leggono i dati in un'immagine, funziona perfettamente. Sospetto che ci siano informazioni dell'intestazione http nei dati dell'immagine jpeg.

Spero che qualcuno trovi una soluzione a questo perché il salvataggio su file soluzione fa schifo.

// problem 

UIImage *newImage = [UIImage imageWithData:receivedData]; 

// crappy workaround 

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

Provato e non cambia nulla – Abramodj

3

ASI-HTTP può risolvere questo problema.

NSURL *coverRequestUrl = [NSURL URLWithString:imageStringURL]; 
ASIHTTPRequest *coverRequest = [[ASIHTTPRequest alloc] initWithURL:coverRequestUrl]; 
[coverRequest setDelegate:self]; 
[coverRequest setDidFinishSelector:@selector(imageRecieved:)]; 

[appDelegate.queue addOperation:coverRequest]; 
[appDelegate.queue go]; 

La mia variabile di coda in appDelegate è oggetto di coda ASINetwork. Perché invio una richiesta asincrona, quindi la uso.

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

Ho risolto questo problema utilizzando un NSMutableDictionary.

NSMutableDictionary *dataDictionary; 

Nella mia funzione loadData, definisco miei dati:

NSMutableData *receivedData = receivedData = [[NSMutableData alloc] init]; 

Poi ho caricare i dati nel mio dizionario, dove la chiave è [descrizione theConnection] e l'oggetto è i miei dati.

[dataDictionary setObject:receivedData forKey:[theConnection description]]; 

In questo modo nei delegati, posso cercare l'oggetto di dati corretti per la connessione che viene passato al delegato e salvare l'istanza di dati corretti altrimenti io alla fine con il problema munging/corruzione JPEG.

In didReceiveData, metto:

//get the object for the connection that has been passed to connectionDidRecieveData and that object will be the data variable for that instance of the connection. 
NSMutableData *theReceivedData = [dataDictionary objectForKey:[connection description]]; 

//then act on that data 
[theReceivedData appendData:data]; 

Analogamente, in didReceiveResponse, metto:

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

E in connectionDidFinishLoading: NSMutableData * theReceivedData = [dataDictionary objectForKey: [descrizione del collegamento]] ; img = [[UIImage alloc] initWithData: theReceivedData];

E questo sembra funzionare molto bene. A proposito, il mio codice è basato su Apple's tutorial for NSUrlConnection con l'aggiunta di un NSMutableDictionary per tenere traccia delle singole connessioni. Spero che aiuti. Fammi sapere se vuoi che pubblico il mio codice completo di gestione delle immagini.

+0

Io uso lo stesso metodo. Funziona alla grande. Assicurati di assegnare e avviare l'oggetto dati nel dizionario prima di inviare la richiesta. Altrimenti finirai con lo stesso errore – JWKothe

0

Anche la copia del contenuto NSData utilizzando receivedData = [NSData dataWithBytes:receivedData.bytes length:receivedData.length] può essere utile (ed è più efficiente rispetto al salvataggio e alla lettura dal disco).

Un possibile motivo per questo è che l'oggetto originale ricevuto Data non conserva il suo contenuto (ad es. Quando viene creato utilizzando [NSData dataWithBytesNoCopy:length:]) e si tenta di leggerli dopo essere stati liberati.

Questo è probabile quando si verifica questo problema su un altro thread dal thread che ha creato l'oggetto NSData.

Problemi correlati