Question Les services de localisation ne fonctionnent pas dans iOS 8


Mon application qui fonctionne correctement sur iOS 7 ne fonctionne pas avec iOS 8 SDK.

CLLocationManager ne renvoie pas d'emplacement et je ne vois pas mon application sous Paramètres -> Services de location non plus. J'ai fait une recherche Google sur le problème, mais rien n'a été fait. Quel pourrait être le problème?


602
2018-06-05 14:12


origine


Réponses:


J'ai fini par résoudre mon propre problème.

Apparemment dans iOS 8 SDK, requestAlwaysAuthorization (pour l'emplacement d'arrière-plan) ou requestWhenInUseAuthorization (emplacement seulement au premier plan) appelez CLLocationManager est nécessaire avant de commencer les mises à jour de localisation.

Il doit également être NSLocationAlwaysUsageDescription ou NSLocationWhenInUseUsageDescription entrer Info.plist avec un message à afficher dans l'invite. Ajouter ceux-ci a résolu mon problème.

enter image description here

J'espère que ça aide quelqu'un d'autre.

EDIT: Pour plus d'informations, regardez: Core-Location-Manager-Modifications-dans-ios-8


1083
2018-06-05 14:58



Je tirais mes cheveux avec le même problème. Xcode vous donne l'erreur:

Essayer de commencer MapKit mises à jour de localisation sans inviter   autorisation de localisation. Doit appeler -[CLLocationManager requestWhenInUseAuthorization] ou -[CLLocationManager requestAlwaysAuthorization] premier.

Mais même si vous implémentez l'une des méthodes ci-dessus, il ne demandera pas à l'utilisateur sauf s'il existe une entrée dans info.plist pour NSLocationAlwaysUsageDescription ou NSLocationWhenInUseUsageDescription.

Ajoutez les lignes suivantes à votre info.plist où les valeurs de chaîne représentent la raison pour laquelle vous devez accéder à l'emplacement des utilisateurs

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

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

Je pense que ces entrées ont peut-être été manquantes depuis que j'ai commencé ce projet dans Xcode 5. Je suppose que Xcode 6 pourrait ajouter des entrées par défaut pour ces clés mais ne les a pas confirmées.

Vous pouvez trouver plus d'informations sur ces deux paramètres ici 


312
2018-06-05 15:58



Pour vous assurer que cette fonctionnalité est rétrocompatible avec iOS 7, vous devez vérifier si l'utilisateur exécute iOS 8 ou iOS 7. Par exemple:

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

103
2018-06-27 01:14



- (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


}

Et à votre fichier info.plist enter image description here


50
2017-09-30 10:24



Selon les docs d'Apple:

À partir d'iOS 8, la présence d'un NSLocationWhenInUseUsageDescription ou un NSLocationAlwaysUsageDescription valeur clé dans le fichier Info.plist de votre application est requise. Il est alors également nécessaire de demander l'autorisation de l'utilisateur avant de s'inscrire aux mises à jour de localisation, soit en appelant [self.myLocationManager requestWhenInUseAuthorization] ou [self.myLocationManager requestAlwaysAuthorization] en fonction de votre besoin. La chaîne que vous avez entrée dans Info.plist sera alors affichée dans la boîte de dialogue qui suit.

Si l'utilisateur accorde la permission, c'est comme d'habitude. Si elles refusent l'autorisation, le délégué n'est pas informé des mises à jour de localisation.


30
2018-06-08 22:16



- (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];
        }
    }

Dans iOS 8, vous devez faire deux choses supplémentaires pour obtenir l'emplacement de travail: Ajouter   une clé pour votre Info.plist et demander une autorisation à partir de l'emplacement   gestionnaire lui demandant de commencer. Il y a deux clés Info.plist pour le nouveau   autorisation de localisation. Une ou deux de ces clés est requise. Si   aucune des clés n'est là, vous pouvez appeler startUpdatingLocation mais   le gestionnaire de localisation ne démarre pas réellement. Il n'enverra pas d'échec   message au délégué soit (puisqu'il n'a jamais commencé, il ne peut pas   échouer). Il échouera également si vous ajoutez une ou les deux clés mais oubliez   pour demander explicitement l'autorisation. Donc, la première chose que vous devez faire   est d'ajouter une ou les deux clés suivantes à votre fichier Info.plist:

  • NSLocationWhenInUseUsageDescription
  • NSLocationAlwaysUsageDescription

Ces deux clés prennent une chaîne

qui est une description de la raison pour laquelle vous avez besoin de services de localisation. Vous pouvez   entrez une chaîne comme "Emplacement requis pour savoir où vous êtes"   qui, comme dans iOS 7, peut être localisé dans le fichier InfoPlist.strings.

enter image description here 


28
2017-12-17 03:26



Ma solution qui peut être compilée dans 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];

19
2017-09-24 12:13



L'ancien code pour demander l'emplacement ne fonctionnera pas dans iOS 8. Vous pouvez essayer cette méthode pour l'autorisation de localisation:

- (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];
    }
}

17
2017-09-27 09:54



Dans iOS 8, vous devez faire deux choses supplémentaires pour que l'emplacement fonctionne: Ajoutez une clé à votre Info.plist et demandez une autorisation au gestionnaire d'emplacement pour lui demander de démarrer.

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>

Ajoutez ceci à votre code

if (IS_OS_8_OR_LATER)
{
    [locationmanager requestWhenInUseAuthorization];

    [locationmanager requestAlwaysAuthorization];
}

12
2017-10-02 06:40



Une erreur courante pour les développeurs Swift:

Assurez-vous d'abord d'ajouter une valeur au plist pour NSLocationWhenInUseUsageDescription ou NSLocationAlwaysUsageDescription.

Si vous êtes encore ne pas voir une fenêtre surgir demandant l'autorisation, regardez pour voir si vous mettez la ligne var locationManager = CLLocationManager() dans votre View Controller viewDidLoad méthode. Si vous le faites, même si vous appelez locationManager.requestWhenInUseAuthorization(), rien ne se montrera. En effet, après l'exécution de viewDidLoad, la variable locationManager est désaffectée (effacée).

La solution est de localiser la ligne var locationManager = CLLocationManager() en haut de la méthode de classe.


11
2018-02-17 22:40



Avant [locationManager startUpdatingLocation];, ajoutez une demande de services de localisation iOS8:

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

Modifier votre application Info.plist et ajoutez la clé NSLocationAlwaysUsageDescription avec la valeur de chaîne qui sera affichée à l'utilisateur (par exemple, We do our best to preserve your battery life.)

Si votre application nécessite des services de localisation uniquement lorsque l'application est ouverte, remplacez:

requestAlwaysAuthorization avec requestWhenInUseAuthorization et

NSLocationAlwaysUsageDescription avec NSLocationWhenInUseUsageDescription.


9
2017-11-11 14:20