Friday, September 17, 2010

iPhone Dev Tip: Watching for 404's

Something I have seen a few times when debugging iPhone apps for clients is a misunderstanding of the definition of "Success" when it comes to the NSURLConnection class. In the NSURLConnection delegate  protocol a "successful'" connection is any one that makes a connection to the target host and gets an ACK. This means that when using these methods to get HTTP content (such as JSON and XML, a common pattern) any 404 or 500 errors returned by the target host are treated as a success if not handled correctly.

The way to fix this is to cast the NSURLResponse object to an NSHTTPURLResponse in the didReceiveResponse delegate method. For example set up a connection in the standard way.

 // url for download  
 NSURL *url = [NSURL URLWithString:[self urlString]];  
 // request  
 NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30;  
 // connect  
 NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];  

Then in your NSURLConnection didReceiveResponse method.

 - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {  
      // cast the response to NSHTTPURLResponse so we can look for 404 etc  
      NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;  
      if ([httpResponse statusCode] >= 400) {  
           NSLog(@"remote URL returned error %d %@: ",[httpResponse statusCode],[NSHTTPURLResponse localizedStringForStatusCode:[httpResponse statusCode]]);  
           .....  
      } else {  
           // start recieving data  
         ...  
      }       
 }  

0 comments: