youtubers tesis sobre sirve resumida que para investigaciones investigacion historia caracteristicas iphone background location multitasking

iphone - sirve - tesis sobre youtube pdf



iPhone-Antecedentes para sondeos de eventos (6)

Durante bastante tiempo había estado buscando una forma en mi aplicación de iPhone para sondear cada X minutos para verificar los contadores de datos. Después de leer mucho la documentación de ejecución en segundo plano y algunas aplicaciones de prueba, descarté esto como imposible sin abusar de las API de fondo.

La semana pasada encontré esta aplicación que hace exactamente eso. http://itunes.apple.com/us/app/dataman-real-time-data-usage/id393282873?mt=8

Se ejecuta en segundo plano y realiza un seguimiento del recuento de datos de Celular / WiFi que ha utilizado. Sospecho que el desarrollador está registrando su aplicación a medida que cambia la ubicación de seguimiento, pero el ícono de los servicios de ubicación no está visible mientras se ejecuta la aplicación, lo que pensé que era un requisito.

¿Alguien tiene alguna pista sobre cómo se puede lograr esto?


Lo que funciona y lo que no funciona

No está del todo claro cuáles de estas respuestas funcionan y he desperdiciado mucho tiempo intentándolas todas. Así que aquí está mi experiencia con cada estrategia:

  1. VOIP hackeo: funciona, pero lo rechazarán si no es una aplicación VOIP
  2. Recursive beginBackgroundTask... - no funciona. Se cerrará después de 10 minutos. Incluso si prueba las correcciones en los comentarios (al menos los comentarios hasta el 30 de noviembre de 2012).
  3. Silent Audio: funciona, pero las personas han sido rechazadas por esto
  4. Notificaciones locales / automáticas: requieren interacción del usuario antes de que su aplicación se despierte
  5. Usar ubicación de fondo: funciona . Aquí están los detalles:

Básicamente, utiliza el modo de fondo "ubicación" para mantener su aplicación ejecutándose en segundo plano. Funciona, incluso si el usuario no permite actualizaciones de ubicación. Incluso si el usuario presiona el botón de inicio y abre otra, su aplicación seguirá ejecutándose. También es un desacelerador de batería y puede ser una extensión en el proceso de aprobación si su aplicación no tiene nada que ver con la ubicación, pero hasta donde yo sé, es la única solución que tiene buenas posibilidades de ser aprobada.

Así es como funciona:

En tu conjunto de plist:

  • La aplicación no se ejecuta en segundo plano: NO
  • Modos de fondo requeridos: ubicación

Luego haga referencia al marco de CoreLocation (en Fases de compilación) y agregue este código en alguna parte de su aplicación (antes de que quede en segundo plano):

#import <CoreLocation/CoreLocation.h> CLLocationManager* locationManager = [[CLLocationManager alloc] init]; [locationManager startUpdatingLocation];

Nota: startMonitoringSignificantLocationChanges no funcionará.

También vale la pena mencionar que si tu aplicación falla, iOS no la devolverá a la vida. El truco de VOIP es el único que puede devolverlo.


Hay otra técnica para permanecer siempre en segundo plano: iniciar / detener el administrador de ubicación en la tarea de fondo , restablecerá el temporizador de fondo cuando se llame aUpdateToLocation : .

No sé por qué funciona, pero creo que didUpdateToLocation también se llama como una tarea y, por lo tanto, restablece el temporizador.

Según las pruebas, creo que esto es lo que DataMan Pro está usando.

Ver esta publicación https://.com/a/6465280 donde obtuve el truco.

Aquí hay algunos resultados de nuestra aplicación:

2012-02-06 15:21:01.520 **[1166:4027] BGTime left: 598.614497 2012-02-06 15:21:02.897 **[1166:4027] BGTime left: 597.237567 2012-02-06 15:21:04.106 **[1166:4027] BGTime left: 596.028215 2012-02-06 15:21:05.306 **[1166:4027] BGTime left: 594.828474 2012-02-06 15:21:06.515 **[1166:4027] BGTime left: 593.619191 2012-02-06 15:21:07.739 **[1166:4027] BGTime left: 592.395392 2012-02-06 15:21:08.941 **[1166:4027] BGTime left: 591.193865 2012-02-06 15:21:10.134 **[1166:4027] BGTime left: 590.001071 2012-02-06 15:21:11.339 **[1166:4027] BGTime left: 588.795573 2012-02-06 15:21:11.351 **[1166:707] startUpdatingLocation 2012-02-06 15:21:11.543 **[1166:707] didUpdateToLocation 2012-02-06 15:21:11.623 **[1166:707] stopUpdatingLocation 2012-02-06 15:21:13.050 **[1166:4027] BGTime left: 599.701993 2012-02-06 15:21:14.286 **[1166:4027] BGTime left: 598.465553


He visto este comportamiento, también. Después de intentar mucho, descubrí dos cosas, que podrían ayudar. Pero aún no estoy seguro de cómo esto puede influir en el proceso de revisión.

