Programming/iOS

[iOS] Location Service - 위치 권한에 대한 모든 것

devssun 2021. 10. 30. 15:38
728x90
반응형

위치 권한에 대한 모든것

위치 정보는 개인정보이기 때문에 앱에서 사용자의 위치를 얻기 위해선 권한이 있어야한다. 이것을 받으려면 어떻게 해야하는지 확인해보자.
requesting_authorization_for_location_services
choosing_the_location_services_authorization_to_request

 

내비게이션앱에서 백그라운드로 내리면 PIP처럼 작은 내비가 뜨는 기능을 만들어보고 싶어서 이 프로젝트를 시작했는데, 아무리 찾아도 안나왔다. 알고보니 iOS는 '다른 앱 위에 그리기' 기능을 제공하지 않는다고.

혹시 그 기능을 구현하고 싶은 분들이 계시다면 참고하기 바랍니다. iOS는 안드로이드 티맵/카카오T나 Facebook chat 처럼 다른 앱 위에 그리기 기능이 되지 않습니다~

그래서 위치 서비스에 대해 알아보기로 했다.

 

위치 권한 상태 (CLAuthorizationStatus)

이 상태는 다른 권한 (카메라, 앨범, 마이크 등)도 있는데 각 권한에 따라 프로퍼티가 약간 차이가 있을 뿐 거의 비슷하다.

  • notDetermined : 사용자가 앱이 위치 서비스를 사용할 수 있는지 선택하지 않았을 때
  • restricted : 앱이 위치 서비스를 사용할 수 있는 권한이 없을 때
  • denied : 앱에서 거부되었거나 혹은 전역 설정으로 위치 서비스가 비활성화 되어있을 때
  • authroizedAlways : 앱이 언제든지 위치 서비스를 시작할 수 있도록 권한을 허용했을 때
  • authroizedWhenInUse : 앱을 사용하는 동안에만 위치 서비스를 사용할 수 있도록 권한을 허용했을 때

When In Use와 Always의 차이

앱에서 요청할 수 있는 승인에는 두 가지 유형이 있다.

  • When In Use : 앱이 사용되는 동안 앱은 모든 위치 서비스를 사용하고 이벤트를 수신할 수 있다. 일반적으로 iOS 앱은 foreground에 있거나 background location usage indicator가 활성화된 background에서 실행 중인 경우 사용 중인 것으로 간주된다.
    • 가능하면 When In Use 승인을 요청해야한다.
  • Always : 사용자가 앱이 실행되고 있다는 사실을 알지 못하는 경우에도 앱은 모든 위치 서비스를 사용하고 이벤트를 수신할 수 있다. 앱이 실행되고 있지 않으면 시스템이 앱을 실행하고 이벤트를 전달할 수 있다.
    • 위치 정보가 필요할 때마다 사용자가 앱을 사용할 수 없거나 사용하고 싶지 않은 상황에서 앱에 Always 권한 부여가 필요할 수 있다.
    • ex) 자동화된 작업을 수행하는 앱, 일기 앱과 같이 하루종일 위치를 기족하는 앱 (사용자가 앱이 사용 중이 아닐 때도 묻지 않고 위치를 기록할 수 있도록), 코로나 동선 안심이 앱 같이 계속 위치 수집이 필요한 앱
    • Always 권한을 가진 앱은 나중에 OS에서 아래와 같은 알럿이 뜨고 사용자가 권한을 유지할 건지 바꿀 건지 선택할 수 있게 된다. (아무래도 이 권한으로 쓰다보면 배터리 소모도 빨라지고 사용자는 원하지 않는 위치 공유를 하고 있을 수도 있어서 알럿을 띄우는 게 아닐까 생각된다.)

앱이 When In Use 권한을 요청하고 받은 경우 나중에 Always 권한을 별도로 요청할 수 있다. 그러나 앱은 권한 부여에 대해 한 번만 요청할 수 있다.

위치 범위 상태 (CLAccuracyAuthorization)

iOS 14부터 사용자는 위치 범위를 정확하게 혹은 대략적으로 제공할 수 있게 되었다. 아래와 같은 팝업에서 '정확한 위치'를 켜거나 끄면 된다. (claccuracyauthorization)

  • 이 옵션 역시 앱에서 원하는 옵션을 받을 수 있도록 요청 팝업을 띄울 수 있는데 네비게이션 같이 정확한 위치가 필요한 경우 정확한 위치를 요청하는 것이 좋을 것 같다. 그외에 꼭 정확한 위치가 필요한 게 아니라면 굳이 요청할 필요는 없겠다.
    • fullAccuracy : 정확한 위치 데이터에 접근
    • reducedAccuracy : 대략적 위치 데이터에 접근
  • 사용자는 앱에게 정확한 위치를 제공하고 싶지 않다면 설정앱 > 개인 정보 보호 > 위치 서비스 > 앱에 들어가서 바꿔주면 된다.

앱에서 위치 권한 요청하기

Info.plist에 권한 추가하기

사진과 같이 위치 권한을 요청하기 위해 앱이 사용할 권한을 `Info.plist`에 추가해야 한다. 위치 권한에 필요한 키는 두개, 이 키를 추가하지 않고 권한 요청을 하면 에러가 발생한다. 그리고 설명을 적지 않으면 AppStoreConnect에 빌드를 올릴 수 없다.

설명에는 왜 앱에서 해당 권한이 필요한건지 간략하게 작성해주면 된다. (이는 카메라, 사진앨범 등도 동일하다.)



- NSLocationAlwaysUsageDescription (deprecated 10.0)
- NSLocationAlwaysAndWhenInUseUsageDescription (iOS 11.0 +)

정확한 위치가 필요한 경우 아래 권한도 추가해준다.

- NSLocationTemporaryUsageDescriptionDictionary

 

위치 권한 요청 팝업 띄우기

앱에서 위치 권한을 요청하는 방법은 간단하다. CLLocationManager 객체의 requestWhenInUseAuthorization() 를 호출하면 된다.
viewDidLoad에서 현재 앱 권한을 가져와서 권한이 없는 경우 요청하도록 코드를 넣어보자.

class ViewController: UIViewController {

	// CLLocationManager 객체 생성
    let locationManager = CLLocationManager()

    override func viewDidLoad() {
        super.viewDidLoad()

        locationManager.delegate = self

        // 위치 권한 체크해서 없는 경우 요청하는 코드
        switch locationManager.authorizationStatus {
        case .denied:
            // 거부 상태라면 알럿을 띄워 허용하도록 유도하는 코드를 넣을 수 있다.
            print("위치 비허용")
        case .notDetermined, .restricted:
            // request
            locationManager.requestWhenInUseAuthorization()
        default:
            break
        }

        // 위치 범위가 대략적 범위로 되어있다면 정확한 위치를 공유하도록 요청하기
        switch locationManager.accuracyAuthorization {
        case .reducedAccuracy:
            locationManager.requestTemporaryFullAccuracyAuthorization(withPurposeKey: "")
        case .fullAccuracy:
			// 이미 정확한 위치를 공유하고 있는데 또 요청하면 오류가 발생한다.
            break
        @unknown default:
            break
        }
    }
}
반응형