¿UIWebView no fue a didFailLoadWithError cuando no se encontró webLink?

Utilizo UIWebView para cargar web desde un webLink web y UIWebViewDelegate para controlar el estado de error:

 [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:webLink]]]; - (void)webViewDidStartLoad:(UIWebView *)webView{ NSLog(@"START LOAD"); } - (void)webViewDidFinishLoad:(UIWebView *)webView{ NSLog(@"FINISH LOAD"); } - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{ NSLog(@"ERROR : %@",error); } 

Pero cuando no se encuentra webLink , NO va a didFailLoadWithError , va a startLoad y didFinishLoad . ¿Cómo se hace la situación cuando webLink no se encuentra? ¡Por favor ayuda!

Lamentablemente, UIWebView no considera los errores 404 (o códigos similares) porque se recibió una respuesta HTML. Peor aún, el UIWebView no captura los códigos de respuesta para nosotros, por lo que debe hacerlo manualmente, a través de NSURLConnection . Aquí hay una forma de lidiar con esto:

 @interface ViewController () <UIWebViewDelegate, NSURLConnectionDataDelegate> @property (nonatomic) BOOL validatedRequest; @property (nonatomic, strong) NSURL *originalUrl; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // since `shouldStartLoadWithRequest` only validates when a user clicks on a link, we'll bypass that // here and go right to the `NSURLConnection`, which will validate the request, and if good, it will // load the web view for us. self.originalUrl = [NSURL URLWithString:@"http://www.stackoverflow.com"]; NSURLRequest *request = [NSURLRequest requestWithURL:self.originalUrl]; [NSURLConnection connectionWithRequest:request delegate:self]; } #pragma mark - UIWebViewDelegate // you will see this called for 404 errors - (void)webViewDidFinishLoad:(UIWebView *)webView { self.validatedRequest = NO; // reset this for the next link the user clicks on } // you will not see this called for 404 errors - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error { NSLog(@"%s error=%@", __FUNCTION__, error); } // this is where you could, intercept HTML requests and route them through // NSURLConnection, to see if the server responds successfully. - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { // we're only validating links we click on; if we validated that successfully, though, let's just go open it // nb: we're only validating links we click on because some sites initiate additional html requests of // their own, and don't want to get involved in mediating each and every server request; we're only // going to concern ourselves with those links the user clicks on. if (self.validatedRequest || navigationType != UIWebViewNavigationTypeLinkClicked) return YES; // if user clicked on a link and we haven't validated it yet, let's do so self.originalUrl = request.URL; [NSURLConnection connectionWithRequest:request delegate:self]; // and if we're validating, don't bother to have the web view load it yet ... // the `didReceiveResponse` will do that for us once the connection has been validated return NO; } #pragma mark - NSURLConnectionDataDelegate method // This code inspinetworking by http://www.ardalahmet.com/2011/08/18/how-to-detect-and-handle-http-status-codes-in-uiwebviews/ // Given that some ISPs do networkingirects that one might otherwise prefer to see handled as errors, I'm also checking // to see if the original URL's host matches the response's URL. This logic may be too restrictive (some valid networkingirects // will be rejected, such as www.adobephotoshop.com which networkingirects you to www.adobe.com), but does capture the ISP // networkingirect problem I am concerned about. - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { NSString *originalUrlHostName = self.originalUrl.host; NSString *responseUrlHostName = response.URL.host; NSRange originalInResponse = [responseUrlHostName rangeOfString:originalUrlHostName]; // handle where we went to "apple.com" and got networkingirected to "www.apple.com" NSRange responseInOriginal = [originalUrlHostName rangeOfString:responseUrlHostName]; // handle where we went to "www.stackoverflow.com" and got networkingirected to "stackoverflow.com" if (originalInResponse.location == NSNotFound && responseInOriginal.location == NSNotFound) { NSLog(@"%s you were networkingirected from %@ to %@", __FUNCTION__, self.originalUrl.absoluteString, response.URL.absoluteString); } if ([response isKindOfClass:[NSHTTPURLResponse class]]) { NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode]; if (statusCode < 200 || statusCode >= 300) { NSLog(@"%s request to %@ failed with statusCode=%d", __FUNCTION__, response.URL.absoluteString, statusCode); } else { self.validatedRequest = YES; [self.webView loadRequest:connection.originalRequest]; } } [connection cancel]; } @end 

Tenga en count que, en mi implementación, no solo estoy buscando los códigos de estado, sino que también estoy revisando las networkingirecciones (que puede o no desear hacer). Lo hago porque las requestes HTTP de intercepción de un ISP y si el sitio de destino no se encuentran, lo networkingireccionan a su propia página web de búsqueda (que creo que es un poco espeluznante sabiendo que mi ISP está revisando cada website que busco). Y si estás tratando con iPhones que se están conectando a través de wifi, tienes que lidiar con estos caprichos.

Por ejemplo, mi código anterior está buscando " http: //www.applecom/pages " (en el cual deliberadamente omití el período de ".com", que debería fallar en una búsqueda de DNS), pero para lo que mi ISP, Verizon interceptó la request y la networkingirigió mediante connection HTTP a su propia página de búsqueda y, como tal, mi aplicación informa:

2013-01-21 23: 14: 21.896 webtest [24198: c07] – [Conexión ViewController: didReceiveResponse:] le networkingirigieron desde http: //www.applecom/pages a http://search.dnsassist.verizon.net/ assist.php? url = http://www.applecom

Es posible que desee pensar qué tipo de networkingirecciones son aceptables (por ejemplo, si va a "www.adobephotoshop.com" y lo networkingirige a "www.adobe.com") y qué types no son (por ejemplo, si yo vaya a "www.applecom" y me networkingirecciona a "search.dnsassist.verizon.net". Puede que esté preocupado por un problema bastante limitado (que me afecta a causa de mi ISP), pero es algo que debe contemplar.