solo que numero mensaje llamadas hace emergencia configurar bloqueado objective-c ios8 location cllocationmanager

objective c - que - Los servicios de localización no funcionan en iOS 8



que hace el sos del iphone (26)

Mi aplicación que funcionó bien en iOS 7 no funciona con el SDK de iOS 8.

CLLocationManager no devuelve una ubicación, y tampoco veo mi aplicación en Configuración -> Servicios de ubicación . Hice una búsqueda en Google sobre el tema, pero no surgió nada. ¿Qué podría estar mal?


  1. Agregue la clave NSLocationWhenInUseUsageDescription o NSLocationAlwaysUsageDescription (uso de GPS de fondo) con una cadena que solicita el uso de GPS en cada info.plist de cada objetivo.

  2. Pida permiso ejecutando:

    [self initLocationManager: locationManager];

Donde initLocationManageresta

// asks for GPS authorization on iOS 8 -(void) initLocationManager:(CLLocationManager *) locationManager{ locationManager = [[CLLocationManager alloc]init]; if([locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) [locationManager requestAlwaysAuthorization]; }

Recuerde que si las claves no están en cada una info.plistpara cada objetivo, la aplicación no preguntará al usuario. El ifproporciona compatibilidad con iOS 7 y el respondsToSelector:método garantiza la compatibilidad futura en lugar de resolver el problema para iOS 7 y 8.


Antes de [locationManager startUpdatingLocation]; , agregue una solicitud de servicios de ubicación iOS8:

