views:

189

answers:

1

All,

I am fairly new to XCode and am trying to get a handle on how to best deal with connection issues when trying to use a WebView. I know there are related questions on SO, but none seem to offer complete solutions. I have the following code, but it seems a little inefficient. Hopefully, someone can help me refactor it down to a point where it can be usable anywhere that a UIWebView is called.

NOTE: Please ignore memory issues for now. I realize that has to be added as well.

- (void)viewDidLoad {
    [webView setDelegate:self];

    NSString *urlAddress = @"http://www.somesite.com/somepage";
    NSURL *url = [NSURL URLWithString:urlAddress];
    NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];

    NSURLConnection *urlConnection = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self];

    [super viewDidLoad];
}

// Check for URLConnection failure
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    UIAlertView *connectionError = [[UIAlertView alloc] initWithTitle:@"Connection error" message:@"Error connecting to page.  Please check your 3G and/or Wifi settings." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil]; 
    [connectionError show];
    webView.hidden = true;
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {

    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;

    //Check for server error
    if ([httpResponse statusCode] >= 400) {
        UIAlertView *serverError = [[UIAlertView alloc] initWithTitle:@"Server error" message:@"Error connecting to page.  If error persists, please contact support." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil]; 
        [serverError show];
        webView.hidden = true;

    //Otherwise load webView
    } else {
        // Redundant code
        NSString *urlAddress = @"http://somesite.com/somepage";
        NSURL *url = [NSURL URLWithString:urlAddress];
        NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];

        [webView loadRequest:urlRequest];
        webView.hidden = false;
    }
}

// Seems redundant since we are already checking the URLConnection
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {

    UIAlertView *connectionError = [[UIAlertView alloc] initWithTitle:@"Connection error" message:@"Error connecting to page.  Please check your 3G and/or Wifi settings." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil]; 
    [connectionError show];
}

I guess what I'm wondering is, are there any shortcuts to achieve the desired functionality? Can I somehow access the URLResponse via the WebView directly? Does a nil value for the URLConnection or UIWebView imply connection errors without having to explicitly check for them? Is there an easier way to pass the URLRequest down into the delegate methods so it doesn't have be recreated twice?

Thanks in advance!

+1  A: 
- (void)viewDidLoad {
    webView = [[UIWebView alloc]init];
    [webView setDelegate:self];
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://yourUrl.com"]]]
    [super viewDidLoad];
}

#pragma mark UIWebView delegate methods
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
    //read your request here
    //before the webview will load your request
    return YES;
}
- (void)webViewDidStartLoad:(UIWebView *)webView{
    //access your request
    webView.request;
}
- (void)webViewDidFinishLoad:(UIWebView *)webView{
    //access your request 
    webView.request;    
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{
    NSLog(@"could not load the website caused by error: %@", error);
}
-(void)dealloc{
[webView release];
[super dealloc];
}

You can load the webpage with NSURLRequest directly into your webview. With the delegate callback methods you can change the behavior of your webview.

With this piece of code you should get it done.

Bart Schoon
I like it. My only question would be whether or not there is a way to get to the httpresponse statuscode from one of those delegate callback methods.
Dave