2015-07-15 15 views
11

sto creando un NSMutableRequest:NSURLSessionDataTask timeout richieste successive mancanza

self.req = [NSMutableURLRequest requestWithURL:myURL cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10.0]; 

Il timeout è impostato per essere di 10 secondi, perché non voglio che l'utente di attendere troppo a lungo per ottenere un feedback. Dopo di che ho creare un NSURLSessionDataTask:

NSURLSessionDataTask *task = [self.session dataTaskWithRequest:self.req completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 
    NSHTTPURLResponse * httpResp = (NSHTTPURLResponse *)response; 
    if (error) { 
     // this is where I get the timeout 
    } 
    else if (httpResp.statusCode < 200 || httpResp.statusCode >= 300) { 
     // handling error and giving feedback 
    } 
    else { 
     NSError *serializationError = nil; 
     NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&serializationError]; 
    } 
    [task resume]; 
} 

Il problema è il server va in Gateway Timeout e ci vuole un sacco di tempo. Ottengo l'errore di timeout e invio un feedback all'utente, ma tutte le seguenti chiamate API hanno esito negativo nello stesso modo a causa di un errore di timeout. L'unico modo per fermarlo è quello di uccidere l'app e ricominciare da capo. C'è qualcosa che dovrei fare per uccidere l'attività o la connessione dopo un errore di timeout? Se non imposto un timeout e aspetto di ricevere il codice di errore dal server tutte le seguenti chiamate funzionano perfettamente (ma l'utente aspetta molto!).

ho cercato di annullare l'attività:

NSURLSessionDataTask *task = [self.session dataTaskWithRequest:self.req completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 
    NSHTTPURLResponse * httpResp = (NSHTTPURLResponse *)response; 
    if (error) { 
     // this is where I get the timeout 
     [task cancel]; 
    } 
    ... 
    [task resume]; 
} 
+0

immagino, si potrebbe richiedere di ri-inizializzare il 'self.req' se c'è un errore/timeout. Non sono sicuro di questo però. – Mrunal

+0

prova a chiamare le connessioni con l'app POSTMAN in chrome, e vedi se ottieni ancora l'errore di timeout o no –

+0

Stai creando questa attività all'interno di qualche blocco? O qualche altro thread, diverso dal thread principale? –

risposta

4

non ho visto si riattiva il compito è stato avviato. È necessario dichiarare:

[task resume]; 

Questa riga Riprende l'attività, se è sospesa.

tenta di chiamare il NSURLSession come segue:

[NSURLSession sharedSessison] instead of self.session 

e invalidare la sessione:

[[NSURLSession sharedSession]invalidateAndCancel]; 

Dalla documentazione di Apple:

Quando la tua applicazione non ha più bisogno di una sessione , invalidarlo chiamando invalidateAndCancel (per annullare le attività in sospeso) o finishTasksAndInvalidate (per consentire compiti in sospeso da finire prima di invalidare l'oggetto).

- (void)invalidateAndCancel 

volta invalidate, i riferimenti al delegato e di callback oggetti sono rotti. Gli oggetti di sessione non possono essere riutilizzati.

Per consentire l'esecuzione di attività in sospeso fino al completamento, chiamare invece FineTasksAndInvalidate.

- (void)finishTasksAndInvalidate 

Questo metodo restituisce immediatamente senza attendere i compiti per terminare. Una volta invalidata una sessione, non è possibile creare nuove attività nella sessione, ma le attività esistenti continuano fino al completamento. Al termine dell'ultima attività e la sessione effettua l'ultima chiamata delegata, i riferimenti al delegato e gli oggetti callback sono interrotti. Gli oggetti di sessione non possono essere riutilizzati.

Per annullare tutte le attività in sospeso, chiamare invece invalidateAndCancel.

+0

Sì, ho dimenticato il curriculum qui nella domanda. Ho intenzione di modificarlo. E l'unico metodo che posso richiamare sull'attività per invalidarlo è "cancel". Non riesco a vedere gli altri. Ho provato ma non risolve il problema. Grazie –

+0

come stai chiamando l'annullamento? –

+0

Ho modificato la domanda. Grazie –

0

La causa più probabile per un timeout è che il servizio DNS è stato risolto in un indirizzo IP che non esisteva o che il server si è arrestato in modo anomalo e deve essere riavviato. In ogni caso, se una richiesta non riesce con il timeout, è probabile che anche più richieste abbiano esito negativo con timeout.

Ovviamente è necessario scrivere l'applicazione in modo che possa sopravvivere quando i server non rispondono.

+0

Se imposto il timeout a 60 anziché a 10 secondi, ricevo il "Timeout del gateway" dal server e tutte le richieste che faccio dopo questo funzionano perfettamente. Il problema è quando si verifica il timeout prima della risposta dal server. Tutte le seguenti richieste falliscono fino a quando non uccido l'app. –

1

Si può impostare il timeout in modo diverso, come codice seguente

NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration]; 
sessionConfiguration.timeoutIntervalForRequest = timeout; 
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration delegate:nil delegateQueue:nil]; 
1

Il problema che si è probabilmente verificato qui è che il vostro compito non sta annullando o completando ed è, quindi, tenendo la sessione di accettare eventuali altri compiti . Come da documentazione di Apple

Dopo aver creato un'attività, la si avvia chiamando il relativo metodo di ripresa. La sessione mantiene quindi un forte riferimento all'attività finché la richiesta termina o non riesce;

Come suggerito T_77, provare a utilizzare [NSURLSession sharedSession]

anche un'altra cosa vorrei cercare di fare a questo punto del tempo sta cercando di scoprire se c'è un ciclo mantenere creato tra l'oggetto della sessione e il compito, utilizzando gli strumenti

Un'altra cosa che potrebbe accadere è che la richiesta non è formata correttamente e non è in esecuzione o è bloccata. Ho avuto un problema simile una volta quando ho provato a caricare un URL su una web view. La pagina non si stava caricando e non stava generando un errore. Prova a verificare la richiesta di URL anche una volta.

Grazie, Suraj

Problemi correlati