[iOS/Swift] MapKit - 위치 권한 설정을 구현해보자!

2023. 10. 1. 18:16·iOS/UIKit&SwiftUI

위치 권한 진행 방법을 결정 하려면 권한 부여 상태와 정확도 값을 모두 확인해야 한다.

위치서비스

  • o 권한 요청
    • 권한 허용
      • 사용자 정보 접근 가능
      • 추후 거부 (설정 → 옵션 끄기)
        • ios 시스템 설정 유도
    • 권한 거부
      • ios 시스템 설정 유도
  • x 권한 없음
    • alert → ios 시스템 설정 유도

 

  1. CoreLocation import
import CoreLocation 
  1. 위치 매니저 인스턴스 생성
private let locationManager = CLLocationManager() 
  1. delegate 연결
locationManager.delegate = self 
  1. 프로토콜 연결해주기
extension MainMapViewController: CLLocationManagerDelegate {
    
    
    // 사용자의 위치를 성공적으로 가져옴
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        
    }
    
    
    // 사용자의 위치를 가져오지 못함
    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        
    }
    
    // 사용자의 권한 상태가 바뀜을 체크함(iOS 14~)
    func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
        
    }
    
}

✅ info.plist

  • Privacy - Location When In Use Usage Description
    • iOS 11이상
    • iOS 앱이 포그라운드에서 실행 중일 때만 위치 정보 엑세스할 때
  • Privacy - Location Always and When in Use Usage Description
    • iOS 11~
    • iOS 앱이 백그라운드에서 실행되는 동안 위치 정보 액세스 하는 경우
  • Privacy - Location Default Accuracy Reduced
    • iOS 14이상
    • 위치 정확도에 대한 앱의 기본 동작을 설정하려면 정보 속성 목록에 이 키를 포함할 수 있다.
  • Privacy - Location Always Usage Description
    • iOS 11 이전 대상에 배포하는 경우
    • 백그라운드에서 위치 정보에 액세스 하는 경우

 

나의 앱은 앱 실행시에만 위치 정보에 엑세스 할 예정

⇒ Location When In Use Usage Description 사용

Untitled.png

)

Untitled.png

다국어 대응을 하고있기 때문에 다국어 키값을 value에 입력하였다.

 

 

Untitled.png

✅ 위치 서비스 활성화 체크

Untitled.png

위치 서비스가 활성화되어 있다면 CLLocationManager를 통해 이 앱에 대한 위치 권한 상태를 확인해야 한다.

 

self.locationManager.authroizationStatus 는 iOS 14.0 이상 버전에서만 사용이 가능하다 iOS 14.0이하에서는 CLLocationManager.authorizationStatus() 를 사용하면 된다.

✅ 권한 상태

위치 서비스가 활성화 되었을 때 사용자의 권한 상태를 확인해야 한다.

// 권한 상태 확인
func checkCurrentLocationAuthorization(status: CLAuthorizationStatus) {
    switch status {
    case .notDetermined: // 사용자가 권한 설정 여부를 선택 안함
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.requestWhenInUseAuthorization()
    case .restricted: // 위치 서비스 사용 권한이 없음
        showOKAlert(title: "locationAlertTitle".localized(), message: "location_Restricted".localized()) { }
    case .denied: // 사용자가 권한 요청 거부
        showRequestLocationServiceAlert()
        print("denied")
    case .authorizedAlways:
        print("authorizedAlways")
    case .authorizedWhenInUse:
        locationManager.startUpdatingLocation()
    @unknown default: print("default")
    }
}
  • notDetermined
    • 앱이 위치 서비스를 사용할 수 있는지에 대한 여부를 사용자가 선택하지 않은 경우
  • restricted
    • 앱이 위치 서비스를 사용할 권한이 없는 경우
    • ex) 자녀 보호 기능과 같은 활성 제한으로 이 앱의 상태를 변경할 수 없는 상태
  • denied
    • 사용자가 권한 요청 얼럿에서 앱의 위치 서비스 사용을 거부한 경우
    • 사용자가 허용을 했더라도 추후 설정에서 비활성화 한 경우
    • 장치가 비행기모드에 있어 위치 서비스를 사용할 수 없는 상태
  • authorizedAlways
    • 앱이 백그라운드 상태에서도 위치 서비스를 시작할 수 있도록 승인한 경우
    • 앱 사용 여부에 관계없이 모든 위치 서비스를 사용하고 위치 이벤트를 수신할 수 있음
  • authorizedWhenInUse
    • 앱이 사용 중인 동안 위치 서비스를 시작하도록 승인

