ios - significantes métodos de delegado de ubicación de cambio que no se llaman
objective-c properties (4)
Todo mi código está en AppDelegate.m:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
_locationMgr = [[CLLocationManager alloc] init];
[_locationMgr setDelegate:self];
if([_locationMgr respondsToSelector:@selector(setAllowsBackgroundLocationUpdates:)])
[_locationMgr setAllowsBackgroundLocationUpdates:YES];
CLAuthorizationStatus authorizationStatus= [CLLocationManager authorizationStatus];
if([launchOptions valueForKey:UIApplicationLaunchOptionsLocationKey] != nil) {
NSLog(@"relaunching because of significant location change - restarting SLC");
[_locationMgr startMonitoringSignificantLocationChanges];
}
else
{
if (authorizationStatus == kCLAuthorizationStatusAuthorizedAlways) {
NSLog(@"launching with authorization to always use location - starting SLC");
[_locationMgr startMonitoringSignificantLocationChanges];
}
else
{
NSLog(@"launching with no authorization to always use location - requesting authorization");
if([_locationMgr respondsToSelector:@selector(requestAlwaysAuthorization)])
[_locationMgr requestAlwaysAuthorization];
}
}
if([userdefaults objectForKey:@"pfuser"] == nil) {
NSLog(@"in delegate signup");
SignUpController *signup = [[SignUpController alloc] init];
[self.window setRootViewController:signup];
}
else {
ViewController *map = [[ViewController alloc] init];
[self.window setRootViewController:map];
}
[self.window makeKeyAndVisible];
return YES;
}
- (void)startSignificantChangeUpdates
{
deviceNotFoundAlertController = [UIAlertController alertControllerWithTitle:@"START" message:@"startSignificantChangeUpdates called" preferredStyle:UIAlertControllerStyleAlert];
[deviceNotFoundAlertController addAction:deviceNotFoundAlert];
// Create the location manager if this object does not
// already have one.
if (nil == _locationMgr) {
_locationMgr = [[CLLocationManager alloc] init];
_locationMgr.delegate = self;
}
[CLLocationManager significantLocationChangeMonitoringAvailable];
[_locationMgr startMonitoringSignificantLocationChanges];
}
-(void)locationManger:(CLLocationManager *)manager didFailWithError:(NSError *)error {
NSLog(@"didFailWithError: %@", error);
deviceNotFoundAlertController = [UIAlertController alertControllerWithTitle:@"LOCATION FAIL" message:@"didFailWithError" preferredStyle:UIAlertControllerStyleAlert];
[deviceNotFoundAlertController addAction:deviceNotFoundAlert];
}
// Delegate method from the CLLocationManagerDelegate protocol.
- (void)_locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations {
deviceNotFoundAlertController = [UIAlertController alertControllerWithTitle:@"LOCATION UPDATE" message:@"didUpdateLocations called" preferredStyle:UIAlertControllerStyleAlert];
[deviceNotFoundAlertController addAction:deviceNotFoundAlert];
// If it''s a relatively recent event, turn off updates to save power.
CLLocation* location = [locations lastObject];
NSDate* eventDate = location.timestamp;
NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
if (fabs(howRecent) < 15.0) {
// If the event is recent, do something with it.
NSLog(@"latitude %+.6f, longitude %+.6f/n",
location.coordinate.latitude,
location.coordinate.longitude);
}
}
Ninguna de las alertas ocurre, parece que los métodos de delegado no se están llamando.
ACTUALIZAR
Ahora tengo:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
deviceNotFoundAlert = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil];
...
}
// Delegate method from the CLLocationManagerDelegate protocol.
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations {
deviceNotFoundAlertController = [UIAlertController alertControllerWithTitle:@"LOCATION UPDATE" message:@"didUpdateLocations called" preferredStyle:UIAlertControllerStyleAlert];
[deviceNotFoundAlertController addAction:deviceNotFoundAlert];
// If it''s a relatively recent event, turn off updates to save power.
CLLocation* location = [locations lastObject];
NSDate* eventDate = location.timestamp;
NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
if (fabs(howRecent) < 15.0) {
// If the event is recent, do something with it.
NSLog(@"latitude %+.6f, longitude %+.6f/n",
location.coordinate.latitude,
location.coordinate.longitude);
}
}
Cuando pruebo la aplicación, la abro en mi casa y luego la cierro, para que cuando salga de mi casa envíe una alerta (o 3) en algún momento, pero no recibo alertas de ninguno de los métodos de delegado. (donde coloqué alertas).
Solo tengo una idea, tal vez tengo que mostrar las alertas del UIViewController
principal, no de AppDelegate
.
Esta puede ser la razón por la que no veo las alertas: ¿Cómo agrego un UIAlertController en el delegado de la aplicación (obj-c)?
ACTUALIZAR
Así es como estoy haciendo las alertas ahora:
deviceNotFoundAlertController = [UIAlertController alertControllerWithTitle:@"START" message:@"startSignificantChangeUpdates called" preferredStyle:UIAlertControllerStyleAlert];
[deviceNotFoundAlertController addAction:deviceNotFoundAlert];
alertWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
alertWindow.rootViewController = [[UIViewController alloc] init];
alertWindow.windowLevel = UIWindowLevelAlert + 1;
[alertWindow makeKeyAndVisible];
[alertWindow.rootViewController presentViewController:deviceNotFoundAlertController animated:YES completion:nil];
ACTUALIZAR
Las alertas no parecían ser el problema, la alerta en startSignificantChangeUpdates
nunca aparece. ¿Debería aparecer una vez que estoy a 500 metros de mi ubicación inicial?
ACTUALIZAR
¿Alguien puede ayudarme a entender esto?
Los métodos de su objeto delegado se invocan desde el hilo en el que inició los servicios de ubicación correspondientes. Ese subproceso debe tener un bucle de ejecución activo, como el que se encuentra en el hilo principal de su aplicación.
ACTUALIZAR
Creo que descubrí lo que dice la cita anterior ... y ahora tengo esto: lo probaré mañana.
...
if([launchOptions valueForKey:UIApplicationLaunchOptionsLocationKey] != nil) {
NSLog(@"relaunching because of significant location change - restarting SLC");
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[_locationMgr startMonitoringSignificantLocationChanges];
});
}
else
{
if (authorizationStatus == kCLAuthorizationStatusAuthorizedAlways) {
NSLog(@"launching with authorization to always use location - starting SLC");
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[_locationMgr startMonitoringSignificantLocationChanges];
});
}
else
{
NSLog(@"launching with no authorization to always use location - requesting authorization");
if([_locationMgr respondsToSelector:@selector(requestAlwaysAuthorization)])
[_locationMgr requestAlwaysAuthorization];
}
}
...
Creo que ese código está comenzando los servicios de localización en su propio hilo. Una cosa que noté, es que cuando salgo de la aplicación, la ubicación en la parte superior derecha desaparece. Acabo de actualizar a iOS 10. En iOS 9, la flecha de ubicación en la esquina superior derecha permanecería allí, pero solo sería un contorno negro cuando la aplicación no se estaba ejecutando. Esto podría ser algo que cambiaron con iOS 10, o ahora porque actualicé a 10, algo más no está funcionando ahora. O eso es lo que sucede cuando los servicios de ubicación se ejecutan en su propio hilo. Desde aquí: iOS start Background Thread
ACTUALIZAR
Tal vez no estoy usando el hilo correctamente, pero como dije, ahora cuando cierro la aplicación, los servicios de ubicación se cierran. Cuando lo estaba haciendo sin el hilo, la flecha del servicio de ubicación se mantendría en la esquina superior derecha, como un contorno.
ACTUALIZAR
Leí que el servicio debería iniciarse en el hilo principal, así que ahora tengo:
CLAuthorizationStatus authorizationStatus= [CLLocationManager authorizationStatus];
NSLog(@"launching with no authorization to always use location - requesting authorization");
if([_locationMgr respondsToSelector:@selector(requestAlwaysAuthorization)]) {
[_locationMgr requestAlwaysAuthorization];
}
if([launchOptions valueForKey:UIApplicationLaunchOptionsLocationKey] != nil) {
NSLog(@"relaunching because of significant location change - restarting SLC");
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[_locationMgr startMonitoringSignificantLocationChanges];
});
}
else if (authorizationStatus == kCLAuthorizationStatusAuthorizedAlways) {
NSLog(@"launching with authorization to always use location - starting SLC");
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[_locationMgr startMonitoringSignificantLocationChanges];
});
}
else {
//
}
La flecha de la derecha no aparece cuando la aplicación está cerrada, ¿es esto algo nuevo en iOS 10 donde ya no lo muestran?
ACTUALIZAR
Accidentalmente _locationMgr = [[CLLocationManager alloc] init];
: _locationMgr = [[CLLocationManager alloc] init];
Lo puse y ahora la flecha siempre está ahí, voy a probar hoy.
ACTUALIZAR
Lo probé, todavía no hay alertas.
Es un problema con su método de delegado por favor reemplace debajo de uno
- (void)_locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations {
}
con
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations {
}
Espero que te ayude.
You have written write code, Just add below delegate method in your code. But startMonitoringSignificantLocationChanges for updating location take 10 to 20 min. and also trigger if location channel change.
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
}
[_locationMgr startMonitoringSignificantLocationChanges];
El servicio de ubicación de cambio significativo entrega actualizaciones solo cuando ha habido un cambio significativo en la ubicación del dispositivo, como 500 metros o más.
Por lo tanto, su método de delegado llamará una vez cada vez que su dispositivo se movió más de 500 metros.
Asegúrate de que tu aplicación tenga permiso de ubicación en segundo plano.
si su aplicación está en segundo plano o en primer plano, llamará al método de delegado; de lo contrario, la aplicación se abrirá con la opción de ubicación en el archivo AppDelegate, donde deberá crear el objeto Administrador de ubicación e iniciar nuevamente la ubicación para obtener una nueva ubicación.
Llevé mi computadora conmigo en mi automóvil y miré la consola, y vi que los cambios significativos de ubicación están sucediendo ahora porque recibo actualizaciones de ubicación cada 500m. Las alertas son lo único que no funciona, pero son irrelevantes para el programa; solo estaban allí para ver si funcionaban. Está trabajando con este código:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
...
_locationMgr = [[CLLocationManager alloc] init];
[_locationMgr setDelegate:self];
if([_locationMgr respondsToSelector:@selector(setAllowsBackgroundLocationUpdates:)])
[_locationMgr setAllowsBackgroundLocationUpdates:YES];
CLAuthorizationStatus authorizationStatus= [CLLocationManager authorizationStatus];
NSLog(@"launching with no authorization to always use location - requesting authorization");
if([_locationMgr respondsToSelector:@selector(requestAlwaysAuthorization)]) {
[_locationMgr requestAlwaysAuthorization];
}
if([launchOptions valueForKey:UIApplicationLaunchOptionsLocationKey] != nil) {
NSLog(@"relaunching because of significant location change - restarting SLC");
[_locationMgr startMonitoringSignificantLocationChanges];
}
else if (authorizationStatus == kCLAuthorizationStatusAuthorizedAlways) {
NSLog(@"launching with authorization to always use location - starting SLC");
[_locationMgr startMonitoringSignificantLocationChanges];
}
else {
//
}
...
[self.window makeKeyAndVisible];
return YES;
}
- (void)startSignificantChangeUpdates
{
// Create the location manager if this object does not
// already have one.
if (nil == _locationMgr) {
_locationMgr = [[CLLocationManager alloc] init];
_locationMgr.delegate = self;
}
[CLLocationManager significantLocationChangeMonitoringAvailable];
[_locationMgr startMonitoringSignificantLocationChanges];
deviceNotFoundAlertController = [UIAlertController alertControllerWithTitle:@"START" message:@"startSignificantChangeUpdates called" preferredStyle:UIAlertControllerStyleAlert];
}
-(void)locationManger:(CLLocationManager *)manager didFailWithError:(NSError *)error {
NSLog(@"didFailWithError: %@", error);
}
// Delegate method from the CLLocationManagerDelegate protocol.
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations {
// If it''s a relatively recent event, turn off updates to save power.
CLLocation* location = [locations lastObject];
NSDate* eventDate = location.timestamp;
NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
if (fabs(howRecent) < 15.0) {
// If the event is recent, do something with it.
NSLog(@"latitude %+.6f, longitude %+.6f/n",
location.coordinate.latitude,
location.coordinate.longitude);
}
}