2016-01-18 16 views
41

Ho fatto qualche ricerca su CoreLocation. Recentemente, ho riscontrato un problema che è stato trattato altrove, ma in Objective C e per iOS 8.Verifica se i servizi di localizzazione sono abilitati

Mi sento un po 'sciocco a chiedere questo, ma come è possibile verificare se i servizi di localizzazione sono abilitati utilizzando swift, su iOS 9?

Su iOS 7 (e forse 8?) Si potrebbe usare locationServicesEnabled(), ma che non sembra di lavorare durante la compilazione per iOS 9.

Così come dovrei fare questo?

Grazie!

risposta

117

Aggiungere il CLLocationManagerDelegate alla vostra eredità classe e poi si può fare questo controllo:

Swift 1.x - versione 2.x:

if CLLocationManager.locationServicesEnabled() { 
    switch CLLocationManager.authorizationStatus() { 
    case .NotDetermined, .Restricted, .Denied: 
     print("No access") 
    case .AuthorizedAlways, .AuthorizedWhenInUse: 
     print("Access") 
    } 
} else { 
    print("Location services are not enabled") 
} 

Swift 3.0 Versione:

if CLLocationManager.locationServicesEnabled() { 
    switch CLLocationManager.authorizationStatus() { 
     case .notDetermined, .restricted, .denied: 
      print("No access") 
     case .authorizedAlways, .authorizedWhenInUse: 
      print("Access") 
     } 
    } else { 
     print("Location services are not enabled") 
} 
+6

Sì! Grazie! Il mio problema è che mi stava cercando di chiamare locatoinServicesEnabled il mio manager, vale a dire 'manager.locationServicesEnabled()' piuttosto che 'CLLocationManager.loationServicesEnabled()' risolto! –

+1

Ho capito che il tuo codice è solo un esempio, ma è leggermente fuorviante ... Penso che sia meglio quando 'authorizationStatus' è * set * a' not Determined', invece di loggarlo sarebbe meglio chiedere all'utente 'Allow/Non consentire " – Honey

+0

@Honey, certo che potresti ovviamente usarlo come preferisci e come hai detto il codice è solo un esempio per mostrare come potrebbe essere usato. –

3

Quando si chiama -startLocation, se i servizi di posizione sono stati negati dall'utente, il delegato del gestore località riceverà una chiamata a - locationManager:didFailWithError: con il codice di errore kCLErrorDenied. Funziona sia su tutte le versioni di iOS.

+0

Grazie. Sfortunatamente, quando ho provato, mostra: 'Uso dell'identificatore non risolto 'kCLErrorDenied''. Pensieri? –

5

In obiettivo-c

si dovrebbe tracciare l'utente già negato o non determinato, quindi chiedere l'autorizzazione o l'utente inviato all'app Impostazione.

-(void)askEnableLocationService 
{ 
    BOOL showAlertSetting = false; 
    BOOL showInitLocation = false; 

    if ([CLLocationManager locationServicesEnabled]) { 

     switch ([CLLocationManager authorizationStatus]) { 
     case kCLAuthorizationStatusDenied: 
      showAlertSetting = true; 
      NSLog(@"HH: kCLAuthorizationStatusDenied"); 
      break; 
     case kCLAuthorizationStatusRestricted: 
      showAlertSetting = true; 
      NSLog(@"HH: kCLAuthorizationStatusRestricted"); 
      break; 
     case kCLAuthorizationStatusAuthorizedAlways: 
      showInitLocation = true; 
      NSLog(@"HH: kCLAuthorizationStatusAuthorizedAlways"); 
      break; 
     case kCLAuthorizationStatusAuthorizedWhenInUse: 
      showInitLocation = true; 
      NSLog(@"HH: kCLAuthorizationStatusAuthorizedWhenInUse"); 
      break; 
     case kCLAuthorizationStatusNotDetermined: 
      showInitLocation = true; 
      NSLog(@"HH: kCLAuthorizationStatusNotDetermined"); 
      break; 
     default: 
      break; 
     } 
    } else { 

     showAlertSetting = true; 
     NSLog(@"HH: locationServicesDisabled"); 
    } 

    if (showAlertSetting) { 
     UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:@"Please enable location service for this app in ALLOW LOCATION ACCESS: Always, Go to Setting?" delegate:self cancelButtonTitle:@"No" otherButtonTitles:@"Open Setting", nil]; 
     alertView.tag = 199; 
     [alertView show]; 
    } 
    if (showInitLocation) { 
     [self initLocationManager]; 
    } 

} 

Implementare alertView Delegato poi inviati all'utente di attivare il servizio di localizzazione, se già negare dall'utente.

-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex 
{ 

    if (alertView.tag == 199) { 
     if (buttonIndex == 1) { 
      [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]]; 
     } 
     return; 
    } 
} 