if([locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) [locationManager requestAlwaysAuthorization];

Edite el Info.plist su aplicación y agregue la clave NSLocationAlwaysUsageDescription con el valor de cadena que se mostrará al usuario (por ejemplo, We do our best to preserve your battery life. ) We do our best to preserve your battery life.

Si su aplicación necesita servicios de ubicación solo mientras la aplicación está abierta, reemplace:

requestAlwaysAuthorization con requestWhenInUseAuthorization y

NSLocationAlwaysUsageDescription con NSLocationWhenInUseUsageDescription .


El código antiguo para pedir la ubicación no funcionará en iOS 8. Puedes probar este método para la autorización de ubicación:

- (void)requestAlwaysAuthorization { CLAuthorizationStatus status = [CLLocationManager authorizationStatus]; // If the status is denied or only granted for when in use, display an alert if (status == kCLAuthorizationStatusAuthorizedWhenInUse || status == kCLAuthorizationStatusDenied) { NSString *title; title = (status == kCLAuthorizationStatusDenied) ? @"Location services are off" : @"Background location is not enabled"; NSString *message = @"To use background location you must turn on ''Always'' in the Location Services Settings"; UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title message:message delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Settings", nil]; [alertView show]; } // The user has not enabled any location services. Request background authorization. else if (status == kCLAuthorizationStatusNotDetermined) { [self.locationManager requestAlwaysAuthorization]; } } - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { if (buttonIndex == 1) { // Send the user to the Settings for this app NSURL *settingsURL = [NSURL URLWithString:UIApplicationOpenSettingsURLString]; [[UIApplication sharedApplication] openURL:settingsURL]; } }


En iOS 8, debe hacer dos cosas adicionales para que la ubicación funcione: agregue una clave a su lista de información y solicite autorización al administrador de la ubicación para que comience

info.plist:

<key>NSLocationUsageDescription</key> <string>I need location</string> <key>NSLocationAlwaysUsageDescription</key> <string>I need location</string> <key>NSLocationWhenInUseUsageDescription</key> <string>I need location</string>

Agrega esto a tu código

if (IS_OS_8_OR_LATER) { [locationmanager requestWhenInUseAuthorization]; [locationmanager requestAlwaysAuthorization]; }


Estaba trabajando en una aplicación que se actualizó a iOS 8 y los servicios de ubicación dejaron de funcionar. Probablemente obtendrá un error en el área de depuración como tal:

Trying to start MapKit location updates without prompting for location authorization. Must call -[CLLocationManager requestWhenInUseAuthorization] or -[CLLocationManager requestAlwaysAuthorization] first.

Hice el procedimiento menos intrusivo. Primero agregue la entrada NSLocationAlwaysUsageDescription a su info.plist:

Note que no llené el valor para esta clave. Esto todavía funciona, y no me preocupa porque esta es una aplicación interna. Además, ya existe un título que solicita el uso de los servicios de ubicación, por lo que no quería hacer nada redundante.

Luego creé un condicional para iOS 8:

if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) { [_locationManager requestAlwaysAuthorization]; }

Después de esto, el método locationManager:didChangeAuthorizationStatus: es llamada:

- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus: (CLAuthorizationStatus)status { [self gotoCurrenLocation]; }

Y ahora todo funciona bien. Como siempre, echa un vistazo a la documentation .


Este es un problema con iOS 8 Agrega esto a tu código

if (IS_OS_8_OR_LATER) { [locationmanager requestWhenInUseAuthorization]; [locationmanager requestAlwaysAuthorization]; }

ya info.plist:

<key>NSLocationUsageDescription</key> <string>I need location</string> <key>NSLocationAlwaysUsageDescription</key> <string>I need location</string> <key>NSLocationWhenInUseUsageDescription</key> <string>I need location</string>



Me estaba sacando el pelo con el mismo problema. Xcode te da el error:

Intentando iniciar las actualizaciones de ubicación de MapKit sin MapKit autorización de ubicación. Debe llamar -[CLLocationManager requestWhenInUseAuthorization] o -[CLLocationManager requestAlwaysAuthorization] primero.

Pero incluso si implementa uno de los métodos anteriores, no le preguntará al usuario a menos que haya una entrada en info.plist para NSLocationAlwaysUsageDescription o NSLocationWhenInUseUsageDescription .

Agregue las siguientes líneas a su lista de información donde los valores de cadena representan la razón por la que necesita acceder a la ubicación de los usuarios

<key>NSLocationWhenInUseUsageDescription</key> <string>This application requires location services to work</string> <key>NSLocationAlwaysUsageDescription</key> <string>This application requires location services to work</string>

Creo que estas entradas pueden haber faltado desde que inicié este proyecto en Xcode 5. Supongo que Xcode 6 podría agregar entradas predeterminadas para estas claves, pero no las he confirmado.

Puede encontrar más información sobre estas dos configuraciones here


Mi solución que se puede compilar en Xcode 5:

#ifdef __IPHONE_8_0 NSUInteger code = [CLLocationManager authorizationStatus]; if (code == kCLAuthorizationStatusNotDetermined && ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)] || [self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)])) { // choose one request according to your business. if([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysUsageDescription"]){ [self.locationManager requestAlwaysAuthorization]; } else if([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"]) { [self.locationManager requestWhenInUseAuthorization]; } else { NSLog(@"Info.plist does not contain NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription"); } } #endif [self.locationManager startUpdatingLocation];


Para acceder a la ubicación de los usuarios en iOS. Necesitas añadir dos llaves.

NSLocationWhenInUseUsageDescription

NSLocationAlwaysUsageDescription

en el archivo Info.plist.

<key>NSLocationWhenInUseUsageDescription</key> <string>Because I want to know where you are!</string> <key>NSLocationAlwaysUsageDescription</key> <string>Want to know where you are!</string>

Vea esta imagen abajo.


Para acceder a la ubicación del usuario en iOS 8 tendrá que agregar,

NSLocationAlwaysUsageDescription in the Info.plist

Esto le pedirá al usuario el permiso para obtener su ubicación actual.


Para aquellos que usan Xamarin , tuve que agregar la clave NSLocationWhenInUseUsageDescription a info.plist manualmente, ya que no estaba disponible en los menús desplegables de Xamarin 5.5.3 Build 6 o XCode 6.1; solo NSLocationUsageDescription estaba en la lista, y eso causó el CLLocationManager Continuar fallando en silencio.


Para asegurarse de que esto sea compatible con iOS 7, debe verificar si el usuario está ejecutando iOS 8 o iOS 7. Por ejemplo:

#define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) //In ViewDidLoad if(IS_OS_8_OR_LATER) { [self.locationManager requestAlwaysAuthorization]; } [self.locationManager startUpdatingLocation];


Recibo un error similar en iOS9 (que funciona con Xcode 7 y Swift 2): al intentar iniciar las actualizaciones de ubicación de MapKit sin pedir autorización de ubicación. Debe llamar - [CLLocationManager requestWhenInUseAuthorization] o - [CLLocationManager requestAlwaysAuthorization] primero. Estaba siguiendo un tutorial pero el tutor estaba usando iOS8 y Swift 1.2. Hay algunos cambios en Xcode 7 y Swift 2, encontré este código y funciona bien para mí (si alguien necesita ayuda):

import UIKit import MapKit import CoreLocation class MapViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate { // MARK: Properties @IBOutlet weak var mapView: MKMapView! let locationManager = CLLocationManager() override func viewDidLoad() { super.viewDidLoad() self.locationManager.delegate = self self.locationManager.desiredAccuracy = kCLLocationAccuracyBest self.locationManager.requestWhenInUseAuthorization() self.locationManager.startUpdatingLocation() self.mapView.showsUserLocation = true } // MARK: - Location Delegate Methods func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { let location = locations.last let center = CLLocationCoordinate2D(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude) let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 1, longitudeDelta: 1)) self.mapView.setRegion(region, animated: true) } func locationManager(manager: CLLocationManager, didFailWithError error: NSError) { print("Errors: " + error.localizedDescription) } }

Finalmente, puse eso en info.plist: Lista de propiedades de información: NSLocationWhenInUseUsageDescription Valor: la aplicación necesita servidores de ubicación para el personal


Según los documentos de Apple:

A partir de iOS 8, se requiere la presencia de un valor clave NSLocationWhenInUseUsageDescription o NSLocationAlwaysUsageDescription en el archivo Info.plist de su aplicación. También es necesario solicitar permiso del usuario antes de registrarse para [self.myLocationManager requestWhenInUseAuthorization] actualizaciones de ubicación, ya sea llamando a [self.myLocationManager requestWhenInUseAuthorization] o [self.myLocationManager requestAlwaysAuthorization] según sus necesidades. La cadena que ingresó en la lista de información se mostrará en el cuadro de diálogo que sigue.

Si el usuario concede permiso, es el negocio habitual. Si niegan el permiso, entonces el delegado no está informado de las actualizaciones de ubicación.


Solución con compatibilidad con versiones anteriores que no produce advertencias de Xcode:

SEL requestSelector = NSSelectorFromString(@"requestWhenInUseAuthorization"); if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined && [self.locationManager respondsToSelector:requestSelector]) { ((void (*)(id, SEL))[self.locationManager methodForSelector:requestSelector])(self.locationManager, requestSelector); [self.locationManager startUpdatingLocation]; } else { [self.locationManager startUpdatingLocation]; }

Configure la clave NSLocationWhenInUseUsageDescription en su Info.plist .

Para la versión 11.0+ de iOS : configure la clave NSLocationAlwaysAndWhenInUseUsageDescription en su Info.plist . junto con otras 2 llaves.


Solución con compatibilidad hacia atrás:

SEL requestSelector = NSSelectorFromString(@"requestWhenInUseAuthorization"); if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined && [self.locationManager respondsToSelector:requestSelector]) { [self.locationManager performSelector:requestSelector withObject:NULL]; } else { [self.locationManager startUpdatingLocation]; }

