2010-02-10 7 views

risposta

7

è possibile catturare l'URLRequest qui:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType 

e consegnare la richiesta sopra al delegato e tornare senza. Quindi nella chiamata di risposta ricevuta da NSURLConnection annulla la connessione e se tutto va bene (verifica la risposta) carica di nuovo l'urlrequest nella webview. Assicurati di restituire SÌ nella chiamata sopra quando carichi di nuovo l'urlrequest.

Non molto elegante, ma potrebbe funzionare.

+0

Grazie per la risposta. Come posso cercare una stringa in una stringa html? Sono bloccato a questo. – EEE

+0

Se si cattura la richiesta, è possibile avviare la propria 'NSUrlconnection' e raccogliere i dati di connessione ricevuti, in' connectionDidFinishLoading', quindi è possibile accedere all'html. – FelixLam

+0

In realtà ho già effettuato l'accesso all'html, il problema era cercare una stringa in html in ogg-c, ma l'ho risolta in C. grazie. – EEE

7

Si sta interpretando male ciò che -didFailLoadWithError è per. Tecnicamente, la richiesta è riuscita. È stato in grado di colpire il server e scoprire che il file che stai richiedendo non esiste (ad esempio 404). Il metodo -didFailLoadWithError verrà chiamato se il server non esiste, per esempio. Il tuo server esiste. Il file no. La visualizzazione Web non interpreterà gli errori nel contenuto. Lo scopo di -didFailLoadWithError dalle Docs UIWebViewDelegate di Apple è:

inviato se una vista web è riuscito a caricare contenuti.

dalla voce di Wikipedia su HTTP 404:

Il messaggio di errore 404 o Not Found è un codice di risposta HTTP standard che indica che il client è stato in grado di comunicare con il server, ma il del server non è stato possibile trovare ciò che è stato richiesto . Errori 404 non dovrebbero essere confusi con "server non trovato" o errori simili, in cui una connessione al server di destinazione non può essere effettuata a .

Con ogni probabilità si dovrà analizzare il testo di risposta per una 404 che si potrebbe ottenere con una combinazione NSURLConnection/NSURLRequest piuttosto che una vista web.

migliori saluti,

+0

grazie per la tua risposta. Ho appena frainteso il metodo didFailLoadError. – EEE

+1

l'analisi del testo di risposta per il codice di errore è una cattiva idea, il testo di risposta potrebbe essere qualsiasi cosa! Vedi la mia risposta per il modo reale di ottenere il codice di stato HTTP. –

7

NSURLConnection è la classe che si sta cercando, non credo che questo può essere fatto direttamente in un UIWebView.

È possibile utilizzare il metodo sincrono

