views:

303

answers:

2

Hi everyone, 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];
}
A: 

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)

Girish Kolari
A: 

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;
}
lucius
Great i think this will help a lot thank you very much! But what do i do if i also want to display my request (the url with the attributes i set previously) because now i can only display the status code right?
Christoph v
and what of which type is the variable "statusCode"?
Christoph v
statusCode is an int. To display the request, it depends on the format of the response, but a UIWebView will most likely work.
lucius