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

È stato utile?

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 a self.theConnection per assicurarsi che i metodi di proprietà accessor sono chiamati. In vari luoghi interscambio anche self.urlData e urlData. Potrebbe desiderare di farli tutti coerenti passando attraverso self.

  • Si consiglia di effettuare la dataRequest una proprietà come bene e passare attraverso self per assicurarsi che venga mantenuta.

  • self.urlData = [[NSMutableData data] retain]; - non dovrebbe essere necessario quel qualcosa in più trattenere. Passando attraverso self 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, è necessario

ulteriori 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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top