Konum hizmetlerinin etkin olup olmadığını kontrol edin


88

CoreLocation hakkında biraz araştırma yapıyorum. Son zamanlarda, başka bir yerde, ancak Objective C ve iOS 8'de ele alınan bir sorunla karşılaştım.

Bunu sormak biraz aptalca geliyor, ancak iOS 9'da konum servislerinin Swift kullanılarak etkinleştirilip etkinleştirilmediğini nasıl kontrol edebilirsiniz?

İOS 7'de (ve belki 8'de?) Kullanabilirsiniz locationServicesEnabled(), ancak bu iOS 9 için derleme yaparken çalışmıyor gibi görünüyor.

Peki bunu nasıl başarabilirim?

Teşekkürler!

Yanıtlar:


247

CLLocationManagerDelegateSınıf mirasınıza ekleyin ve ardından şu kontrolü yapabilirsiniz:

Swift 1.x - 2.x sürümü:

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 4.x sürümü:

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 5.1 sürümü

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

8
Evet! Teşekkürler! Benim sorunum yöneticimde locatoinServicesEnabled'ı çağırmaya çalışmamdı, yani Çözüldü manager.locationServicesEnabled() yerine CLLocationManager.loationServicesEnabled()!
Brendan Chang

2
Bunun senin kod sadece bir örnek olduğunu olsun, ama bu biraz yanıltıcı oluyor ... Ben daha iyi olduğunu düşünüyorum authorizationStatusedilir set için notDeterminedsadece kullanıcı '/ Do "İzin ver istemi daha iyi olurdu giriş yerine o
Bal

@ Tatlım, tabii ki tercih ettiğiniz gibi kullanabilirsiniz ve söylediğiniz gibi kod, nasıl kullanılabileceğini göstermek için sadece örnek.
Rashwan L

13

Amaç-c'de

Reddedilmiş veya belirlenmemiş kullanıcıyı takip etmeli, ardından izin istemeli veya kullanıcıyı Ayar uygulamasına göndermelisiniz.

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

}

Daha sonra alertView Delegate'i uygula, daha sonra kullanıcı tarafından zaten reddedilmişse konum hizmetini etkinleştirmesi için kullanıcıyı gönderdi.

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

Lütfen kCLAuthorizationStatusAuthorizedAlways ve kCLAuthorizationStatusAuthorizedWhenInUse arasında fark olduğunu unutmayın.


Bu objektif-c versiyonu için teşekkürler, ancak asıl soru hızlıydı. Ek ipuçları: call requestWhenInUseAuthorization durum belirlenmediyse, kullanım açıklaması için ilgili plist girişini ayarlayın (muhtemelen yerelleştirilmiş) ve muhtemelen didChangeAuthorizationStatus uygulayın
Giorgio Barchiesi

9

SWIFT (24 Temmuz 2018 itibariyle)

if CLLocationManager.locationServicesEnabled() {

}

bu size kullanıcının uygulamanın konum izni isteği için zaten bir ayar seçip seçmediğini söyleyecektir


8

Swift 4'te sadece 2 satırlık bir işlevdir:

import CoreLocation

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

6

İşte Apple'ın önerdiği format .

  switch CLLocationManager.authorizationStatus() {
      case .notDetermined:
         // Request when-in-use authorization initially
         break
      case .restricted, .denied:
         // Disable location features
         break
      case .authorizedWhenInUse, .authorizedAlways:
         // Enable location features
         break
      }

İşte tam bir örnek.

Bu, daha önce erişim reddedilmişse AlertViewkullanıcıyı Settingsekrana götüren bir düğmeyi içerir .

import CoreLocation
let locationManager = CLLocationManager()

class SettingsTableViewController:CLLocationManagerDelegate{

    func checkUsersLocationServicesAuthorization(){
        /// Check if user has authorized Total Plus to use Location Services
        if CLLocationManager.locationServicesEnabled() {
            switch CLLocationManager.authorizationStatus() {
            case .notDetermined:
                // Request when-in-use authorization initially
                // This is the first and the ONLY time you will be able to ask the user for permission
                self.locationManager.delegate = self
                locationManager.requestWhenInUseAuthorization()
                break

            case .restricted, .denied:
                // Disable location features
                switchAutoTaxDetection.isOn = false
                let alert = UIAlertController(title: "Allow Location Access", message: "MyApp needs access to your location. Turn on Location Services in your device settings.", preferredStyle: UIAlertController.Style.alert)

                // Button to Open Settings
                alert.addAction(UIAlertAction(title: "Settings", style: UIAlertAction.Style.default, handler: { action in
                    guard let settingsUrl = URL(string: UIApplication.openSettingsURLString) else {
                        return
                    }
                    if UIApplication.shared.canOpenURL(settingsUrl) {
                        UIApplication.shared.open(settingsUrl, completionHandler: { (success) in
                            print("Settings opened: \(success)") 
                        })
                    }
                }))
                alert.addAction(UIAlertAction(title: "Ok", style: UIAlertAction.Style.default, handler: nil))
                self.present(alert, animated: true, completion: nil)

                break

            case .authorizedWhenInUse, .authorizedAlways:
                // Enable features that require location services here.
                print("Full Access")
                break
            }
        }
    }
}

5

Swift3.0 ve üstü için lokasyon servislerinin kullanılabilirliği için sık sık kontroller yapılıyorsa aşağıdaki gibi bir sınıf oluşturun,

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

ve sonra bunu VC'nizde bu şekilde kullanın

    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)
        }
    }

3

-StartLocation'ı aradığınızda, konum hizmetleri kullanıcı tarafından reddedildiyse, konum yöneticisi temsilcisi hata koduyla - locationManager:didFailWithError: araması alır kCLErrorDenied. Bu hem iOS'un tüm sürümlerinde çalışır.


Teşekkürler. Denedim Ne yazık ki, bu gösterir: Use of unresolved identifier 'kCLErrorDenied'. Düşünceler?
Brendan Chang

1

Swift 3.0'da

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

Kullandığınız konum hizmetleri için izin istemek için:

yourSharedLocationManager.requestWhenInUseAuthorization()

Durum şu anda belirlenmemişse, kullanıcıdan erişime izin vermesini isteyen bir uyarı gösterilecektir. Erişim reddedilirse, uygulamanız CLLocationManagerDelegate'de bilgilendirilir, aynı şekilde herhangi bir noktada izin reddedilirse, burada güncellenirsiniz.

Mevcut izinleri belirlemek için kontrol etmeniz gereken iki ayrı durum vardır.

  • Kullanıcının genel konum hizmetlerinin etkin olup olmadığı

CLLocationManager.locationServicesEnabled()

  • Kullanıcı, uygulamanız için doğru izni verdiyse ..

CLLocationManager.authorizationStatus() == .authorizedWhenInUse

Bir uzantı ekleyebilirsiniz, kullanışlı bir seçenektir:

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

}

Burada, kullanıcı ilk yol tarifi istediğinde erişilir:

 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)
    }
}

Temsilci şöyle:

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

    if !CLLocationManager.authorizedToRequestLocation() {
        showAlertNoLocation(locationError: .invalidPermissions)
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.