2014-01-09 2 views
0

Мне нужно создать приложение iOS, в котором приложение должно постоянно проверять обновления с сервера (может быть каждые 30 секунд). Но только когда приложение работает на переднем плане.
Я знаю, что это разрядит батарею, но это будет работать в среде, где нет Интернета. Поэтому мы не можем использовать push-уведомления.
iOS чтение данных с сервера регулярно

Только вариант, о котором я могу думать, отправляет запрос на сервер каждые 30 секунд или около того и получает обновления. Каков наилучший способ сделать это? Использование NSTimer и NSURLConnection или любых других лучших подходов?

Также, если я использую таймер, когда приложение переходит на задний план, оно приостанавливается и начнет работать, когда оно снова появится на переднем плане? Есть ли вероятность, что приложение будет убито во время его работы?

Благодаря

+0

Я не понимаю. Если нет Интернета, как вы собираетесь общаться с сервером? – Desdenova

+0

Все находится внутри локальной сети. поэтому мы подключаемся к серверу локально. – Madhu

+0

А вы правы. Виноват. – Desdenova

ответ

0

Посмотрите на ракетное в режиме реального времени в сети, которая выглядит легко настроить с помощью AFNetworking 2,0.

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

Смотрите последнюю часть этой вики. Я не использовал его, но я бы попробовал, если бы у меня были ваши требования.

+0

Спасибо, ты имеешь в виду здесь использовать подход на основе сокетов, где сервер может отправлять уведомление в приложение вместо того, чтобы делать опрос? – Madhu

1

Лучше всего настроить отдельный объект, который управляет этими операциями в фоновом потоке. Затем в делегат своего приложения, когда

- (void)applicationWillResignActive:(UIApplication *)application 

называется, имеют этот специальный объект остановить все это синхронизировать и очистить все, что ему нужно.

Тогда, когда:

- (void)applicationDidBecomeActive:(UIApplication *)application 

вызывается как приложение снова становится активным, сигнал вашего объекта запроса/опрос на его фоне нить снова.

Ваш пользовательский объект может иметь интерфейс, как этот

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

Реализация может быть что-то вроде этого:

@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 
+0

Спасибо. Итак, что мне нужно сделать, это создать поток с использованием GCD и поместить в него таймер и остановить его в applicationWillResignActive и начать обратно в applicationDidBecomeActive? dispatch_async (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^{nstimer = ....}); – Madhu

+0

Ну, таймер должен быть вне очереди GCD, и он должен быть настроен для запуска метода каждый интервал. Но этот метод должен также проверять флаг отмены какого-либо типа, чтобы он знал, когда нужно остановить таймер или запустить метод опроса в отдельной очереди GCD или NSOperation. – valheru

+0

добавлен еще пример кода. Не копируйте и не вставляете его. Попытайтесь это понять. – valheru

1

Использование NSTimer и NSURLConnection или любые другие лучшие подходы?

Моей первой мыслью было также использовать NSTimer и NSURLConnection.

Также, если я использую таймер, когда приложение переходит на задний план, оно остановится и начнет работать, когда оно снова появится на переднем плане?

Да, это будет. Это не совсем пауза, но на основе моего тестирования в симуляторе эффект подобен. Предположим, что таймер выключен в 00:00:00, 00:00:30, 00:00:60, ... и вы запустите приложение в 00:00:15 и возобновите его в 00:00: 45. Таймер, который должен был срабатывать в 00:00:30, срабатывает немедленно, когда вы возобновляете (в 00:00:45), и следующий увольнение (в 00:00:60), а последующие стрельбы возвращаются по графику.

Есть ли шанс, что приложение будет убито во время его фона?

Да, есть. Но если вы запускаете таймер всякий раз, когда приложение запускается, это не должно быть проблемой, верно?

+0

Спасибо за детали. Поэтому, чтобы запустить таймер, когда приложение выходит на передний план и чтобы остановить его при переходе на задний план, мне нужно будет сделать что-то похожее на другой ответ «valheru». Это верно? – Madhu

+1

На самом деле «NSTimer» не запускается, когда приложение имеет фоновые рисунки, поэтому вам не нужно вручную его останавливать. Вы можете отправить сообщение, чтобы запустить повторяющийся таймер в '-application: doneFinishLaunchingWithOptions:', а затем забудьте об этом. –

+0

Хорошо спасибо. Но начнется ли она автоматически, когда приложение снова появится на переднем плане? – Madhu