Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best way to poll data periodically from server when app is active in iOS in a separate thread?

I need to poll data from server periodically in my iOS application. I need to do it every 10 seconds in a thread, in order to keep the UI usable. This function will be fired when the user logs in. I'm thinking about using NSRunLoop with NSTimer to achieve this functionality, and maybe use AFNetworking to get JSON data.

Is this the correct approach? Should this be done using GCD?

like image 258
amb Avatar asked Oct 30 '12 13:10

amb


People also ask

What is polling in IOS?

Apple users rely on its unique features like end-to-end encryption for regular messages and group chats. One helpful group chat feature seen on other chat apps is polling. Polls can be used to make decisions or arrange plans. However, Apple doesn't support polls for iMessage as of yet.

What is polling in system design?

Polling is a technique that allows the servers to push information to a client. Long polling is a version of traditional polling that allows the server to send data to a client whenever available.


1 Answers

Probably the only part that must be done off the main thread is the request itself. Deciding that you need a request and forming that request can be done without any fancy stuff...

Agree with H2CO3 that polling might become a problem for your server with too many clients in the wild, but also agree with you that it's not necessarily a mistake in all cases.

Setup a timer ...

[NSTimer scheduledTimerWithTimeInterval:10.0
                                 target:self
                               selector:@selector(timerFired:)
                               userInfo:nil
                                repeats:YES];

Run a request ...

- (void)timerFired:(NSTimer *)timer {

    NSURLRequest *request = // setup your request
    [NSURLConnection sendAsynchronousRequest:request 
                                       queue:[NSOperationQueue mainQueue]
                           completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
    if (!error) {
       // change my model in an observable way, or
       // if we're in a vc, change my model and update the UI

       // if we want to stop polling, [timer invalidate];
    }
}];

NSTimer fires periodically. Upon fire, a method (on the main thread) decides if it needs to poll (in the case you described, always 'yes' if it's called on a 10sec period). Form the request, NSURLConnection sendAsynchronousRequest: will move the slow part of the request off the main. The block on sendAsynch runs back on the main when the request is done.

The trick is that other parts of your app need to be setup to observe changes in the model and update the views. This may be as simple as doing a table reload in the sendAsynch block, or more complex, like setting up KVO that will trigger as the model changes.

like image 93
danh Avatar answered Sep 28 '22 04:09

danh