IT TIP

위치 서비스가 활성화되어 있는지 확인

itqueen 2020. 11. 2. 20:11
반응형

위치 서비스가 활성화되어 있는지 확인


CoreLocation에 대한 조사를 해왔습니다. 최근에 다른 곳에서 다루었지만 Objective C 및 iOS 8에서 다루는 문제가 발생했습니다.

어리석은 질문이지만 iOS 9에서 swift를 사용하여 위치 서비스가 활성화되었는지 어떻게 확인할 수 있습니까?

iOS 7 (또는 8?)에서는을 사용할 수 locationServicesEnabled()있지만 iOS 9 용으로 컴파일 할 때는 작동하지 않는 것 같습니다.

그럼 어떻게해야할까요?

감사!


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

Objective-c에서

이미 거부되었거나 결정되지 않은 사용자를 추적 한 다음 권한을 요청하거나 사용자를 설정 앱으로 보내야합니다.

-(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 위치 관리자

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

kCLAuthorizationStatusAuthorizedAlways와 kCLAuthorizationStatusAuthorizedWhenInUse가 다릅니다.


SWIFT (2018 년 7 월 24 일 현재)

if CLLocationManager.locationServicesEnabled() {

}

사용자가 이미 앱의 위치 권한 요청에 대한 설정을 선택했는지 알려줍니다.


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

Swift 4에서는 2 줄 함수입니다.

import CoreLocation

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

다음은 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
            }
        }
    }
}

When you call -startLocation, if location services were denied by the user, the location manager delegate will receive a call to - locationManager:didFailWithError: with the kCLErrorDenied error code. This works both in all versions of iOS.


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
            }

To ask for permission for location services you use:

yourSharedLocationManager.requestWhenInUseAuthorization()

If the status is currently undetermined an alert will show prompting the user to allow access. If access is denied your app will be notified in the CLLocationManagerDelegate, likewise if permission is denied at any point you will be updated here.

There are two separate statuses you need to check to determine the current permissions.

  • If the user has the general location services enabled or not

CLLocationManager.locationServicesEnabled()

  • If the user has granted the correct permission for your app..

CLLocationManager.authorizationStatus() == .authorizedWhenInUse

You could add an extension is a handy option:

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

}

Here it is being accessed when the user has first requested directions:

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

Here is the delegate:

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

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

참고URL : https://stackoverflow.com/questions/34861941/check-if-location-services-are-enabled

반응형