🍎 아이폰 iOS ~ Swift

[iOS/Swift] 현재 위치 정보 - 위도, 경도, 주소 가져오기

핑크빛연어 2023. 8. 29. 23:06

 

안녕하세요👋🏻 iOS 에서 현재 위도, 경도, 위치 정보 가져오는 방법 포스팅 입니다.

 

 

💡 작성한 파일 목록입니다.

 • Info.plist

 • LocationVC.swift

 • Location.storyboard

 

 

Info.plist

현재 위치를 사용하는 데에 동의를 구하는 내용을 추가합니다.

Privacy - Location Always and When In Use Usage Description

value 에 원하는 문구 작성하기

 

 

LocationVC.swift

1️⃣ ViewController 에서 CoreLocationimport해줍니다.

CoreLocation 을 이용하여 위치정보를 받아와 위도, 경도를 가져올 수 있습니다.

import UIKit
import CoreLocation

class LocationVC: UIViewController {
	...
}

 

2️⃣ viewDidLoad() 에서

CLLocationManager 의 delegate 를 설정하고, 거리정확도를 설정해줍니다.

locationManager.delegate = self  // 델리게이트 설정
locationManager.desiredAccuracy = kCLLocationAccuracyBest  // 거리 정확도 설정

 

3️⃣ checkAuthorizationStatus() 함수를 호출하여 권한 상태를 확인합니다.

iOS 버전에 따라 위치 서비스 권한 부여 상태를 확인하여

위치 서비스 권한이 부여된 상태라면 locationManager.startUpdatingLocation() 코드를 통해

사용자의 현재 위치를 보고하는 업데이트 생성을 시작합니다.

/**
 * checkAuthorizationStatus()
 * - 권한 상태 확인하기
 **/
func checkAuthorizationStatus() {

    if #available(iOS 14.0, *) {

        if locationManager.authorizationStatus == .authorizedAlways
            || locationManager.authorizationStatus == .authorizedWhenInUse {
            print("==> 위치 서비스 On 상태")
            locationManager.startUpdatingLocation() //위치 정보 받아오기 시작 - 사용자의 현재 위치를 보고하는 업데이트 생성을 시작
        } else if locationManager.authorizationStatus == .notDetermined {
            print("==> 위치 서비스 Off 상태")
            locationManager.requestWhenInUseAuthorization()
        } else if locationManager.authorizationStatus == .denied {
            print("==> 위치 서비스 Deny 상태")
        }

    } else {

        // Fallback on earlier versions
        if CLLocationManager.locationServicesEnabled() {
            print("위치 서비스 On 상태")
            locationManager.startUpdatingLocation() //위치 정보 받아오기 시작 - 사용자의 현재 위치를 보고하는 업데이트 생성을 시작
            print("LocationViewController >> checkPermission() - \(locationManager.location?.coordinate)")
        } else {
            print("위치 서비스 Off 상태")
            locationManager.requestWhenInUseAuthorization()
        }

    }
}

 

4️⃣ 채택한 CLLocationManagerDelegate 프로토콜을 extension 으로 분리 시킨 후, 구현합니다.

locationManager() - didUpdateLocations 는 locationManager.startUpdatingLocation() 가 호출되었을 때 호출되고,

위도경도 값을 가져올 수 있습니다.

locationManager() - didChangeAuthorization앱의 권한이 변경되었을 때 호출됩니다.

extension LocationVC: CLLocationManagerDelegate {
    
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        print("locationManager >> didUpdateLocations 🐥 ")
        
        var longitude = CLLocationDegrees()
        var latitude = CLLocationDegrees()
         
        if let location = locations.first {
            print("위도: \(location.coordinate.latitude)")
            print("경도: \(location.coordinate.longitude)")
            longitude = location.coordinate.latitude
            latitude = location.coordinate.longitude
            
            self.txtLongitude.text = String(longitude)
            self.txtLatitude.text = String(latitude)
            
//        위도: 37.5151
//        경도: 127.0204
        }
        getAddress()
        locationManager.stopUpdatingLocation()
       
    }
    
    
    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        print("locationManager >> didChangeAuthorization 🐥 ")
        locationManager.startUpdatingLocation()  //위치 정보 받아오기 start
    }
    
    
    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        print("locationManager >> didFailWithError 🐥 ")
    }
    
}

 

5️⃣ 위도, 경도 값을 가져온 후 getAddress() 함수를 호출하여 현재 위치 주소를 가져옵니다.

/**
 * getAddress()
 * - 현재 위치 주소 가져오기
 **/
func getAddress() {
    print("CLLocationManagerDelegate >> getAddress() ")
    locationManager.delegate = self
    locationManager.distanceFilter = kCLDistanceFilterNone
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.requestWhenInUseAuthorization()
    locationManager.startUpdatingLocation()

    let geocoder = CLGeocoder.init()

    let location = self.locationManager.location

    if location != nil {
        geocoder.reverseGeocodeLocation(location!) { (placemarks, error) in
            if error != nil {
                return
            }
            if let placemark = placemarks?.first {
                var address = ""

                if let administrativeArea = placemark.administrativeArea {
                    print("== [시/도] administrativeArea : \(administrativeArea)")  //서울특별시, 경기도
                    address = "\(address) \(administrativeArea) "
                }

                if let locality = placemark.locality {
                    print("== [도시] locality : \(locality)") //서울시, 성남시, 수원시
                    address = "\(address) \(locality) "
                }

                if let subLocality = placemark.subLocality {
                    print("== [추가 도시] subLocality : \(subLocality)") //강남구
                    address = "\(address) \(subLocality) "
                }


                if let thoroughfare = placemark.thoroughfare {
                    print("== [상세주소] thoroughfare : \(thoroughfare)") //강남대로106길, 봉은사로2길
                    address = "\(address) \(thoroughfare) "
                }

                if let subThoroughfare = placemark.subThoroughfare {
                    print("== [추가 거리 정보] subThoroughfare : \(subThoroughfare)") //272-13
                    address = "\(address) \(subThoroughfare)"
                }

                print("CLLocationManagerDelegate >> getAddress() - address : \(address)")  // 서울특별시 광진구 중곡동 272-13

                self.txtAddress.text = address

            }

        }
    }
}

 

