У меня большая головная боль с темой.Я работаю над приложением, которое должно регулярно опрашивать веб-сервер, чтобы проверять наличие новых данных.Основываясь на возвращенной информации, я хочу отправить локальное уведомление пользователю.
Я знаю, что этот подход немного отличается от того, который изображен Apple, в котором удаленный сервер выполняет работу, выдвигая удаленныйуведомление, основанное на APNS.Однако есть много причин, по которым я не могу принять этот подход во внимание.Одним из всех является механизм аутентификации пользователя.Удаленный сервер по соображениям безопасности не может учитывать учетные данные пользователя.Все, что я могу сделать, - это перенести ядро входа и загрузки на клиент (iPhone).
Я заметил, что Apple предоставляет возможность приложениям активизироваться и держать открытым соединение Socket (т.е.Приложение VoIP).
Итак, я начал расследование таким образом.Добавил необходимую информацию в plist, я могу "разбудить" мое приложение, используя что-то вроде этого в моем appDelegate:
[[UIApplication sharedApplication] setKeepAliveTimeout:1200 handler:^{
NSLog(@"startingKeepAliveTimeout");
[self contentViewLog:@"startingKeepAliveTimeout"];
MyPushOperation *op = [[MyPushOperation alloc] initWithNotificationFlag:0 andDataSource:nil];
[queue addOperation:op];
[op release];
}];
NSOperation, а затем запускает фоновую задачу, используя следующий код блока:
#pragma mark SyncRequests
-(void) main {
NSLog(@"startSyncRequest");
[self contentViewLog:@"startSyncRequest"];
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
NSLog(@"exipiration handler triggered");
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
[self cancel];
}];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSMutableURLRequest *anURLRequest;
NSURLResponse *outResponse;
NSError *exitError;
NSString *username;
NSString *password;
NSLog(@"FirstLogin");
anURLRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:webserverLogin, username, password]]];
[anURLRequest setHTTPMethod:@"GET"];
[anURLRequest setTimeoutInterval:120.00];
[anURLRequest setCachePolicy:NSURLRequestReloadIgnoringCacheData];
exitError = nil;
NSData *tmpData = [NSURLConnection sendSynchronousRequest:anURLRequest returningResponse:&outResponse error:&exitError];
[anURLRequest setTimeoutInterval:120.00];
if(exitError != nil) { //somethings goes wrong
NSLog(@"somethings goes wrong");
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
[self cancel];
return;
}
//do some stuff with NSData and prompt the user with a UILocalNotification
NSLog(@"AlltasksCompleted");
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
[self cancel];
});
}
}
Вышеприведенный код, кажется, работает (иногда), но во многих других случаях это приводит к сбою моего приложения со следующей информацией журнала:
Exception Type: 00000020
Exception Codes: 0x8badf00d
Highlighted Thread: 3
Application Specific Information:
DemoBackApp[5977] has active assertions beyond permitted time:
{(
<SBProcessAssertion: 0xa9da0b0> identifier: UIKitBackgroundCompletionTask process: DemoBackApp[5977] permittedBackgroundDuration: 600.000000 reason: finishTask owner pid:5977 preventSuspend preventIdleSleep
)}
Elapsed total CPU time (seconds): 0.010 (user 0.010, system 0.000), 100% CPU
Elapsed application CPU time (seconds): 0.000, 0% CPU
Для тех, кто спрашивает, да.Я тоже попробовал подход Async NSURLConnection.Независимо от того.Сбой тот же, даже если я использую асинхронный подход с обработчиком тайм-аута и didFinishLoading: WithError.
Я застрял.Любые намеки высоко ценятся.