问题
my app is supposed to make a request from a server every 10 seconds or so with a specific url, change some attributes in the url, and then show the request in another view called "updateView" or if any network error occurred display the error. The first part works fine but if i switch of wifi for example the app crashes. How do i fix this and how do i display the various errors? Thanks in advance!! Here's my code (this is the method which gets called every 10 seconds):
- (void)serverUpdate{
CLLocationCoordinate2D newCoords = self.location.coordinate;
gpsUrl = [NSURL URLWithString:[NSString stringWithFormat:@"http://odgps.de/chris/navextest?objectid=3&latitude=%2.4fN&longitude=%2.4fE&heading=61.56&velocity=5.21&altitude=%f&message=Eisberg+voraus%21", newCoords.latitude, newCoords.longitude, self.location.altitude]];
self.pageData = [NSString stringWithContentsOfURL:gpsUrl];
[updateView.transmissions insertObject:pageData atIndex:counter];
if (counter == 100) {
[updateView.transmissions removeAllObjects];
counter = -1;
}
counter = counter + 1;
[updateView.tableView reloadData];
self.sendToServerSuccessful = self.sendToServerSuccessful + 1;
[self.tableView reloadData];
}
回答1:
First, you're blocking the main thread while it waits for the network operation to complete when you call stringWithContentsOfURL:
and that's a bad thing because if the network is slow or unreachable, it'll look like your app has crashed.
Second, stringWithContentsOfURL:
is deprecated and you should use this instead, even though it still blocks the main thread:
self.pageData = [NSString stringWithContentsOfURL:gpsURL encoding:NSUTF8StringEncoding error:nil];
You should be using NSURLConnection to download the data without blocking the main thread. Create a NSURLRequest
from the URL, pass it to [NSURLConnection connectionWithRequest:request delegate:self];
which starts the URL connection.
Here's some code for the NSURLConnection delegate:
- (void)connection:(NSURLConnection *)aConnection didReceiveResponse:(NSURLResponse *)response {
if ([response isKindOfClass: [NSHTTPURLResponse class]]) {
statusCode = [(NSHTTPURLResponse*) response statusCode];
/* HTTP Status Codes
200 OK
400 Bad Request
401 Unauthorized (bad username or password)
403 Forbidden
404 Not Found
502 Bad Gateway
503 Service Unavailable
*/
}
self.receivedData = [NSMutableData data];
}
- (void)connection:(NSURLConnection *)aConnection didReceiveData:(NSData *)data {
[self.receivedData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)aConnection {
// Parse the received data
[self parseReceivedData:receivedData];
self.receivedData = nil;
}
- (void)connection:(NSURLConnection *)aConnection didFailWithError:(NSError *)error {
statusCode = 0; // Status code is not valid with this kind of error, which is typically a timeout or no network error.
self.receivedData = nil;
}
回答2:
Do following changes:
1.Changing the call to
+ (id)stringWithContentsOfURL:(NSURL
*)url encoding:(NSStringEncoding)enc error:(NSError **)error
presently you are using stringWithContentsOfURL.
2.Handle the nil value this call return. if there is any error in executing the URL the call return nil object. in present implementation you are just adding object API return (I think this is might be the reason for your crash)
来源:https://stackoverflow.com/questions/3325362/nsurl-error-handling