How to detect and handle HTTP error codes in UIWebView?

前端 未结 9 674
无人及你
无人及你 2021-02-02 11:54

I want to inform user when HTTP error 404 etc is received. How can I detect that? I\'ve already tried to implement

- (void)webView:(UIWebView *)webView didFailL         


        
相关标签:
9条回答
  • 2021-02-02 12:29

    UIWebView does not provide any functionality for getting HTTP status codes for the requests it loads. One workaround is to intercept the request loading process of UIWebView using the UIWebViewDelegate methods and use NSURLConnection to detect how the server responds to that request (as suggested above). Then you can take an appropriate action suitable for the situation.

    And you don't need to continue loading the request after you received a response. You can just cancel the connection in - (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response method after learning the HTTP status code. This way you prevent the connection from loading any unnecessary response data. Then you can load the request in UIWebView again or show an appropriate error message to the user depending on the HTTP status code, etc.

    and here is the demo project on github

    0 讨论(0)
  • 2021-02-02 12:30

    I used below code for my solution

    -(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”);
    

    }

    0 讨论(0)
  • 2021-02-02 12:31

    Heres is my swift 3 version of @AxelGuilmin response:

    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
                }
            }
        }
    
    0 讨论(0)
  • 2021-02-02 12:32

    I am new to iOS and Swift development, and needed to find a way to accomplish this as well, using WKWebView (not UI). I was fortunate enough to run across this site that gave me the following answer, which works perfectly for my needs. It might help passers-by that are looking for the same answer I was.

    Using this function (from WKNavigationDelegate):

    func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void)
    

    You can create custom responses based on the HTTP response, like so:

    func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
    
        // get the statuscode
        guard let statusCode = (navigationResponse.response as? HTTPURLResponse)?.statusCode
        else {
            decisionHandler(.allow)
            return
        }
    
        // respond or pass-through however you like
        switch statusCode {
        case 400..<500:
            webView.loadHTMLString("<html><body><h1>You shall not pass!</h1></body></html>", baseURL: nil)
        case 500..<600:
            webView.loadHTMLString("<html><body><h1>Sorry, our fault.</h1></body></html>", baseURL: nil)
        default:
            print("all might be well")
        }
    
        decisionHandler(.allow)
    }
    
    0 讨论(0)
  • 2021-02-02 12:38

    In webViewDidFinishLoad:

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

    You may consider this solution over other more complex ones, even though some responses might not get cached. Note that wrong urls are usually getting cached by a system which has default configurations.

    0 讨论(0)
  • 2021-02-02 12:41

    My implementation inspired by Radu Simionescu's response :

    - (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
        }
    }
    

    It manages HTTP client errors (4xx) and HTTP server errors (5xx).

    Note that cachedResponseForRequest returns nil if the response is not cached, in that case statusCode is assigned to 0 and the response is considered errorless.

    0 讨论(0)
提交回复
热议问题