swift CoreLocation 을 이용해서 현재 위치 잡기 + kakaoMap

임혜정·2024년 7월 24일
0
post-thumbnail
post-custom-banner

❗️요구사항 : 지도 페이지에서 UIButton을 눌렀을 때 현재 나의 위치로 이동하도록

1. info.plist 설정

Privacy - Location When In Use Usage Description
Privacy - Location Always Usage Description
Privacy - Location Always and When In Use Usage Description

앱 실행시 위치정보에 접근할 수 있도록 사용자에게 권한 설정 창을 띄운다
value에는 안내메세지를 입력한다.

2. viewController 설정

import CoreLocation

class ViewController: UIViewController, CLLocationManagerDelegate {

	let locationManager = CLLocationManager()

}

애플이 제공하는 CoreLocation 프레임워크를 사용할 준비가 되었다.
Core Location 문서

만약 협업을 하고있거나 이 기능을 구현하는 viewController 파일 안에 다른 여러 기능들도 포함한다면 가독성, 빠르게 찾을 수 있도록 extension으로 빼고 CLLocationManagerDelegate을 채택하는 것이 좋겠다.

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

4. 전체 코드

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

5.실행

실행하고 시뮬레이터를 띄운 채로 상단 메뉴
Features > Location > Custom Location 에서 위도,경도 값을 입력하면 현재 위치로 설정할 수 있다.

profile
오늘 배운걸 까먹었을 미래의 나에게..⭐️
post-custom-banner

0개의 댓글