❗️요구사항 : 지도 페이지에서 UIButton을 눌렀을 때 현재 나의 위치로 이동하도록
Privacy - Location When In Use Usage Description
Privacy - Location Always Usage Description
Privacy - Location Always and When In Use Usage Description
앱 실행시 위치정보에 접근할 수 있도록 사용자에게 권한 설정 창을 띄운다
value에는 안내메세지를 입력한다.
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate {
let locationManager = CLLocationManager()
}
애플이 제공하는 CoreLocation 프레임워크를 사용할 준비가 되었다.
Core Location 문서
만약 협업을 하고있거나 이 기능을 구현하는 viewController 파일 안에 다른 여러 기능들도 포함한다면 가독성, 빠르게 찾을 수 있도록 extension으로 빼고 CLLocationManagerDelegate을 채택하는 것이 좋겠다.
위치 업데이트
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let location = locations.last else { return }
print("위도: \(location.coordinate.latitude), 경도: \(location.coordinate.longitude)")
}
권한 상태 변경
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
switch status {
case .authorizedAlways, .authorizedWhenInUse:
print("권한 설정됨")
locationManager.startUpdatingLocation()
case .notDetermined:
print("권한 설정되지 않음")
case .restricted, .denied:
print("권한 요청 거부됨")
default:
print("알 수 없는 권한 상태")
}
}
오류 처리
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("위치 정보를 가져오는데 실패했습니다: \(error.localizedDescription)")
}
//MARK: - 현재 위치 파악
private func setupMyLocationButton() {
guard let myLocationButton = mapView?.myLocationButton else {
return
}
myLocationButton.addTarget(self, action: #selector(myLocationButtonTapped), for: .touchUpInside)
}
@objc func myLocationButtonTapped() {
locationManager.requestLocation()
if let location = locationManager.location {
// 업데이트된 현재 위치로 카메라 이동
moveCameraToCurrentLocation(location.coordinate)
}
}
private func setLocation() {
// CLLocationManager의 delegate 설정
// 위치 관련 이벤트를 현재 클래스에서 처리하도록 함
locationManager.delegate = self
// 위치 정확도를 최고로 설정
// 배터리 소모가 증가할 수 있으나 가장 정확한 위치 정보를 제공
locationManager.startUpdatingLocation()
// 앱이 사용 중일 때 위치 접근 권한 요청
// 이 메서드 호출 시 사용자에게 위치 권한 허용 여부를 묻는 알림이 표시됨
locationManager.requestWhenInUseAuthorization()
}
}
extension MapViewController: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let location = locations.last else { return }
print("위도: \(location.coordinate.latitude), 경도: \(location.coordinate.longitude)")
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
switch status {
case .authorizedAlways, .authorizedWhenInUse:
print("권한 설정됨")
locationManager.startUpdatingLocation()
case .notDetermined:
print("권한 설정되지 않음")
case .restricted, .denied:
print("권한 요청 거부됨")
@unknown default:
print("알 수 없는 위치")
}
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("위치 정보를 가져오는데 실패했습니다: \(error.localizedDescription)")
// 사용자에게 오류 메시지를 표시
showToast(self.view, message: "위치 정보를 가져오는데 실패했습니다.")
// CLError 타입으로 다운캐스팅하여 구체적인 에러 처리
if let clError = error as? CLError {
switch clError.code {
case .denied:
print("위치 서비스가 비활성화되었습니다. 설정에서 활성화해주세요.")
case .network:
print("네트워크 오류가 발생했습니다.")
default:
print("알 수 없는 오류가 발생했습니다.")
}
}
}
// 로드된 카카오맵 위에서 버튼 클릭 시 현재위치로 카메라 전환
private func moveCameraToCurrentLocation(_ coordinate: CLLocationCoordinate2D) {
// CLLocationCoordinate2D를 KakaoMap SDK의 MapPoint로 변환
let currentPosition = MapPoint(longitude: coordinate.longitude, latitude: coordinate.latitude)
// KakaoMap 인스턴스 가져오기
// 타입 캐스팅으로 KakaoMap 타입으로 변환
if let mapView = mapController?.getView("mapview") as? KakaoMap {
// CameraUpdate를 사용하여 카메라 이동
// target: 이동할 위치, zoomLevel: 확대 수준 1~20, 숫자가 클수록 확대됨
mapView.moveCamera(CameraUpdate.make(target: currentPosition, zoomLevel: 15, mapView: mapView))
}
}
}
실행하고 시뮬레이터를 띄운 채로 상단 메뉴
Features > Location > Custom Location 에서 위도,경도 값을 입력하면 현재 위치로 설정할 수 있다.