Periksa apakah layanan lokasi diaktifkan

88

Saya telah melakukan beberapa penelitian tentang CoreLocation. Baru-baru ini, saya mengalami masalah yang telah dibahas di tempat lain, tetapi di Objective C, dan untuk iOS 8.

Saya merasa agak konyol menanyakan ini, tetapi bagaimana Anda bisa memeriksa apakah layanan lokasi diaktifkan menggunakan swift, di iOS 9?

Di iOS 7 (dan mungkin 8?) Anda dapat menggunakan locationServicesEnabled(), tetapi itu tampaknya tidak berfungsi saat menyusun untuk iOS 9.

Jadi bagaimana saya melakukannya?

Terima kasih!

Brendan Chang
sumber

Jawaban:

247

Tambahkan CLLocationManagerDelegateke warisan kelas Anda dan kemudian Anda dapat melakukan pemeriksaan ini:

Versi Swift 1.x - 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")
}

Versi Swift 4.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")
}

Versi Swift 5.1

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")
}
Rashwan L.
sumber
8
Ya! Terima kasih! Masalah saya adalah bahwa saya mencoba memanggil locatoinServicesEnabled di manajer saya, yaitu manager.locationServicesEnabled() daripada CLLocationManager.loationServicesEnabled() Dipecahkan!
Brendan Chang
2
Saya mengerti bahwa kode Anda hanya sebuah contoh, tapi itu sedikit menyesatkan ... Saya pikir lebih baik saat authorizationStatusini ditetapkan untuk notDeterminedkemudian bukan hanya penebangan akan lebih baik untuk meminta pengguna 'Izinkan / Jangan Biarkan"
Madu
@Honey, tentu saja Anda dapat menggunakannya sesuka Anda dan seperti yang Anda katakan, kode tersebut hanyalah contoh untuk menunjukkan bagaimana kode itu dapat digunakan.
Rashwan L
13

Dalam tujuan-c

Anda harus melacak pengguna yang sudah ditolak atau tidak ditentukan kemudian meminta izin atau mengirim pengguna ke aplikasi Pengaturan.

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

}

Implementasikan alertView Delegate kemudian kirim pengguna untuk mengaktifkan layanan lokasi jika sudah ditolak oleh pengguna.

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

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

Manajer Lokasi Init

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

Harap perhatikan perbedaan kCLAuthorizationStatusAuthorizedAlways dan kCLAuthorizationStatusAuthorizedWhenInUse.

Marosdee Uma
sumber
Terima kasih untuk versi objektif-c ini, meskipun pertanyaan aslinya adalah tentang cepat. Petunjuk tambahan: panggil requestWhenInUseAuthorization jika status tidak ditentukan, setel entri plist yang relevan untuk deskripsi penggunaan (mungkin dilokalkan), dan mungkin terapkan didChangeAuthorizationStatus
Giorgio Barchiesi
9

SWIFT (Per 24 Juli 2018)

if CLLocationManager.locationServicesEnabled() {

}

ini akan memberi tahu Anda jika pengguna telah memilih pengaturan untuk permintaan izin lokasi aplikasi

BennyTheNerd
sumber
8

Ini hanya fungsi 2 baris di Swift 4:

import CoreLocation

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

Berikut adalah format yang direkomendasikan Apple .

  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
      }

Berikut contoh lengkapnya.

Ini termasuk AlertViewtombol dengan untuk membawa pengguna ke Settingslayar jika sebelumnya ditolak aksesnya.

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
            }
        }
    }
}
fs_tigre
sumber
5

Untuk swift3.0 dan yang lebih baru, jika sering dilakukan pemeriksaan untuk ketersediaan layanan lokasi, buat kelas seperti di bawah ini,

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

dan kemudian gunakan seperti ini di VC Anda

    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)
        }
    }
Sri Hari YS
sumber
3

Saat Anda memanggil -startLocation, jika layanan lokasi ditolak oleh pengguna, delegasi pengelola lokasi akan menerima panggilan ke - locationManager:didFailWithError: dengan kCLErrorDeniedkode kesalahan. Ini berfungsi baik di semua versi iOS.

Shaheen Sharifian
sumber
Terima kasih. Sayangnya, ketika saya mencoba itu, itu menunjukkan: Use of unresolved identifier 'kCLErrorDenied'. Pikiran?
Brendan Chang
1

Di 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
            }
Amul4608
sumber
1

Untuk meminta izin layanan lokasi yang Anda gunakan:

yourSharedLocationManager.requestWhenInUseAuthorization()

Jika status saat ini belum ditentukan, peringatan akan muncul meminta pengguna untuk mengizinkan akses. Jika akses ditolak, aplikasi Anda akan diberi tahu di CLLocationManagerDelegate, demikian pula jika izin ditolak, Anda akan diperbarui di sini.

Ada dua status terpisah yang perlu Anda periksa untuk menentukan izin saat ini.

  • Jika pengguna mengaktifkan layanan lokasi umum atau tidak

CLLocationManager.locationServicesEnabled()

  • Jika pengguna telah memberikan izin yang benar untuk aplikasi Anda ..

CLLocationManager.authorizationStatus() == .authorizedWhenInUse

Anda dapat menambahkan ekstensi adalah opsi praktis:

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

}

Ini sedang diakses ketika pengguna pertama kali meminta petunjuk arah:

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

Berikut delegasinya:

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

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