2012-09-02 11 views
23

Sé que si una aplicación utiliza "El servicio de ubicación de cambio significativo", iOS lo activará si hay una actualización de ubicación que se entregará, incluso si la aplicación finaliza.¿iOS desbloqueará la aplicación terminada si está registrada con la ubicación de UIBackgroundModes?

No pude encontrar una respuesta clara sobre el caso si la aplicación utiliza servicios de ubicación estándar y especifica la ubicación como la clave para UIBackgroundModes: ¿iOS también lo activará para entregar la actualización incluso si ha finalizado? ¿O la aplicación debe ejecutarse en segundo plano para obtener la devolución de llamada de actualización de ubicación?

ACTUALIZACIÓN: En el momento en que le pregunté esto, no tuve tiempo de probarlo. Pero después de obtener una respuesta aquí, escribí este fragmento de código en el delegado de mi aplicación para ver si mi aplicación terminada se relanza cuando recibe una actualización de ubicación. Estoy mostrando una UILocalNotification cuando recibo la notificación de la actualización. Sin embargo, cuando terminé mi aplicación y luego cambié mi ubicación en la ciudad, no se relanzó la aplicación y no obtuve ninguna actualización. ¿Puedes decirme qué es lo que estoy haciendo mal?

ACTUALIZACIÓN # 2: De acuerdo con los resultados finales de este Q & A, no hay nada malo con este código y es el comportamiento esperado para una aplicación que utiliza los servicios de localización estándar, a no ser relanzado después de la terminación.

He agregado la ubicación como uno de los UIBackgroundModes en el archivo Info.plist.

Y esto es las partes relacionadas con la ubicación de mi aplicación delegado:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  

    [UIApplication sharedApplication].applicationIconBadgeNumber = 0; 

    m_locManager = [[CLLocationManager alloc] init]; 
    m_locManager.delegate = self; 
    [m_locManager startUpdatingLocation]; 
    return YES; 
} 

- (void)applicationDidEnterBackground:(UIApplication *)application { 
    [m_locManager startUpdatingLocation]; 
} 

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error 
{ 
    NSLog("%@", [NSString stringWithFormat:@"Background Fail %@", [error localizedDescription]]); 
} 

- (void)locationManager:(CLLocationManager *)manager 
    didUpdateToLocation:(CLLocation *)newLocation 
      fromLocation:(CLLocation *)oldLocation 
{ 
    UILocalNotification * theNotification = [[UILocalNotification alloc] init]; 
    theNotification.alertBody = [NSString stringWithFormat:@"Background location %.06f %.06f %@" , newLocation.coordinate.latitude, newLocation.coordinate.longitude, newLocation.timestamp]; 
    theNotification.alertAction = @"Ok"; 

    theNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:1]; 

    [[UIApplication sharedApplication] scheduleLocalNotification:theNotification]; 
} 
+2

No sabía el truco de que podría despertarse una aplicación, –

+0

, una vez más, ¡NO PUEDE utilizarse como un truco para activar su aplicación periódicamente! Apple rechazará instantáneamente su aplicación si usa UIBackgroundModes para ningún otro uso que no sea su finalidad: * Rastreando la ubicación de un usuario *. – runmad

+0

@runmad Sí, sé que esto debería usarse para el propósito correcto. El mío es rastrear la ubicación del usuario para enviarlo al servidor, para que el servidor le envíe una notificación automática si está más cerca de un área. Teniendo en cuenta el rechazo de la aplicación, ¿estaré más seguro si uso un servicio de ubicación de cambio significativo en lugar del estándar? – aslisabanci

Respuesta

4

Sí, se comportará de la misma manera excepto que recibirá actualizaciones con más frecuencia (y por lo tanto consumir más batería).

Fuente: App States and Multitasking en la sección Seguimiento de la ubicación del usuario.

EDITAR Después de volver a la lectura, parece que el programa se despertó de un estado suspendido pero no un terminado uno. Aunque no creo que realmente necesites este modo de fondo. Está diseñado para aplicaciones que necesitan buena información de ubicación (como la navegación paso a paso). Consulte la sección en la Guía de programación de ubicaciones sobre la programación "basada en la región". El ejemplo en sus comentarios figura como uno de los usos de esta aplicación.

EDITAR OTRA VEZ Según la discusión en los comentarios, la solución final parece establecer un cambio de ubicación significativo hasta que el usuario está lo suficientemente cerca, y luego cambiar a cambio de ubicación precisa (y esperando que la aplicación no obtenga terminado durante ese tiempo ^^)

