위치권한이 필요한 프로젝트를 진행하면서, 계속 검색을 하다가 이제는 필요한 내용을 기록해야 겠다는 생각이 들어서 작성한다.
사용자의 위치권한을 받아야 하는 경우는 많지만 개인적으로 필요한 이유는,
Wi-Fi 정보를 읽기 위해서였다. 디바이스가 붙어있는 Wi-Fi 정보를 가져오려했더니 위치정보를 켜야한다나…
이쪽은 또 처음이다 보니 일단은 그런가 보다 하고 시작했다.
1. CoreLocation
위치정보를 가져오기에 앞서 import 해야할 Framework이다.
https://developer.apple.com/documentation/corelocation
coreLocation은 장치의 지리적 위치, 고도, 방향 등 정보를 가져올 수 있도록 해준다.
이 프레임워크는 Wi-Fi, GPS, Bluetooth…등 장치에서 사용 가능한 모든 구성 요소를 사용하여 데이터를 수집한다.
import CoreLocation
import한다.
2. info.plist -> Privacy - Location .... Description 추가
위치정보를 얻기 위해서는 사용자의 동의를 얻어야하므로 승인요청 팝업이 발생하게 된다.
info.plist로 이동하여 아래와 같이 두 개의 접근권한 Descrition을 추가 해줘야 한다.
만약 위 문구를 추가하지 않고 권한 요청을 하게 된다면 콘솔로그가 출력되며 원하는 동작이 이뤄지지 않는다.
3. CLLocationManager
CLLocationManager의 인스턴스를 통해 위치 서비스를 구성, 시작, 중지할 수 있다.
var locationManager: CLLocationManager?
이 위치 서비스를 사용하기 위해 앱은 사용자에게 승인을 요청하거나 거부하라는 메시지를 표시한다.
locationManager는 ‘구성가능한 정확도(아래에서 설명)’로 사용자의 현재 위치에서 크거나 작은 변화를 추적한다.
locationManager가 파악하는 변화/추적에 대해서는 delegate(CLLocationManagerDelegate)를 통해 정보를 얻을 수 있다.
ViewController에서 locationManager를 생성하고 위치정보를 얻고 싶다면 아래와 같이 작성한다.
class ViewController {
var locationManager: CLLocationManager!
func viewDidLoad() {
locationManager = CLLocationManager()
requestLocationAuthorization()
}
private func requestLocationAuthorization() { // 1
locationManager.requestWhenInUseAuthoriation() // 2
// locationManager.requestAlwaysAuthorization() // 3
}
}
- requestWhenInUseAuthorization(): 시스템 팝업을 호출한다. 사용자는 승인요청 팝업에서 수집허용을 할 수 있다.
- requestAlwaysAuthorization(): Background에서도 위치정보를 가져오기 위해 필요하다. 이처럼 특별한 경우가 아니라면 사용이 권장되지 않는다.
4. CLLocationManagerDelegate
locationManager 인스턴스를 만들었으니, location변화에 대한 정보를 받아보자.
ViewController의 extension에서는 CLLocationManagerDelegate를 채택하여 locatinoManager의 delegateMethod를 구현해주자.
override func viewDidLoad() {
super.viewDidLoad()
locationManager = CLLocationManager()
locationManager.delegate = self
requestLocationAuthorization()
}
...
}
extension ViewController: CLLocationManagerDelegate {
//14.0 미만
func locationManager(_ manager: CLLocationManager,
didChangeAuthorization status: CLAuthorizationStatus) {
}
func locationManager(_ manager: CLLocationManager,
didUpdateLocations locations: [CLLocation]) {
}
}
- didUpdateLocations: 가장 최근 위치 데이터를 배열의 마지막 요소로 포함하는 CLLocation 배열이 인자로 전달된다.
- didChangeAuthorization: 위치 추적 허가 상태의 변경을 알려준다.
!! deprecated DidChangeAuthorization
iOS 14.0부터는 아래 메서드로 호출된다.
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
// 14.0부터
}
4.1 위치 권한 상태 (CLAuthorizatinoStatus)
위치 추적 허가 상태를 나타내는 열거형
- notDetermined: 사용자가 앱이 위치 서비스를 사용할 수 있는지 선택하지 않았을 때
- restricted: 앱이 위치 서비스를 사용할 수 있는 권한이 없을 때
- denied: 앱에서 거부되었거나 혹은 전역 설정으로 위치 서비스가 비활성화 되어있을 때
- authorizedAlways: 앱이 언제든지 위치 서비스를 시작할 수 있도록 권한을 허용했을 때 ( 백그라운드 허용.capability랑 함께 봐야 하지 않을까 ...?)
- authorizedWhenInUse: 앱을 사용하는 동안에만 위치 서비스를 사용할 수 있도록 권한을 허용했을 때
만약 이러한 권한상태가 바뀌게 되는경우 델리게이트 메서드의 didChangeAuthorization이 호출된다.
func locationManager(_ manager: CLLocationManager,
didChangeAuthorization status: CLAuthorizationStatus) {
switch status {
case .notDetermined:
break
case .restricted:
break
case .denied:
break
case .authorizedAlways, .authorizedWhenInUse:
locationManager.startUpdatingLocation() //위치정보 업데이트를 시작한다.
case .authorized:
break
@unknown default:
break
}
}
4.2 정확도
위치정보의 정확성을 설정해줄 수 있다.
높은 수준의 정확도를 설정 할 수록 배터리를 많이 소모한다고 한다.
정확도는 CLLocationManager 인스턴스의 desiredAccuracy 속성을 통해 설정할 수 있다.
public let kCLLocationAccuracyBestForNavigation: CLLocationAccuracy //가장 높은 정확도- 전원이 연결된 상태에서 사용
public let kCLLocationAccuracyBest: CLLocationAccuracy
//배터리로 동작할 때 권장되는 가장 높은 수준의 정확도
public let kCLLocationAccuracyNearestTenMeters: CLLocationAccuracy //10미터 이내의 정확도
public let kCLLocationAccuracyHundredMeters: CLLocationAccuracy //100미터 이내의 정확도
public let kCLLocationAccuracyKilometer: CLLocationAccuracy //1킬로 미터 이내의 정확도
public let kCLLocationAccuracyThreeKilometers: CLLocationAccuracy // 3킬로 미터 이내의 정확도
전체 소스:
도움:
'난 iOS개발자 > iOS' 카테고리의 다른 글
Timer로 작업 예약하기 (0) | 2022.02.17 |
---|---|
정확한 위치 정보 (0) | 2022.02.16 |
JsonString 에서 Dictionary로 변환 (0) | 2022.01.27 |
현재 네트워크 정보 가져오기 CNCopyCurrentNetworkInfo (0) | 2022.01.07 |
NEHotspotNetwork를 이용한 현재 Wi-Fi 상태 가져오기 (0) | 2021.12.20 |