setKeepAliveTimeout y BackgroundTasks

Tengo un gran dolor de cabeza con el tema. Estoy trabajando en una aplicación que necesita sondear un servidor web regularmente para verificar si hay nuevos datos. Según la información devuelta, deseo enviar una notificación local al usuario.

Sé que este enfoque es ligeramente diferente del representado por Apple, en el que un servidor remoto hace el trabajo, enviando una notificación remota, basada en APNS. Sin embargo, hay muchas razones por las cuales no puedo tomar este enfoque en consideración. Uno para todos, es el mecanismo de autenticación del usuario. El servidor remoto, por razones de seguridad, no puede tener en cuenta las credenciales del usuario. Todo lo que puedo hacer es mover el inicio de sesión y recuperar el núcleo al cliente (iPhone).

Noté que Apple ofrece una oportunidad para que las aplicaciones se activen y mantengan abierta una conexión Socket (es decir, una aplicación VoIP).

Entonces, comencé a investigar de esta manera. Agregué la información requerida en el plist, puedo "despertar" mi aplicación, usando algo como esto en mi aplicación Delegar:

[[UIApplication sharedApplication] setKeepAliveTimeout:1200 handler:^{ 
    NSLog(@"startingKeepAliveTimeout");
    [self contentViewLog:@"startingKeepAliveTimeout"];
    MyPushOperation *op = [[MyPushOperation alloc] initWithNotificationFlag:0 andDataSource:nil];
    [queue addOperation:op];
    [op release];
}];

La operación NSO, luego inicia una tarea en segundo plano utilizando el siguiente código de bloque:

#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];
        });
    }
}

El código anterior parece funcionar (a veces), pero muchos otros bloquea mi aplicación, con la siguiente información de registro:

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

Para los que preguntan, sí. También probé el enfoque Async NSURLConnection. No importa. Se bloquea de la misma manera, incluso si uso un enfoque asíncrono con el controlador de tiempo de espera y didFinishLoading: WithError.

Estoy atascado. Cualquier pista es muy apreciada.

Respuestas a la pregunta(4)

Su respuesta a la pregunta