ตรวจสอบว่ามีการเปิดใช้บริการตำแหน่งหรือไม่


88

ฉันได้ทำการค้นคว้าเกี่ยวกับ CoreLocation เมื่อเร็ว ๆ นี้ฉันพบปัญหาที่ครอบคลุมในที่อื่น แต่ใน Objective C และสำหรับ iOS 8

ฉันรู้สึกโง่ที่ถามเรื่องนี้ แต่คุณจะตรวจสอบได้อย่างไรว่าบริการระบุตำแหน่งเปิดใช้งานโดยใช้ swift บน iOS 9 หรือไม่?

บน iOS 7 (และอาจจะเป็น 8?) คุณสามารถใช้ได้locationServicesEnabled()แต่ดูเหมือนว่าจะใช้งานไม่ได้เมื่อคอมไพล์สำหรับ iOS 9

แล้วฉันจะทำสิ่งนี้ให้สำเร็จได้อย่างไร?

ขอบคุณ!

คำตอบ:


247

เพิ่มในCLLocationManagerDelegateการสืบทอดคลาสของคุณจากนั้นคุณสามารถทำการตรวจสอบนี้ได้:

เวอร์ชัน 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")
}

เวอร์ชัน 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")
}

เวอร์ชัน 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")
}

8
ได้! ขอบคุณ! ปัญหาของฉันคือฉันพยายามโทรหา locatoinServicesEnabled ในผู้จัดการของฉันนั่นคือ manager.locationServicesEnabled() แทนที่จะ CLLocationManager.loationServicesEnabled() แก้ไข!
Brendan Chang

2
ฉันได้รับมันว่ารหัสของคุณเป็นเพียงตัวอย่าง แต่ก็ทำให้เข้าใจผิดเล็กน้อย ... ฉันคิดว่ามันจะดีกว่าเมื่อauthorizationStatusมีการตั้งค่าไปnotDeterminedแล้วแทนเพียงเข้าสู่ระบบมันจะดีกว่าที่จะแจ้งให้ผู้ใช้ 'อนุญาต / ไม่อนุญาตให้"
น้ำผึ้ง

@ ฮันนี่แน่ใจว่าคุณสามารถใช้มันได้ตามที่คุณต้องการและอย่างที่คุณบอกว่าโค้ดเป็นเพียงตัวอย่างเพื่อแสดงให้เห็นว่าสามารถใช้งานได้อย่างไร
Rashwan L

13

ในวัตถุประสงค์ -c

คุณควรติดตามผู้ใช้ที่ถูกปฏิเสธหรือไม่ได้รับการพิจารณาจากนั้นขออนุญาตหรือส่งผู้ใช้ไปยังแอพ Setting

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

}

ใช้ alertView Delegate จากนั้นส่งผู้ใช้เพื่อเปิดใช้งานบริการตำแหน่งหากผู้ใช้ปฏิเสธแล้ว

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

โปรดทราบว่า kCLAuthorizationStatusAuthorizedAlways และ kCLAuthorizationStatusAuthorizedWhenInUse คือความแตกต่าง


ขอบคุณสำหรับวัตถุประสงค์ -C เวอร์ชันนี้แม้ว่าคำถามเดิมจะเกี่ยวกับความรวดเร็ว คำแนะนำเพิ่มเติม: call requestWhenInUseAuthorization หากไม่ได้กำหนดสถานะให้ตั้งค่ารายการ plist ที่เกี่ยวข้องสำหรับคำอธิบายการใช้งาน (อาจแปลเป็นภาษาท้องถิ่น) และอาจใช้ didChangeAuthorizationStatus
Giorgio Barchiesi

9

SWIFT (ณ วันที่ 24 กรกฎาคม 2018)

if CLLocationManager.locationServicesEnabled() {

}

สิ่งนี้จะบอกคุณว่าผู้ใช้ได้เลือกการตั้งค่าสำหรับคำขออนุญาตตำแหน่งของแอปแล้วหรือไม่


8

มันเป็นเพียงฟังก์ชั่น 2 บรรทัดใน Swift 4:

import CoreLocation

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

6

นี่คือรูปแบบที่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
      }

นี่คือตัวอย่างที่สมบูรณ์

ซึ่งรวมถึงAlertViewปุ่มเพื่อนำผู้ใช้ไปที่Settingsหน้าจอหากก่อนหน้านี้ถูกปฏิเสธการเข้าถึง

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 ขึ้นไปหากมีการตรวจสอบความพร้อมของบริการระบุตำแหน่งบ่อยๆให้สร้างคลาสดังต่อไปนี้

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

แล้วใช้แบบนี้ใน 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)
        }
    }

3

เมื่อคุณเรียกใช้ -startLocation หากบริการตำแหน่งถูกปฏิเสธโดยผู้ใช้ผู้รับมอบสิทธิ์ผู้จัดการสถานที่จะได้รับสายไปที่ - locationManager:didFailWithError: พร้อมkCLErrorDeniedรหัสข้อผิดพลาด ซึ่งใช้ได้ทั้งใน iOS ทุกเวอร์ชัน


ขอบคุณ. น่าเสียดายที่เมื่อฉันลองแล้วมันแสดง: Use of unresolved identifier 'kCLErrorDenied'. ความคิด?
Brendan Chang

1

ใน 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

ในการขออนุญาตสำหรับบริการระบุตำแหน่งที่คุณใช้:

yourSharedLocationManager.requestWhenInUseAuthorization()

หากสถานะไม่ได้กำหนดไว้ในขณะนี้การแจ้งเตือนจะแสดงข้อความแจ้งให้ผู้ใช้อนุญาตการเข้าถึง หากการเข้าถึงถูกปฏิเสธแอปของคุณจะได้รับการแจ้งเตือนใน CLLocationManagerDelegate เช่นเดียวกันหากการอนุญาตถูกปฏิเสธคุณจะได้รับการอัปเดตที่นี่

มีสองสถานะแยกกันที่คุณต้องตรวจสอบเพื่อกำหนดสิทธิ์ปัจจุบัน

  • หากผู้ใช้มีการเปิดใช้บริการตำแหน่งทั่วไปหรือไม่

CLLocationManager.locationServicesEnabled()

  • หากผู้ใช้ได้ให้สิทธิ์ที่ถูกต้องสำหรับแอปของคุณ ..

CLLocationManager.authorizationStatus() == .authorizedWhenInUse

คุณสามารถเพิ่มส่วนขยายเป็นตัวเลือกที่มีประโยชน์:

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

}

ที่นี่จะถูกเข้าถึงเมื่อผู้ใช้ขอเส้นทางครั้งแรก:

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

นี่คือผู้รับมอบสิทธิ์:

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

    if !CLLocationManager.authorizedToRequestLocation() {
        showAlertNoLocation(locationError: .invalidPermissions)
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.