각 권한 상태에 따라 구현해준다.

권한이 거부되었다면 alert메세지를 이용하여 거부됨을 사용자에게 알려주고, 권한 설정을 할 수 있는 방법을 명시해준다.

 

✅ 권한 변경 탐지

채택한 CLLocationManagerDelegate의 메서드 중 권한 상태를 체크하는 메서드를 사용한다.

해당 메서드는 iOS 14부터 사용 가능하다.

// 사용자의 권한 상태가 바뀜을 체크함(iOS 14~)
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
    checkDeviceLocationAuthorization()
}

상태가 변경되었으면 다시 위치 서비스 활성화 여부 판단부터 상태 체크까지 진행한다.

 

✅ 현 위치 보여주기

권한을 사용자가 허용했다면 locationManager.startUpdatingLocation()를 호출해준다.

채택한 CLLocationManagerDelegate의 메서드 중 didUpdateLocations()를 실행하게 된다.

// 사용자의 위치를 성공적으로 가져옴
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    if let coordinate = locations.last?.coordinate {
        setRegionAndAnnotation(center: coordinate)
    }
    locationManager.stopUpdatingLocation()
}

사용자의 최종 위치 좌표를 가져와서 어노테이션을 찍어서 보여준다.

// 사용자의 위치 어노테이션 찍기
func setRegionAndAnnotation(center: CLLocationCoordinate2D){
    
    let region = MKCoordinateRegion(center: center, latitudinalMeters: 5000, longitudinalMeters: 5000)
    mapView.setRegion(region, animated: true)
    
    mapView.showsUserLocation = true
    
}

'iOS > UIKit&SwiftUI' 카테고리의 다른 글

[iOS/Swift] search bar 에 테두리와 그림자 동시 적용하기 - clipsToBounds  (0) 2023.10.01
[iOS/Swift] MapKit - 원하는 곳에 어노테이션을 찍어보자  (0) 2023.10.01
[iOS/Swift] Realm - 백업 및 복구 구현하기  (1) 2023.09.16
[iOS/Swift] Realm - Migration  (0) 2023.09.16
[iOS/Swift] Realm - 이미지 파일 저장하기  (0) 2023.09.16
'iOS/UIKit&SwiftUI' 카테고리의 다른 글
  • [iOS/Swift] search bar 에 테두리와 그림자 동시 적용하기 - clipsToBounds
  • [iOS/Swift] MapKit - 원하는 곳에 어노테이션을 찍어보자
  • [iOS/Swift] Realm - 백업 및 복구 구현하기
  • [iOS/Swift] Realm - Migration
김졀니
김졀니
🍎 iOS 개발
  • 김졀니
    졀니의 개발 공부✨
    김졀니
  • 전체
    오늘
    어제
    • 분류 전체보기
      • iOS
        • Swift
        • UIKit&SwiftUI
        • RxSwift&Combine
        • WWDC
      • Study
        • 🚨 TroubleShooting
        • 🌱 SeSAC
  • 블로그 메뉴

    • 홈
    • Github
  • 인기 글

  • 최근 글

  • 태그

    Swift
    ReactorKit
    Drawing Cycle
    mapkit
    OperationQueue
    traits
    의존성 주입
    동시성프로그래밍
    swift concurrency
    pointfree
    displayPriority
    인앱리뷰
    @PropertyWrapper
    Sendable
    RxSwift
    clipstobounds
    layoutIfNeeded
    Realm
    이미지 캐싱
    swiftdata
    wwdc23
    위치 권한
    FileManager
    concurrency
    kingfisher header
    actor
    CLLocation
    mainactor
    observable
    ios
  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.3
김졀니
[iOS/Swift] MapKit - 위치 권한 설정을 구현해보자!
상단으로

티스토리툴바