Si usa una de las funciones de fondo, la aplicación será lanzada por iOS en segundo plano una vez que se haya cerrado (por el sistema). Esto vamos a abusar más tarde.

En mi caso utilicé el fondo de VoIP habilitado en mi plist. Todo el código aquí se hace en su AppDelegate:

// if the iOS device allows background execution, // this Handler will be called - (void)backgroundHandler { NSLog(@"### -->VOIP backgrounding callback"); // try to do sth. According to Apple we have ONLY 30 seconds to perform this Task! // Else the Application will be terminated! UIApplication* app = [UIApplication sharedApplication]; NSArray* oldNotifications = [app scheduledLocalNotifications]; // Clear out the old notification before scheduling a new one. if ([oldNotifications count] > 0) [app cancelAllLocalNotifications]; // Create a new notification UILocalNotification* alarm = [[[UILocalNotification alloc] init] autorelease]; if (alarm) { alarm.fireDate = [NSDate date]; alarm.timeZone = [NSTimeZone defaultTimeZone]; alarm.repeatInterval = 0; alarm.soundName = @"alarmsound.caf"; alarm.alertBody = @"Don''t Panic! This is just a Push-Notification Test."; [app scheduleLocalNotification:alarm]; } }

y el registro se hace en

- (void)applicationDidEnterBackground:(UIApplication *)application { // This is where you can do your X Minutes, if >= 10Minutes is okay. BOOL backgroundAccepted = [[UIApplication sharedApplication] setKeepAliveTimeout:600 handler:^{ [self backgroundHandler]; }]; if (backgroundAccepted) { NSLog(@"VOIP backgrounding accepted"); } }

Ahora sucede la magia: ni siquiera uso VoIP-Sockets. Pero esta devolución de llamada de 10 minutos proporciona un bonito efecto secundario: después de 10 minutos (a veces antes) descubrí que mis temporizadores y las pistas de rodadura anteriores se están ejecutando durante un tiempo breve. Puede ver esto, si coloca algún NSLog (..) en su código. Esto significa que este breve "despertar" ejecuta el código por un tiempo. Según Apple, tenemos 30 segundos de tiempo de ejecución. Supongo que ese código de fondo, como los hilos, se está ejecutando durante casi 30 segundos. Este es un código útil, si debe "a veces" verificar algo.

El documento dice que todas las tareas en segundo plano (VoIP, audio, actualizaciones de ubicación) se reiniciarán automáticamente en segundo plano si la aplicación finalizó. ¡Las aplicaciones de VoIP se iniciarán en segundo plano automáticamente después del arranque!

Al abusar de este comportamiento, puede hacer que su aplicación parezca funcionar "para siempre". Regístrese para un proceso en segundo plano (es decir, VoIP). Esto hará que tu aplicación se reinicie después de la finalización.

Ahora escriba el código "La tarea debe estar terminada". Según Apple, ¿le queda algo de tiempo (5 segundos?) Para finalizar las tareas. Descubrí, que este debe ser el tiempo de CPU. Entonces eso significa: si no haces nada, ¡tu aplicación aún se está ejecutando! Apple sugiere llamar a un gestor de vencimiento, si ha terminado con su trabajo. En el siguiente código, puede ver que tengo un comentario en el expirationHandler. Esto hará que su aplicación se ejecute siempre que el sistema permita que su aplicación se ejecute. Todos los temporizadores y subprocesos se mantienen en ejecución hasta que iOS finaliza su aplicación.

- (void)applicationDidEnterBackground:(UIApplication *)application { UIApplication* app = [UIApplication sharedApplication]; bgTask = [app beginBackgroundTaskWithExpirationHandler:^{ [app endBackgroundTask:bgTask]; bgTask = UIBackgroundTaskInvalid; }]; // Start the long-running task and return immediately. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // you can do sth. here, or simply do nothing! // All your background treads and timers are still being executed while (background) [self doSomething]; // This is where you can do your "X minutes" in seconds (here 10) sleep(10); } // And never call the expirationHandler, so your App runs // until the system terminates our process //[app endBackgroundTask:bgTask]; //bgTask = UIBackgroundTaskInvalid; }); }

¡Sé muy sobrio con el tiempo de CPU aquí y tu aplicación se ejecutará más tiempo! Pero una cosa es segura: su aplicación finalizará después de un tiempo. Pero debido a que registró su aplicación como VoIP u otra, el sistema reinicia la aplicación en segundo plano, lo que reiniciará el proceso en segundo plano ;-) Con este PingPong puedo crear una gran cantidad de fondos. pero recuerda ser muy sobrio con el tiempo de CPU. Y guarde todos los datos para restaurar sus vistas: su aplicación finalizará un tiempo más tarde. Para hacer que parezca que aún se está ejecutando, debes volver a tu último "estado" después de la activación.

No sé si este es el enfoque de las aplicaciones que mencionaste antes, pero funciona para mí.

Espero poder ayudar

Actualizar:

Después de medir el tiempo de la tarea de BG, hubo una sorpresa. La tarea BG está limitada a 600 segundos. Este es el tiempo mínimo exacto del tiempo mínimo de VoIP (setKeepAliveTimeout: 600).

Entonces ESTE código lleva a la ejecución "infinita" en el fondo:

Encabezamiento:

UIBackgroundTaskIdentifier bgTask;

Código:

// if the iOS device allows background execution, // this Handler will be called - (void)backgroundHandler { NSLog(@"### -->VOIP backgrounding callback"); UIApplication* app = [UIApplication sharedApplication]; bgTask = [app beginBackgroundTaskWithExpirationHandler:^{ [app endBackgroundTask:bgTask]; bgTask = UIBackgroundTaskInvalid; }]; // Start the long-running task dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ while (1) { NSLog(@"BGTime left: %f", [UIApplication sharedApplication].backgroundTimeRemaining); [self doSomething]; sleep(1); } }); - (void)applicationDidEnterBackground:(UIApplication *)application { BOOL backgroundAccepted = [[UIApplication sharedApplication] setKeepAliveTimeout:600 handler:^{ [self backgroundHandler]; }]; if (backgroundAccepted) { NSLog(@"VOIP backgrounding accepted"); } UIApplication* app = [UIApplication sharedApplication]; bgTask = [app beginBackgroundTaskWithExpirationHandler:^{ [app endBackgroundTask:bgTask]; bgTask = UIBackgroundTaskInvalid; }]; // Start the long-running task dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ while (1) { NSLog(@"BGTime left: %f", [UIApplication sharedApplication].backgroundTimeRemaining); [self doSomething]; sleep(1); } }); }

Después de que se agote el tiempo de espera de su aplicación, se llamará al VoIP expirationHandler, donde simplemente reiniciará una tarea de larga ejecución. Esta tarea finalizará después de 600 segundos. Pero habrá una nueva llamada al manejador de vencimiento, que iniciará otra tarea de larga ejecución, etc. Ahora solo tiene que verificar si la aplicación está volviendo al primer plano. Luego cierre el bgTask, y listo. Tal vez uno puede hacer algo. así dentro del caché de expiración de la tarea de larga ejecución. Solo pruébalo. Usa tu consola para ver qué pasa ... ¡Diviértete!

Actualización 2:

A veces, simplificar las cosas ayuda. Mi nuevo enfoque es este:

- (void)applicationDidEnterBackground:(UIApplication *)application { UIApplication* app = [UIApplication sharedApplication]; // it''s better to move "dispatch_block_t expirationHandler" // into your headerfile and initialize the code somewhere else // i.e. // - (void)applicationDidFinishLaunching:(UIApplication *)application { // // expirationHandler = ^{ ... } } // because your app may crash if you initialize expirationHandler twice. dispatch_block_t expirationHandler; expirationHandler = ^{ [app endBackgroundTask:bgTask]; bgTask = UIBackgroundTaskInvalid; bgTask = [app beginBackgroundTaskWithExpirationHandler:expirationHandler]; }; bgTask = [app beginBackgroundTaskWithExpirationHandler:expirationHandler]; // Start the long-running task and return immediately. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // inform others to stop tasks, if you like [[NSNotificationCenter defaultCenter] postNotificationName:@"MyApplicationEntersBackground" object:self]; // do your background work here }); }

Esto funciona sin el truco de VoIP. De acuerdo con la documentación, el controlador de caducidad (en este caso mi bloque ''expirationHandler'') se ejecutará si el tiempo de ejecución ha terminado. Al definir el bloque en una variable de bloque, uno puede iniciar recursivamente la tarea de ejecución larga nuevamente dentro del controlador de caducidad. Esto lleva a una ejecución sin fin, también.

Tenga en cuenta que finalizará la tarea si su aplicación vuelve a estar en primer plano. Y termine la tarea si ya no la necesita.

Para mi propia experiencia, medí algo. Usar las retrollamadas de ubicación con tener la radio de GPS encendida es muy rápida. Usar el enfoque que publiqué en la Actualización 2 casi no consume energía. De acuerdo con "userexperience" este es un mejor enfoque. Tal vez otras aplicaciones funcionan así, ocultando su comportamiento detrás de la funcionalidad del GPS ...


Intenté la Actualización 2 pero simplemente no funciona. Cuando se llama al controlador de caducidad, finaliza la tarea de fondo. Luego, comenzar una nueva tarea de fondo simplemente fuerza una llamada inmediata al manejador de vencimiento nuevamente (el temporizador no se reinicia y aún expira). Así obtuve 43 inicios / paradas de tareas en segundo plano antes de que se suspendiera la aplicación.


Si no es un GPS, creo que la única forma de hacerlo es la función de música de fondo, es decir, reproducir 4 "33" todo el tiempo que esté habilitado. Ambos suenan como un abuso de las API de procesamiento en segundo plano y, por lo tanto, están potencialmente sujetas a los caprichos del proceso de revisión.


en mis pruebas en iOS5 encontré que es útil tener la monitorización de CoreLocation iniciada, a través de startMonitoringForLocationChangeEvents (no SignificantLocationChange), la precisión no importa, e incluso así en el iPod si lo hago - backgroundTimeRemaining nunca baja.