Init Location Manager

-(void)initLocationManager{ 
    self.locationManager = [[CLLocationManager alloc] init]; 
    if([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) { 
     [self.locationManager requestAlwaysAuthorization]; 
    } 
} 

Si prega di notare kCLAuthorizationStatusAuthorizedAlways e kCLAuthorizationStatusAuthorizedWhenInUse è differenza.

5

SWIFT 3(A partire dal 4 lug 2017)

if CLLocationManager.locationServicesEnabled() { 

} 

questo vi dirà se l'utente ha già messo giù un ambiente per la posizione

3

Per swift3.0 e, soprattutto, se controlli frequenti sono fatti per la disponibilità dei servizi di localizzazione, creare una classe come di seguito,

import CoreLocation 

    open class Reachability { 
     class func isLocationServiceEnabled() -> Bool { 
      if CLLocationManager.locationServicesEnabled() { 
       switch(CLLocationManager.authorizationStatus()) { 
        case .notDetermined, .restricted, .denied: 
        return false 
        case .authorizedAlways, .authorizedWhenInUse: 
        return true 
        default: 
        print("Something wrong with Location services") 
        return false 
       } 
      } else { 
        print("Location services are not enabled") 
        return false 
       } 
      } 
     } 

e quindi utilizzarlo come questo nella tua VC

if Reachability.isLocationServiceEnabled() == true { 
    // Do what you want to do. 
    } else { 
    //You could show an alert like this. 
     let alertController = UIAlertController(title: "Location 
     Services Disabled", message: "Please enable location services 
     for this app.", preferredStyle: .alert) 
     let OKAction = UIAlertAction(title: "OK", style: .default, 
     handler: nil) 
     alertController.addAction(OKAction) 
     OperationQueue.main.addOperation { 
      self.present(alertController, animated: true, 
      completion:nil) 
     } 
    } 
2

E 'solo una la funzione 2 linee a Swift 4:

import CoreLocation 

static func isLocationPermissionGranted() -> Bool 
{ 
    guard CLLocationManager.locationServicesEnabled() else { return false } 
    return [.authorizedAlways, .authorizedWhenInUse].contains(CLLocationManager.authorizationStatus()) 
} 
1

in Swift 3,0

if (CLLocationManager.locationServicesEnabled()) 
      { 
       locationManager.delegate = self 
       locationManager.desiredAccuracy = kCLLocationAccuracyBest 
       if ((UIDevice.current.systemVersion as NSString).floatValue >= 8) 
       { 
        locationManager.requestWhenInUseAuthorization() 
       } 

       locationManager.startUpdatingLocation() 
      } 
      else 
      { 
       #if debug 
        println("Location services are not enabled"); 
       #endif 
      } 
1

a chiedere il permesso per i servizi di localizzazione che si utilizzano:

yourSharedLocationManager.requestWhenInUseAuthorization() 

Se lo stato è attualmente indeterminato un avviso indicherà che richiede all'utente di consentire l'accesso. Se l'accesso viene negato, l'app verrà notificata in CLLocationManagerDelegate, allo stesso modo se l'autorizzazione viene negata in qualsiasi momento in cui verrà aggiornato qui.

Esistono due stati separati da verificare per determinare le autorizzazioni correnti.

  • Se l'utente dispone dei servizi generali di localizzazione abilitati o non

CLLocationManager.locationServicesEnabled()

  • Se l'utente ha concesso l'autorizzazione corretta per la vostra applicazione ..

CLLocationManager.authorizationStatus() == .authorizedWhenInUse

Si potrebbe aggiungere un'estensione è una comoda opzione:

extension CLLocationManager { 
static func authorizedToRequestLocation() -> Bool { 
    return CLLocationManager.locationServicesEnabled() && 
     (CLLocationManager.authorizationStatus() == .authorizedAlways || CLLocationManager.authorizationStatus() == .authorizedWhenInUse) 
} 

}

Qui si accede quando l'utente ha prima chiesto direzioni:

private func requestUserLocation() { 
    //when status is not determined this method runs to request location access 
    locationManager.requestWhenInUseAuthorization() 

    if CLLocationManager.authorizedToRequestLocation() { 

     //have accuracy set to best for navigation - accuracy is not guaranteed it 'does it's best' 
     locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation 

     //find out current location, using this one time request location will start the location services and then stop once have the location within the desired accuracy - 
     locationManager.requestLocation() 
    } else { 
     //show alert for no location permission 
     showAlertNoLocation(locationError: .invalidPermissions) 
    } 
} 

Qui è il delegato:

func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) { 

    if !CLLocationManager.authorizedToRequestLocation() { 
     showAlertNoLocation(locationError: .invalidPermissions) 
    } 
}