Configure la clave NSLocationWhenInUseUsageDescription en su Info.plist


Terminé resolviendo mi propio problema.

Aparentemente, en el SDK de iOS 8, la requestAlwaysAuthorization (para la ubicación en segundo plano) o la requestWhenInUseAuthorization (la ubicación solo cuando está en primer plano) es necesaria en CLLocationManager antes de iniciar las actualizaciones de ubicación.

También debe haber NSLocationAlwaysUsageDescription clave NSLocationAlwaysUsageDescription o NSLocationWhenInUseUsageDescription en Info.plist con un mensaje que se mostrará en el indicador. Añadiendo estos resuelto mi problema.

Espero que ayude a alguien más.

EDITAR: Para obtener información más extensa, eche un vistazo a: nevan.net/2014/09/core-location-manager-changes-in-ios-8


Un pequeño ayudante para todos ustedes que tienen más de un archivo Info.plist ...

find . -name Info.plist | xargs -I {} /usr/libexec/PlistBuddy -c ''Add NSLocationWhenInUseUsageDescription string'' {}

Agregará la etiqueta necesaria a todos los archivos Info.plist en el directorio actual (y subcarpetas).

Otro es:

find . -name Info.plist | xargs -I {} /usr/libexec/PlistBuddy -c ''Set NSLocationWhenInUseUsageDescription $YOURDESCRIPTION'' {}