+0

Para ampliar esta respuesta, no puede usar este modo de fondo para hacer que su aplicación se lance por otros motivos, si es necesario que la ubicación de los usuarios realice una actualización de algún tipo. – runmad

+0

Bastante correcto @runmad Apple rechazará aplicaciones que se comporten de esta manera. – borrrden

+0

OK, gracias chicos. Publiqué mi comentario en mi pregunta. – aslisabanci

3

Parece que encontraste una solución viable y parece que usar el marco de cambio significante te ahorraría algo de duración de la batería, siempre que sea lo suficientemente preciso para tus propósitos. Su solución también es beneficiosa porque le permite hacer malabarismos potencialmente mayores que el límite por aplicación de 20 regiones a las que se permite monitorear simultáneamente, solo monitoreando las regiones a las que está más cerca.

Necesito una funcionalidad similar, pero no creo que el cambio significativo sea lo suficientemente preciso para mi aplicación, así que busqué más y encontré lo siguiente.

por la Location Awareness Programming Guide, bajo "monitoreo Regiones Shape-base":

En iOS, regiones asociadas con su aplicación se realiza un seguimiento en todo momento, incluso cuando su aplicación no se está ejecutando. Si se cruza un límite de la región mientras una aplicación no se está ejecutando, esa aplicación se relanza en el fondo para manejar el evento. Del mismo modo, si la aplicación se suspende cuando se produce el evento, se activa y se le da un breve período de tiempo para manejar el evento.

Y también en "Manejo de Eventos cruce de fronteras para una región":

Cada vez que la ubicación actual del usuario, atraviesa una región de límites, el sistema genera un evento región apropiada para su aplicación. Si su aplicación ya se está ejecutando, estos eventos van directamente a los delegados de cualquier objeto actual del administrador de la ubicación. Si su aplicación no se está ejecutando, el sistema la inicia en segundo plano para que pueda responder. Las aplicaciones pueden implementar los métodos siguientes para manejar los cruces de frontera:

locationManager: didEnterRegion:

locationManager: didExitRegion:

En mi caso, yo sólo necesitaba para disparar una notificación cuando se cruzó el límite, así que puse mi AppDelegate para ajustarse a CLLocationManagerDelegate, creé una propiedad locationManager, y poner esto en mi archivo de implementación:

- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    self.locationManager.delegate = self; 
    return YES; 
} 

- (CLLocationManager *)locationManager 
{ 
    if (!_locationManager) { 
     _locationManager = [[CLLocationManager alloc] init]; 
     _locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters; 
    } 
    return _locationManager; 
} 

- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region 
{ 
    UILocalNotification *notification = [[UILocalNotification alloc] init]; 
    notification.alertBody = NSLocalizedString(@"You crossed a boundary!", @"user crossed a boundary"); 
    [[UIApplication sharedApplication] presentLocalNotificationNow:notification]; 
} 

Testing s cómo funciona esto sin necesidad de configurar la clave de ubicación UIBackgroundModes. En este caso de uso, el SO maneja la supervisión de límites por usted y luego envía el evento a su aplicación el tiempo suficiente para procesar el evento. Esto no hace que ejecute la aplicación, simplemente la ejecuta en segundo plano durante unos segundos para procesar el evento de límite, durante el cual solo puede realizar actividades relevantes. Espero que esto ayude a alguien más, también!

+0

Hola Daniel, en mi caso tengo que realizar múltiples llamadas a la API. Creo que cuando el usuario cruza una región, la aplicación se despierta durante unos segundos, lo que no es suficiente para realizar mis tareas. Lo he comprobado con una notificación local en la región de cruce. ¿Es posible extender el tiempo de activación de la aplicación de alguna forma? Gracias por adelantado. – Yogendra

2

vez que matan a la aplicación, las actualizaciones de ubicación se envían a la aplicación

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 

, deberá recoger las actualizaciones de ubicación dentro de este método delegado mediante la búsqueda de la llave puesta en marcha de la siguiente manera,

if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey]) 
{ 
//Code to handle the location update 
} 

Espero que esto es lo que estás buscando. Sí, debe configurar la clave "Modos de fondo necesarios" con el valor "Registros de aplicación para actualizaciones de ubicación" en plist.

Cuestiones relacionadas