+ (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error 

o quelli asincroni. Questi sono più difficili da configurare in quanto è necessario aggiungere tutti i bit di dati che si ottengono nel NSData 1, ma il risultato finale è lo stesso.


Indipendentemente se si utilizzano i metodi sincrona o asincrona:

Se si ottiene un NSError * oggetto poi c'è stato un errore di COMMS. Come notato nelle altre risposte, questo NON è un codice di stato HTTP ma piuttosto un problema di comunicazione.

Se la connessione è riuscita, si ottiene un NSURLResponse e NSData. È importante sottolineare che la richiesta NSURLResponse per HTTP è in realtà la sottoclasse NSHTTPURLResponse!

Quindi è necessario controllare la risposta per vedere qual è il codice di errore. Prova questo (dove _responseInfo è il vostro oggetto NSURLResponse):

NSInteger httpStatusCode = (NSHTTPURLResponse*)_responseInfo.statusCode; 

responseInfo dovrebbe sempre essere una NSHTTPURLResponse per le richieste HTTP ... ma si potrebbe essere saggio avere un'asserzione lì per ogni evenienza.

Se lo statusCode è un successo (vale a dire 200), l'oggetto NSData deve contenere i dati della risposta (qualunque esso sia). Se il codice di stato indica un errore, NSData potrebbe contenere una descrizione testuale dell'errore dal server.

NB. Non consiglio assolutamente di eseguire l'analisi dell'oggetto NSData per il messaggio di errore. Ecco a cosa serve HTTP statusCode!

8

UIWebView non fornisce alcuna funzionalità per ottenere i codici di stato HTTP per le richieste che carica. Una soluzione è intercettare il processo di caricamento della richiesta di UIWebView usando i metodi UIWebViewDelegate e utilizzare NSURLConnection per rilevare come il server risponde a tale richiesta (come suggerito sopra). Quindi puoi intraprendere un'azione appropriata adatta alla situazione. This article spiega in dettaglio la soluzione in merito a un progetto dimostrativo.

E non è necessario continuare a caricare la richiesta dopo aver ricevuto una risposta. È possibile semplicemente annullare la connessione in - connessione (void): connessione (NSURLConnection *) risposta: risposta ricevuta: (risposta NSURLResponse *) metodo dopo l'apprendimento del codice di stato HTTP. In questo modo si impedisce alla connessione di caricare dati di risposta non necessari. Poi si può caricare la richiesta in UIWebView di nuovo o mostrare un messaggio appropriato errore per l'utente in base al codice di stato HTTP, ecc

Here is the article

and here is the demo project on github

2

In webViewDidFinishLoad:

if ([[(NSHTTPURLResponse*)[[NSURLCache sharedURLCache] cachedResponseForRequest:webView.request] valueForHTTPHeaderField:@"Status"] intValue] == 404){ 
} 

È possibile considerare questa soluzione su altre più complesse, anche se alcune risposte potrebbero non essere memorizzate nella cache. Tieni presente che gli URL errati vengono solitamente memorizzati nella cache da un sistema con configurazioni predefinite.

16

mia implementazione ispirato la risposta di Radu Simionescu:

- (void)webViewDidFinishLoad:(UIWebView *)webView { 
    NSCachedURLResponse *urlResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:webView.request]; 
    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*) urlResponse.response; 
    NSInteger statusCode = httpResponse.statusCode; 
    if (statusCode > 399) { 
     NSError *error = [NSError errorWithDomain:@"HTTP Error" code:httpResponse.statusCode userInfo:@{@"response":httpResponse}]; 
     // Forward the error to webView:didFailLoadWithError: or other 
    } 
    else { 
     // No HTTP error 
    } 
} 

Gestisce gli errori del client HTTP (4xx) e gli errori del server HTTP (5xx).

Si noti che cachedResponseForRequest restituisce nil se la risposta non è memorizzata nella cache, in tal caso statusCode è assegnato a 0 e la risposta è considerata senza errori.

+0

Grazie Penso che la tua risposta sia il modo più corretto per farlo. – GeneCode

+0

Mi stavo strappando i capelli fino a quando ho provato questo su un dispositivo reale, il simulatore restituisce sempre un 404 per me. Non è stato fino a quando ho provato sull'iPad che funzionava davvero !! – Plasma

+1

ma molte volte 'cachedResponseForRequest' restituisce' Nil' – Mrug

-1

ho usato qui di seguito il codice per la mia soluzione

-(void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{ 
NSLog(@"error :%@",error); 

NSString *strError = [NSString stringWithFormat:@"%@",error]; 

if ([strError rangeOfString:@"Code=-1005"].location == NSNotFound) { 
    NSLog(@"string does not contain Code=-1005"); 
} else 
    NSLog(@"string contains Code=-1005”); 

}

1

Heres è la mia versione rapida 3 della risposta @AxelGuilmin:

func webViewDidFinishLoad(_ webView: UIWebView) { 

     guard let request = webView.request else { return } 

     let cachedUrlResponse = URLCache.shared.cachedResponse(for: request) 
     let httpUrlResponse = cachedUrlResponse?.response as? HTTPURLResponse 
     if let statusCode = httpUrlResponse?.statusCode { 
      if statusCode == 404 { 
       // Handling 404 response 
      } 
     } 
    } 
Problemi correlati