Agregará su descripción a todos los archivos.


Procedimiento de Objective-C Siga las instrucciones a continuación:

Para iOS-11 Para iOS 11, eche un vistazo a esta Respuesta: acceso a la ubicación de iOS 11

Debe agregar dos claves a la lista y enviar un mensaje como se muestra en la siguiente imagen:

1. NSLocationAlwaysAndWhenInUseUsageDescription 2. NSLocationWhenInUseUsageDescription 3. NSLocationAlwaysUsageDescription

Para iOS-10 y más abajo:

NSLocationWhenInUseUsageDescription

locationManager = [[CLLocationManager alloc] init]; locationManager.delegate = self; locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers; if([locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]){ [locationManager requestWhenInUseAuthorization]; }else{ [locationManager startUpdatingLocation]; }

Métodos de Delegado

#pragma mark - Lolcation Update - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { NSLog(@"didFailWithError: %@", error); UIAlertView *errorAlert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Failed to Get Your Location" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [errorAlert show]; } -(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status { switch (status) { case kCLAuthorizationStatusNotDetermined: case kCLAuthorizationStatusRestricted: case kCLAuthorizationStatusDenied: { // do some error handling } break; default:{ [locationManager startUpdatingLocation]; } break; } } - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { CLLocation *location = [locations lastObject]; userLatitude = [NSString stringWithFormat:@"%f", location.coordinate.latitude] ; userLongitude = [NSString stringWithFormat:@"%f",location.coordinate.longitude]; [locationManager stopUpdatingLocation]; }

Procedimiento rápido

Siga las instrucciones a continuación:

Para iOS-11 Para iOS 11, eche un vistazo a esta Respuesta: acceso a la ubicación de iOS 11

Debe agregar dos claves a la lista y enviar un mensaje como se muestra en la siguiente imagen:

1. NSLocationAlwaysAndWhenInUseUsageDescription 2. NSLocationWhenInUseUsageDescription 3. NSLocationAlwaysUsageDescription

Para iOS-10 y más abajo:

import CoreLocation class ViewController: UIViewController ,CLLocationManagerDelegate { var locationManager = CLLocationManager() //MARK- Update Location func updateMyLocation(){ locationManager.delegate = self; locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers; if locationManager.respondsToSelector(#selector(CLLocationManager.requestWhenInUseAuthorization)){ locationManager.requestWhenInUseAuthorization() } else{ locationManager.startUpdatingLocation() } }

Métodos de Delegado

//MARK: Location Update func locationManager(manager: CLLocationManager, didFailWithError error: NSError) { NSLog("Error to update location :%@",error) } func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) { switch status { case .NotDetermined: break case .Restricted: break case .Denied: NSLog("do some error handling") break default: locationManager.startUpdatingLocation() } } func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { let location = locations.last! as CLLocation var latitude = location.coordinate.latitude var longitude = location.coordinate.longitude }


Un error común para los desarrolladores de Swift:

Primero asegúrese de agregar un valor a la lista para NSLocationWhenInUseUsageDescription o NSLocationAlwaysUsageDescription .

Si aún no ve una ventana emergente que solicita autorización, vea si está colocando la línea var locationManager = CLLocationManager() en el método viewDidLoad su controlador de viewDidLoad . Si lo haces, incluso si llamas a locationManager.requestWhenInUseAuthorization() , no aparecerá nada. Esto se debe a que después de que se ejecuta viewDidLoad, la variable locationManager se desasigna (se borra).

La solución es ubicar la línea var locationManager = CLLocationManager() en la parte superior del método de clase.


Añado clave en los que InfoPlist.stringsen iOS 8.4, mini iPad 2. Funciona también. No pongo ninguna tecla, como NSLocationWhenInUseUsageDescription, en mi Info.plist.

InfoPlist.strings :

"NSLocationWhenInUseUsageDescription" = "I need GPS information....";

nevan.net/2014/09/core-location-manager-changes-in-ios-8 , dijo as in iOS 7, se puede localizar en las InfoPlist.strings. En mi prueba, esas claves se pueden configurar directamente en el archivo InfoPlist.strings.

Entonces, lo primero que debe hacer es agregar una o las dos claves siguientes a su archivo Info.plist:

  • NSLocationWhenInUseUsageDescription
  • NSLocationAlwaysUsageDescription

Ambas claves toman una cadena que es una descripción de por qué necesita servicios de ubicación. Puede ingresar una cadena como "Se requiere ubicación para saber dónde se encuentra" que, como en iOS 7 , se puede localizar en el archivo InfoPlist.strings.

ACTUALIZAR:

Creo que @IOSel método es mejor. Agregar clave a Info.plistcon valor vacío y agregar cadenas localizadas a InfoPlist.strings.


El problema para mí fue que la clase que era la clase CLLocationManagerDelegateera privada, lo que evitó que se llamara a todos los métodos de delegado. Supongo que no es una situación muy común, pero pensé que lo mencionaría en caso de que ayude a alguien.


// ** Don''t forget to add NSLocationWhenInUseUsageDescription in MyApp-Info.plist and give it a string self.locationManager = [[CLLocationManager alloc] init]; self.locationManager.delegate = self; // Check for iOS 8. Without this guard the code will crash with "unknown selector" on iOS 7. if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) { [self.locationManager requestWhenInUseAuthorization]; } [self.locationManager startUpdatingLocation]; // Location Manager Delegate Methods - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { NSLog(@"%@", [locations lastObject]); }


- (void)startLocationManager { locationManager = [[CLLocationManager alloc] init]; locationManager.delegate = self; locationManager.distanceFilter = kCLDistanceFilterNone; //whenever we move locationManager.desiredAccuracy = kCLLocationAccuracyBest; [locationManager startUpdatingLocation]; [locationManager requestWhenInUseAuthorization]; // Add This Line }

Y a su archivo info.plist


- (void)viewDidLoad { [super viewDidLoad]; self.locationManager = [[CLLocationManager alloc] init]; self.locationManager.delegate = self; if([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]){ NSUInteger code = [CLLocationManager authorizationStatus]; if (code == kCLAuthorizationStatusNotDetermined && ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)] || [self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)])) { // choose one request according to your business. if([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysUsageDescription"]){ [self.locationManager requestAlwaysAuthorization]; } else if([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"]) { [self.locationManager requestWhenInUseAuthorization]; } else { NSLog(@"Info.plist does not contain NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription"); } } } [self.locationManager startUpdatingLocation]; } > #pragma mark - CLLocationManagerDelegate - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { NSLog(@"didFailWithError: %@", error); UIAlertView *errorAlert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Failed to Get Your Location" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [errorAlert show]; } - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { NSLog(@"didUpdateToLocation: %@", newLocation); CLLocation *currentLocation = newLocation; if (currentLocation != nil) { longitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.longitude]; latitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.latitude]; } }

En iOS 8, debe hacer dos cosas adicionales para que la ubicación funcione: agregue una clave a su lista de información y solicite autorización al administrador de la ubicación para que comience. Hay dos claves Info.plist para la nueva autorización de ubicación. Se requiere una o ambas de estas claves. Si ninguna de las claves está allí, puede llamar a startUpdatingLocation pero el administrador de ubicación no se iniciará realmente. Tampoco enviará un mensaje de error al delegado (ya que nunca se inició, no puede fallar). También fallará si agrega una o las dos claves pero se olvida de solicitar explícitamente la autorización. Entonces, lo primero que debe hacer es agregar una o las dos claves siguientes a su archivo Info.plist:

  • NSLocationWhenInUseUsageDescription
  • NSLocationAlwaysUsageDescription

Ambas claves toman una cuerda

que es una descripción de por qué necesita servicios de ubicación. Puede ingresar una cadena como "Se requiere ubicación para saber dónde se encuentra" que, como en iOS 7, se puede localizar en el archivo InfoPlist.strings.