Да, каждый раз, когда вызывается метод setKeepAliveTimeout, я создаю новую конечную фоновую задачу (которая, кажется, запускается в течение 10 минут).

я большая головная боль с темой. Я работаю над приложением, которое должно регулярно опрашивать веб-сервер, чтобы проверять наличие новых данных. На основании возвращенной информации я хочу отправить локальное уведомление пользователю.

Я знаю, что этот подход немного отличается от того, который изображает 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.

Я застрял. Любые намеки высоко ценятся.

Ответы на вопрос(4)

Ваш ответ на вопрос