https://explorer89.tistory.com/159
위치정보를 받아오는 방법
참고 사이트 https://velog.io/@maddie/iOS-UIKit-CoreLocation-%EC%82%AC%EC%9A%A9%EB%B2%95-%EC%A0%95%EB%A6%AC" data-og-host="velog.io" data-og-source-url="https://velog.io/@maddie/iOS-UIKit-CoreLocation-%EC%82%AC%EC%9A%A9%EB%B2%95-%EC%A0%95%EB%A6%AC" da
explorer89.tistory.com
이전에 작성한 위치 정보를 받아오는 법에서 좀 더 업데이트 했습니다.
✅ Import CoreLocation 선언
import UIKit
import CoreLocation
✅ viewDidLoad() 내에 delegate 선언
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
}
✅ CLLocationManagerDelegate 채택 및 메서드 설정
extension HomeViewController: CLLocationManagerDelegate {
/*
func checkUserDeviceLocationServiceAuthorization() {
// 1. 디바이스 차원의 위치 서비스가 켜져 있는지 확인
guard CLLocationManager.locationServicesEnabled() else {
showRequestLocationServiceAlert()
return
}
// 2. 위치 권한 요청 (결과는 delegate 메서드에서 처리)
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
}
*/
// iOS 14 이상 권한 변경 감지 콜백
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
handleAuthorizationStatus(manager.authorizationStatus)
}
// iOS 14 미만 권한 변경 감지 콜백
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
handleAuthorizationStatus(status)
}
// 실제 권한 상태에 따라 분기 처리하는 함수
private func handleAuthorizationStatus(_ status: CLAuthorizationStatus) {
switch status {
case .notDetermined:
// 사용자가 아직 권한 선택을 하지 않은 상태 (다시 request 요청함)
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
case .restricted, .denied:
// 설정에서 위치 권한을 꺼뒀거나 제한된 경우
showRequestLocationServiceAlert()
case .authorizedWhenInUse, .authorizedAlways:
// 권한이 허용된 상태 → 위치 정보 요청
locationManager.startUpdatingLocation()
default:
print("Unhandled status: \(status.rawValue)")
}
}
// 위치 업데이트 콜백
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let coordinate = locations.last?.coordinate {
// ⭐️ 사용자 위치 정보 활용
print("사용자 위치: \(coordinate.latitude), \(coordinate.longitude)")
}
locationManager.stopUpdatingLocation()
}
// 위치 요청 실패 콜백
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("❌ 위치 정보 가져오기 실패: \(error.localizedDescription)")
}
// 위치 권한이 꺼져있는 경우 사용자 설정 유도
func showRequestLocationServiceAlert() {
let alert = UIAlertController(
title: "위치 정보 이용",
message: "위치 서비스를 사용할 수 없습니다.\n디바이스의 '설정 > 개인정보 보호'에서 위치 서비스를 켜주세요.",
preferredStyle: .alert
)
let goSetting = UIAlertAction(title: "설정으로 이동", style: .destructive) { _ in
if let appSetting = URL(string: UIApplication.openSettingsURLString) {
UIApplication.shared.open(appSetting)
}
}
let cancel = UIAlertAction(title: "취소", style: .default) { [weak self] _ in
self?.reloadDataIfNeeded()
}
alert.addAction(cancel)
alert.addAction(goSetting)
present(alert, animated: true)
}
// `reloadData` 대체용 (선택사항)
private func reloadDataIfNeeded() {
// 권한이 거부된 후 UI를 갱신하거나 데이터를 다시 로드하고 싶다면 여기에 작성
print("🔄 위치 권한 거부: UI 갱신 필요 시 이곳에서 처리")
}
}
🔍 왜 viewDidLoad()에서 권한 요청을 호출하지 않아도 동작할까?
CLLocationManager는 delegate를 설정하고 앱이 실행되면, 시스템이 알아서 locationManagerDidChangeAuthorization(_:)을 호출
그리고 거기서 authorizationStatus를 읽고 .notDetermined 상태일 경우에 우리가 직접 requestWhenInUseAuthorization()을 호출
private func handleAuthorizationStatus(_ status: CLAuthorizationStatus) {
switch status {
case .notDetermined:
// 사용자가 아직 권한 선택을 하지 않은 상태 (다시 request 요청함)
// ✅ 이 부분을 말함
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
case .restricted, .denied:
// 설정에서 위치 권한을 꺼뒀거나 제한된 경우
showRequestLocationServiceAlert()
case .authorizedWhenInUse, .authorizedAlways:
// 권한이 허용된 상태 → 위치 정보 요청
locationManager.startUpdatingLocation()
default:
print("Unhandled status: \(status.rawValue)")
}
}
'Project > CafePoCa' 카테고리의 다른 글
🔍 SearchController를 통해 검색 기능 구현하기 (3) | 2025.06.10 |
---|---|
🤔 깃 브랜치 구조는 어떻게 할래? (0) | 2025.06.06 |
✅ collectionview 위에 headerview 구현하기 (1) | 2025.06.05 |