🧤 LocationVC.swift 의 전체 소스입니다.

//
//  LocationVC.swift

import UIKit
import CoreLocation

class LocationVC: UIViewController {
    
    // 주소
    @IBOutlet weak var txtAddress: UILabel!
    // 위도
    @IBOutlet weak var txtLatitude: UILabel!
    // 경도
    @IBOutlet weak var txtLongitude: UILabel!
    
    var locationManager = CLLocationManager()

    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        print("LocationVC >> viewDidLoad() ")
        
        locationManager.delegate = self  // 델리게이트 설정
        locationManager.desiredAccuracy = kCLLocationAccuracyBest  // 거리 정확도 설정
        
        checkAuthorizationStatus()
    }
    
    
    /**
     * checkAuthorizationStatus()
     * - 권한 상태 확인하기
     **/
    func checkAuthorizationStatus() {
        
        if #available(iOS 14.0, *) {
            
            if locationManager.authorizationStatus == .authorizedAlways
                || locationManager.authorizationStatus == .authorizedWhenInUse {
                print("==> 위치 서비스 On 상태")
                locationManager.startUpdatingLocation() //위치 정보 받아오기 시작 - 사용자의 현재 위치를 보고하는 업데이트 생성을 시작
            } else if locationManager.authorizationStatus == .notDetermined {
                print("==> 위치 서비스 Off 상태")
                locationManager.requestWhenInUseAuthorization()
            } else if locationManager.authorizationStatus == .denied {
                print("==> 위치 서비스 Deny 상태")
            }
            
        } else {
            
            // Fallback on earlier versions
            if CLLocationManager.locationServicesEnabled() {
                print("위치 서비스 On 상태")
                locationManager.startUpdatingLocation() //위치 정보 받아오기 시작 - 사용자의 현재 위치를 보고하는 업데이트 생성을 시작
                print("LocationViewController >> checkPermission() - \(locationManager.location?.coordinate)")
            } else {
                print("위치 서비스 Off 상태")
                locationManager.requestWhenInUseAuthorization()
            }
            
        }
    }
    
    
    /**
     * getAddress()
     * - 현재 위치 주소 가져오기
     **/
    func getAddress() {
        print("CLLocationManagerDelegate >> getAddress() ")
        locationManager.delegate = self
            locationManager.distanceFilter = kCLDistanceFilterNone
            locationManager.desiredAccuracy = kCLLocationAccuracyBest
            locationManager.requestWhenInUseAuthorization()
            locationManager.startUpdatingLocation()
        
            let geocoder = CLGeocoder.init()
            
            let location = self.locationManager.location
            
            if location != nil {
                geocoder.reverseGeocodeLocation(location!) { (placemarks, error) in
                    if error != nil {
                        return
                    }
                    if let placemark = placemarks?.first {
                        var address = ""
                        
                        if let administrativeArea = placemark.administrativeArea {
                            print("== [시/도] administrativeArea : \(administrativeArea)")  //서울특별시, 경기도
                            address = "\(address) \(administrativeArea) "
                        }
                        
                        if let locality = placemark.locality {
                            print("== [도시] locality : \(locality)") //서울시, 성남시, 수원시
                            address = "\(address) \(locality) "
                        }
                        
                        if let subLocality = placemark.subLocality {
                            print("== [추가 도시] subLocality : \(subLocality)") //강남구
                            address = "\(address) \(subLocality) "
                        }
                        
                        if let thoroughfare = placemark.thoroughfare {
                            print("== [상세주소] thoroughfare : \(thoroughfare)") //강남대로106길, 봉은사로2길
                            address = "\(address) \(thoroughfare) "
                        }
                        
                        if let subThoroughfare = placemark.subThoroughfare {
                            print("== [추가 거리 정보] subThoroughfare : \(subThoroughfare)") //272-13
                            address = "\(address) \(subThoroughfare)"
                        }
                        
                        print("CLLocationManagerDelegate >> getAddress() - address : \(address)")  // 서울특별시 광진구 중곡동 272-13
                        
                        self.txtAddress.text = address
                
                    }
             
                }
            }
        }
}


extension LocationVC: CLLocationManagerDelegate {
    
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        print("locationManager >> didUpdateLocations 🐥 ")
        
        var longitude = CLLocationDegrees()
        var latitude = CLLocationDegrees()
         
        if let location = locations.first {
            print("위도: \(location.coordinate.latitude)")
            print("경도: \(location.coordinate.longitude)")
            longitude = location.coordinate.latitude
            latitude = location.coordinate.longitude
            
            self.txtLongitude.text = String(longitude)
            self.txtLatitude.text = String(latitude)
        }
        
        getAddress()
        locationManager.stopUpdatingLocation()
       
    }
    
    
    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        print("locationManager >> didChangeAuthorization 🐥 ")
        locationManager.startUpdatingLocation()  //위치 정보 받아오기 start
    }
    
    
    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        print("locationManager >> didFailWithError 🐥 ")
    }
    
}

 

 

Location.storyboard

 

 

결과 화면

 

 

감사합니당 :)

728x90
반응형