Nessun Dato Restituito Utilizzando NSURLConnection In Modo Asincrono
-
16-09-2019 - |
Domanda
Ho un cavolo di tempo con qualcosa che sembra piuttosto
semplice, ma non riesco a far funzionare.Sto costruendo un
app per iPhone che consente di recuperare i dati da un host web.Sto cercando di
stabilire una connessione asincrona per l'host come voglio mantenere il
dispositivo liberato durante la connessione.(sendSynchronousRequest si blocca
il telefono fino a quando la richiesta è fatta.) Qui è il collegamento con il mio codice:
//temp url to see if data is returned:
NSURL *theURL = [NSURL URLWithString:@"http://www.theappleblog.com/feed"];
NSURLRequest *dataRequest = [NSURLRequest requestWithURL:theURL
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
timeoutInterval:60];
/* establish the connection */
theConnection = [[NSURLConnection alloc]
initWithRequest:dataRequest
delegate:self
startImmediately:YES];
if (theConnection == nil) {
NSLog(@"Connection Failure!");
self.urlData = nil;
} else {
self.urlData = [[NSMutableData data] retain];
}
Ho dei metodi delegati impostare:
-(void)connection:(NSURLConnection *)connection
didReceiveResponse:(NSURLResponse*)response
{
[urlData setLength:0];
UIApplication *application = [UIApplication sharedApplication];
application.networkActivityIndicatorVisible = YES;
NSLog(@"Received Response!");
}
-(void)connection:(NSURLConnection *)connection
didReceiveData:(NSData*)incrementalData
{
[self.urlData appendData:incrementalData];
NSNumber *resourceLength = [NSNumber
numberWithUnsignedInteger:[self.urlData length]];
NSLog(@"resourceData length: %d", [resourceLength intValue]);
NSLog(@"filesize: %d", self.urlDataSize);
NSLog(@"float filesize: %f", [self.urlDataSize floatValue]);
}
-(void)connectionDidFinishLoading:(NSURLConnection*)connection
{
NSLog(@"Connection finished loading\n");
NSLog(@"Succeeded! Received %d bytes of data",[urlData length]);
_isFinished = YES;
UIApplication *application = [UIApplication sharedApplication];
application.networkActivityIndicatorVisible = NO;
}
- (void)connection:(NSURLConnection *)connection
didFailWithError:(NSError *)error
{
NSLog(@"Error: %@",[error localizedDescription]);
}
Come potete vedere, ho un battello carico di messaggi di log, in quanto volevo
per vedere se nulla era venuta a tutti.Il mio test di connessione
torna VERO, ma i dati non viene mai caricato.Come ho detto, sono sicuro che
Devo fare (o non fare) qualcosa davvero stupido.Ma che cosa?
Qualsiasi aiuto sarebbe molto apprezzato.
Grazie, Lorenzo
Soluzione
Questo non risponde alla tua domanda direttamente, ma si potrebbe prendere in considerazione esaminando Ben Copsey di biblioteca ASIHTTPRequest
, che avvolge le classi CFNetwork
e comprende asincrono, il codice richiesta threaded che prende un sacco di lavoro da fare questo in modo corretto.
Altri suggerimenti
Il problema era che stavo continuando il flusso del programma e non fermarsi per consentire il collegamento per completare il download. Grazie per tutti i suggerimenti.
Alcuni suggerimenti:
-
Nel tuo primo frammento, invece di cercare
theConnection
assegnando aself.theConnection
per assicurarsi che i metodi di proprietà accessor sono chiamati. In vari luoghi interscambio ancheself.urlData
eurlData
. Potrebbe desiderare di farli tutti coerenti passando attraversoself
. -
Si consiglia di effettuare la
dataRequest
una proprietà come bene e passare attraversoself
per assicurarsi che venga mantenuta. -
self.urlData = [[NSMutableData data] retain];
- non dovrebbe essere necessario quel qualcosa in più trattenere. Passando attraversoself
fa per voi. L'extra mantengono la farà così l'oggetto verrà attaccare intorno e perdite, anche quando tutto è fatto. -
In una nota correlata, nei vostri NSLogs assicurarsi di stampare il numero di trattenere per ogni oggetto. Inoltre, si consiglia di avere una routine di pulizia generale intorno a rilasciare queste strutture (o set
self.foo = nil
) così in qualsiasi momento se barfs fuori è possibile chiamare la routine per ottenere le cose ripulito. -
Ottenere una copia di Carlo o WireShark (o tcpdump corsa nella console) e guardare il traffico di rete. Vi aiuterà millimetrica in quale fase del flusso è mancato.
pensiero iniziale - è l'oggetto che ha tutto questo codice viene mantenuto correttamente? Potrebbe essere che è stato rilasciato, e deallocando così la connessione ...
In caso contrario, si dovrebbe almeno vedere la risposta.
Nulla, ovviamente, sbagliato lì.Ho il codice che è sostanzialmente la stessa e funziona bene.Le uniche differenze che vedo sono:
Io uso NSURLRequestUseProtocolCachePolicy invece di NSURLRequestReloadIgnoringLocalCachedata
Io uso connessione=[[NSURLConnection alloc] initWithRequest:theRequest delegato:self];invece di specificare startImmediately:SÌ (in quanto è l'impostazione predefinita)
Sarebbe utile sapere che, se del caso, del delegato metodi sono sempre chiamato.Almeno, si dovrebbe ottenere almeno l'uno o l'altro di connectionDidFinishLoading o connectionDidFail di essere chiamato.Se no, allora qualcosa è probabilmente sbagliato con il delegato di installazione, sei ASSOLUTAMENTE sicuro che il metodo delegato firme siano corrette, e che stai passando l'elemento di destra come il delegato?
E 'difficile a zero su qualsiasi cosa in quanto non è chiaro dalla tua domanda che, se una qualsiasi delle dichiarazioni NSLog esegue. Si prega di essere un po 'più chiaro circa i risultati che state ottenendo.
Da un rapido sguardo l'unica cosa che si presenta come un potenziale problema è che avete una condizione di competizione quando si imposta la connessione. Se la rete è particolarmente veloce c'è una piccola possibilità, ma diverso da zero che di collegamento: didReceiveData: saranno chiamati prima self.urlData è stato allocato. Io suggerirei di assegnazione URLData sia prima di iniziare il collegamento o di collegamento: didReceiveResponse:. Per evitare che questo
Se questo non risolvere il problema, è necessarioulteriori informazioni da voi.
Dici questo codice funziona bene con il metodo asincrono? Testare l'URL, reindirizza ad un altro, così che cosa se si implementano i metodi di reindirizzamento delegato? Che cosa succede se si tenta alcuni URL differenti?
è l'applicazione altrimenti reattivo? È il runloop in esecuzione? Che cosa fa l'applicazione fa dopo aver avviato la richiesta - fa tornare dalla sua gestore di eventi di nuovo alla runloop? (In caso contrario, non otterrete mai le tue callback, perché sono consegnati attraverso il runloop.)
NSURLConnection è progettato per funzionare con qualsiasi tipo di protocollo, non solo HTTP. Ciò significa che il collegamento: didFail: withError è chiamato per il collegamento di errori, ma non per protocollo errori. Non stai controllando per errori di protocollo - si deve prendere loro in relazione: didReceiveResponse :. Il trucco è che l'oggetto di risposta che viene passato in realtà è un oggetto NSHTTPURLResponse. Se si seleziona statusCode della risposta, scommetto che stai ricevendo un errore HTTP, come 404 o 500 del server.