1

I have a URL that I'm trying to get XML from.

Now in my iOS app I have this, to get the data.

- (void)viewDidLoad {
[super viewDidLoad];
    [self loadDataUsingNSURLConnection];
}

- (void) loadDataUsingNSURLConnection {
    NSString *url = @"http://64.182.231.116/~spencerf/university_of_albany/u_albany_alumni_menu_test.xml";
                [self getMenuItems:url];
}

And then finally this,

- (void)getMenuItems:(NSString*)url{

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
    NSLog(@"response == %@", response);

    NSLog(@"data: %@", data);
    /*
    self.mealdata=[[MealData alloc]init:data];
    dispatch_async(dispatch_get_main_queue(), ^{
        [self.tableView reloadData];
        [self.loadingView removeFromSuperview];
    });
    */

}];
}

Now sometimes when I run my app it works great and data is returned, but then sometimes, I would say about 25% of the time, with me changing nothing in-between runs. It returns no data, and the NSLog returns

2015-03-10 18:28:05.472 APP[6289:97905] response == <NSHTTPURLResponse: 

0x7fee7628e000> { URL: http://64.182.231.116/~spencerf/university_of_albany/u_albany_alumni_menu_test.xml } { status code: 200, headers {
    "Accept-Ranges" = bytes;
    Connection = "Keep-Alive";
    "Content-Length" = 0;
    "Content-Type" = "application/xml";
    Date = "Tue, 10 Mar 2015 22:28:04 GMT";
    Etag = "W/\"218ceff-0-510f6aa0317dd\"";
    "Keep-Alive" = "timeout=5, max=90";
    "Last-Modified" = "Tue, 10 Mar 2015 22:28:03 GMT";
    Server = Apache;
} }


2015-03-10 18:28:05.472 App[6289:97905] data: <>

Not sure why this is happening, and I can't tell the difference between when it works and when it doesn't what is changing? So Im not sure how to fix this?

What I want is it to get the data every time?

Thanks for the help in adavence.

user229044
  • 232,980
  • 40
  • 330
  • 338
iqueqiorio
  • 1,149
  • 2
  • 35
  • 78

5 Answers5

2

Try to increase timeout interval for your request:

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
[request setTimeoutInterval:60.0];//seconds
Sergey Neskoromny
  • 1,188
  • 8
  • 15
1

Your code is fine. It is the server that is giving you trouble.

I reloaded the page that you mentioned 20 times. It successfully loaded 13 times. 7 times it returned no error but also an empty response body.

What you can do is simply check for this condition in your app and run the request again to try again.

Or talk to the server owner to find out if they can improve the reliability of this service.

Stefan Arentz
  • 34,311
  • 8
  • 67
  • 88
  • Oh I see, what is happening is that file is generated from a script I have running with cron jobs, which was running once every minute, so when it was running there is about 5 second in which the page is updating. Would you mind showing me how to check for if it is updating and try the request again? – iqueqiorio Mar 11 '15 at 03:05
  • Stefan do you have any suggestions? – iqueqiorio Mar 12 '15 at 19:53
  • My suggestion is to re-run the request if you receive a zero-length response. You can execute the same code again. And for example keep a counter to keep track of how many times you've retried. And use an `NSTimer` for a little delay in between requests. - Do you need help with that? – Stefan Arentz Mar 12 '15 at 20:00
  • if you could provide some that would be great :) – iqueqiorio Mar 12 '15 at 20:24
  • I have changed the url to http://64.182.231.116/~spencerf/babson/babson_trim_menu.xml – iqueqiorio Mar 17 '15 at 20:20
1

Running your code on device, when there is no data received, error message is either null or Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost.".

As to the latter error, you can see AFNetworking/issues/2314, below is a comment extracted from the post.

when iOS client received HTTP response with a Keep-Alive header, it keeps this connection to re-use later (as it should), but it keeps it for more than the timeout parameter of the Keep-Alive header and then when a second request comes it tries to re-use a connection that has been dropped by the server.

You could also refer to the solution here, if you can't change the server, I'd suggest you retry the request when error code is -1005 or received data length is 0.

Community
  • 1
  • 1
gabbler
  • 13,626
  • 4
  • 32
  • 44
1

Perhaps Long-Polling would help you. The web server intermittently returns data when I tried it.

Long-Polling will allow you to continue sending requests until you get the data you specify back.

This code shows you an example of how implement long-polling

- (void) longPoll {
//create an autorelease pool for the thread
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];

//compose the request
NSError* error = nil;
NSURLResponse* response = nil;
NSURL* requestUrl = [NSURL URLWithString:@"http://www.example.com/pollUrl"];
NSURLRequest* request = [NSURLRequest requestWithURL:requestUrl];

//send the request (will block until a response comes back)
NSData* responseData = [NSURLConnection sendSynchronousRequest:request
                        returningResponse:&response error:&error];

//pass the response on to the handler (can also check for errors here, if you want)
[self performSelectorOnMainThread:@selector(dataReceived:) 
      withObject:responseData waitUntilDone:YES];

//clear the pool 
[pool drain];

//send the next poll request
[self performSelectorInBackground:@selector(longPoll) withObject: nil];
}

-(void) startPoll {
    //not covered in this example:  stopping the poll or ensuring that only 1 poll is active at any given time
    [self performSelectorInBackground:@selector(longPoll) withObject: nil];
}

-(void) dataReceived: (NSData*) theData {
    //process the response here
}
1

Your URL returns 404 Not Found, so you should fix server part

Azat
  • 6,745
  • 5
  • 31
  • 48