programing

위치 서비스를 사용할 수 있는지 확인

css3 2023. 8. 8. 21:48

위치 서비스를 사용할 수 있는지 확인

저는 CoreLocation에 대해 조사하고 있습니다.최근에 저는 목표 C와 iOS 8에서 다른 곳에서 다루어진 문제에 직면했습니다.

이런 질문을 하는 것은 좀 바보 같지만 iOS 9에서 swift를 사용하여 위치 서비스가 가능한지 어떻게 확인할 수 있습니까?

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

그럼 제가 어떻게 이 일을 해낼 수 있을까요

감사합니다!

추가합니다.CLLocationManagerDelegate클래스 상속에 대한 다음 검사를 수행할 수 있습니다.

핵심 위치 프레임워크 가져오기

import CoreLocation

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

iOS 14.x

In iOS 14 you will get the following error message: authorizationStatus()가 iOS 14.0에서 더 이상 사용되지 않습니다.

To solve this, use the following:
private let locationManager = CLLocationManager()

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

목적어-c에서

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

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

초기 위치 관리자

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

kCLA 허가 상태를 참고하십시오.승인됨항상 및 kCLA 권한 부여 상태승인됨사용 중인 경우가 다릅니다.

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

Swift 4에서는 2개의 라인 기능만 제공되는 기능은 다음과 같습니다.

import CoreLocation

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

스위프트 (2018년 7월 24일 기준)

if CLLocationManager.locationServicesEnabled() {

}

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

swift 3.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)
        }
    }

-startLocation을 호출하면 위치 서비스가 사용자에 의해 거부된 경우 위치 관리자 대리인은 -로 전화를 받게 됩니다.locationManager:didFailWithError와 함께kCLErrorDenied오류 코드이것은 모든 버전의 iOS에서 모두 작동합니다.

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
            }

사용하는 위치 서비스에 대한 권한을 요청하려면 다음과 같이 하십시오.

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

스위프트 5.2

먼저 사용자 클래스를 CLLocationManager 대리자로 설정합니다.

import SwiftUI
import CoreLocation

class User: NSObject, ObservableObject {

   let manager = CLLocationManager()

   override init() {
      super.init()
      manager.delegate = self
      manager.requestWhenInUseAuthorization()
      manager.requestLocation()
      manager.startUpdatingLocation()
   }
}

extension User: CLLocationManagerDelegate {

   func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
      print("Location services authorization request")
   }

   func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
      print("Location updated")
   }

   func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
      print("Failed to find user's location: \(error.localizedDescription)")
   }
 }

그러면 보기에서:

if (user.manager.authorizationStatus == .denied) {
   print("Location authorization denied, displaying sheet.")      
}

제 솔루션은 다음과 같습니다.

import CoreLocation
import Combine

class LocationManager: NSObject, CLLocationManagerDelegate {
    static let shared = LocationManager()
    private (set) var didChangeLocationAuthorization: CurrentValueSubject<CLAuthorizationStatus, Never> = .init(.notDetermined)
    
    private let manager = CLLocationManager()
    private let notificationCenter = NotificationCenter.default
    var authorizationStatus: CLAuthorizationStatus = .notDetermined
    
    private override init() { }
    
    func checkLocationService() {
        setupLocationManager()
        checkLocationManagerAuthorization()
    }
    
    private func setupLocationManager() {
        manager.delegate = self
        manager.desiredAccuracy = kCLLocationAccuracyBest
    }
    
    private func checkLocationManagerAuthorization() {
        authorizationStatus = manager.authorizationStatus
        switch authorizationStatus{
            case .notDetermined:
                print("::: -> Location: notDetermined")
                manager.requestWhenInUseAuthorization()
                
            case .authorizedAlways, .authorizedWhenInUse:
                print("::: -> Location: authorizedWhenInUse")
                manager.startUpdatingLocation()
                
            case .denied, .restricted:
                print("::: -> Location: denied")
            default:
                break
        }
    }
    
    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        checkLocationManagerAuthorization()
        didChangeLocationAuthorization.send(manager.authorizationStatus)
    }
    
    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        manager.stopUpdatingLocation()
    }
}

다음과 같이 사용:

LocationManager.shared.checkLocationService()
LocationManager.shared.didChangeLocationAuthorization
    .sink { [weak self] authorization in
        print("::: Location Permission: \(authorization)")
    }.store(in: &cancelBag)

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