Madhu
Madhu

Reputation: 1229

iOS reading data from server regularly

I need to create a iOS app where the app has to continuously check for the updates from the server(may be every 30 secs). But only when the app is running on the foreground.
I know this will drain the battery, but this will run on a environment where there's no internet. So we can't use push notifications.

Only option I can think of is sending a request to the server every 30 secs or so and get the updates. What is the best way to do this? Using NSTimer and NSURLConnection or any other better approaches?

Also if I use a timer, when the app goes to the background will it pause and will it start running as it comes to the foreground again? Is there a chance that app get killed while its on background?

Thanks

Upvotes: 0

Views: 189

Answers (3)

valheru
valheru

Reputation: 2562

Your best bet is to setup a separate object that manages these operations on a background thread. Then in your app delegate, when

- (void)applicationWillResignActive:(UIApplication *)application

is called, have this special object stop all of it's synchronizing and clean up anything it needs to.

Then when:

- (void)applicationDidBecomeActive:(UIApplication *)application

gets called as the app gets active again, signal your object to query / poll on its background thread again.

Your custom object could have an interface like this

@interface PollingObject : NSObject
{
   NSTimer* _timer;
   NSUinteger _interval;
   BOOL _cancel;
   BOOL _isPolling;
   dispatch_queue_t _pollQueue;
}
- (void)startPolling;
- (void)stopPolling;
@end

The implementation can be something like this:

@implementation PollingObject : NSObject

- (id)init
{
   if (self = [super init])
   {
      _interval = 1; // 1 second interval
      _cancel = NO; // default to NO
      _isPolling = NO; // default to NO

      // init your background queue
      _pollQueue = dispatch_queue_create("com.yourconame.yourappname.pollQueue", NULL);
   }
   return self;
}

- (void)heartbeat
{
   if (_cancel)
   {
      // stop the timer
      [_timer invalidate];
      _isPolling = NO;
      return;
   }

   // Runs the polling method ONCE on a background queue
   dispatch_async(_pollQueue, ^{
       [self pollingMethod];
   });
}

- (void)pollingMethod
{
   // Do actual network polling work here...but only run it once. (don't loop)
}

- (void)startPolling
{
   _cancel = NO;
   if (_isPolling)
   {
      NSLog(@"Already polling");
      return;
   }

   // schedule the method heartbeat to run every second
   _timer = [NSTimer scheduledTimerWithTimeInterval:_interval target:self selector:@selector(heartbeat) userInfo:nil repeats:YES];

}

- (void)stopPolling
{
   // we set the flag here and the next second the heartbeat will stop the timer
   _cancel = YES;
}

@end

Upvotes: 1

Joseph Chen
Joseph Chen

Reputation: 1530

Using NSTimer and NSURLConnection or any other better approaches?

My first thought was also to use NSTimer and NSURLConnection.

Also if I use a timer, when the app goes to the background will it pause and will it start running as it comes to the foreground again?

Yes, it will. It doesn't exactly pause, but based on my testing in the simulator, the effect is similar. Let's say the timer is set to go off at 00:00:00, 00:00:30, 00:00:60, ... and you background the app at 00:00:15 and resume it at 00:00:45. The timer that was supposed to fire at 00:00:30 fires immediately when you resume (at 00:00:45), and the next firing (at 00:00:60) and subsequent firings are back on schedule.

Is there a chance that app get killed while its on background?

Yes, there is. But if you start the timer whenever the app launches, this shouldn't be a problem, right?

Upvotes: 1

Rudy
Rudy

Reputation: 939

Look at Rocket real-time networking which looks easy to setup through AFNetworking 2.0.

https://github.com/AFNetworking/AFNetworking/wiki/AFNetworking-2.0-Migration-Guide

See the last part of this wiki. I have not used it but it would be something I would try if I had your requirements.

Upvotes: 0

Related Questions