Задача, выполняемая в фоновом режиме, не вызывает делегатов - PullRequest
1 голос
/ 18 января 2012

Я довольно новичок в разработке под iOS и objC, поэтому, пожалуйста, держитесь со мной ..

Мое приложение должно опрашивать сервер в течение максимум 10 минут (используя RestKit), даже если приложение отправляется в фоновом режиме. (опрос всегда начинается, когда приложение находится на переднем плане)

У меня есть View Controller (не RootViewController), который слушает applicationDidEnterBackground.

Кроме того, есть класс «Порядок», который имеет метод «опрос», который используется для отправки запроса на сервер, и несколько других методов обратного вызова для «тайм-аута», «отмены запроса», «обработки ответа» и т. Д. .

- (void)poll
{
    RKRequest* request = [[RKClient sharedClient] requestWithResourcePath:@"/foo.php" delegate:self];
request.backgroundPolicy = RKRequestBackgroundPolicyContinue;    
[request send];    

NSLog(@"I am your RKClient singleton : %@", [RKClient sharedClient]);        
}
- (void)requestDidStartLoad:(RKRequest *)request {
NSLog(@"requestDidStartLoad");
}
- (void)requestDidTimeout:(RKRequest *)request {
NSLog(@"requestDidTimeout");
}
- (void)request:(RKRequest *)request didFailLoadWithError:(NSError *)error {
NSLog(@"didFailLoadWithError");
}
- (void)request:(RKRequest*)request didLoadResponse:(RKResponse*)response 
{  
}

Пока приложение находится на переднем плане, все работает нормально, и выполняются обратные вызовы.

Когда мое приложение переходит в фоновый режим, я хочу продолжить опрос сервера. Я использую этот метод, вызывается «опрос», но никакие обратные вызовы не запускаются ..

- (void)applicationDidEnterBackground:(NSNotification *) notification 
{
Order *order = [[Order alloc] init];

UIApplication *app = [UIApplication sharedApplication];

__block UIBackgroundTaskIdentifier taskId;

taskId = [app beginBackgroundTaskWithExpirationHandler:^{    
    [app endBackgroundTask:taskId]; 
}];

if (taskId == UIBackgroundTaskInvalid) { 
    return;
}

dispatch_async(dispatch_get_global_queue(0, 0), ^{ 

    while(YES)
    {
        sleep(1);

        [order poll];
    }

    [app endBackgroundTask:taskId]; 
});

[order release];

}

Что я делаю не так?

Спасибо!

1 Ответ

1 голос
/ 18 января 2012

Я не знаю этот RKClient, который вы используете, но, вероятно, он основан на NSURLConnection API.Этот асинхронный API вызывает делегатов, только если он выполняется внутри цикла выполнения;из документации NSURLConnection:

Messages to the delegate will be sent on the thread that calls this method. For the connection to work correctly the calling thread’s run loop must be operating in the default run loop mode.

К сожалению, GCD не гарантирует, что вы запускаете блок внутри потока, который выполняет цикл выполнения.В таком случае рекомендуется, чтобы вы провели «опрос» внутри NSOperation, который оптимизирован для подобных ситуаций.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...