๊ถํ ์ค์ ํ๊ธฐ (info.plist)
- ํ์ํ ๊ถํ๋ง ์ค์ ํ๊ธฐ
- ๊ถํ์ ๋ํ ํ์์ฑ Description ๊ตฌ์ฒด์ ์ผ๋ก ์์ฑํ๊ธฐ
โ๏ธ Privacy - Location When In User Usage Description
foreground์์ ์คํ ์ค์ผ ๋๋ง ์ฑ์ด ์์น ์ ๋ณด์ ์์ธ์คํ๋ ๊ฒฝ์ฐ ( iOS 11+ )
โ๏ธ Privacy - Location Always and When In Use Usage Description
background์์ ์คํ๋๋ ๋์ ์ฑ์ด ์์น ์ ๋ณด์ ์์ธ์คํ๋ ๊ฒฝ์ฐ ( iOS 11+ )
โ๏ธ Privacy - Location Always Usage Description
background์์ ์ฑ์ด ์์น ์ ๋ณด์ ์์ธ์คํ๋ ๊ฒฝ์ฐ ( iOS 11- )
โ๏ธ Privacy - Location Default Accuracy Reduced
์์น ์ ํ๋์ ๋ํ ์ฑ์ ๊ธฐ๋ณธ ๋์ ์ค์ ์, ์ ๋ณด ์์ฑ ๋ชฉ๋ก์ ์ด ํค๋ฅผ ํฌํจ ( iOS 14+ )
→ true: ์ ํ๋๊ฐ ๋จ์ด์ง๋ ์ง ๋ฌป๋ ๋ฉ์ธ์ง๊ฐ ํ์๋๋๋ก ํค ๊ฐ์ ์ค์
→ false: ์ ์ฒด ์์น ์ ํ๋๋ฅผ ๋ฌป๋ ๋ฉ์ธ์ง๊ฐ ํ์๋๋ก๋ก ์ค์ (๊ธฐ๋ณธ๊ฐ)
โ๏ธ Privacy - Location Temporary Usage Description Dictionary
์ฑ์ ํ ๋ถ๋ถ์์ ์ฌ์ฉ์ ์์น์ ๋ํ ์์ ์์ธ์ค๋ฅผ ์์ฒญํ๋ ์ด์ ์ค๋ช
โ๏ธ Privacy - Location Usage Description
MacOS ์ฑ์ด ์ฌ์ฉ์์ ์์น ์ ๋ณด์ ์์ธ์คํ๋ API๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ํ์
์ด๋ ๊ฒ ์ถ๊ฐํด์ ์ค์ ํ๋ฉด ๋๋ค. (์์น๋ฅผ ํ์ฉํด์ฃผ์ธ์.)
์๋๋ ๋ชฉ์ ๊ณผ ์ด์ ์ ์ด๋์ ์ฌ์ฉ์ด ๋๋์ง ๊ผญ ๊ตฌ์ฒด์ ์ผ๋ก ์์ฑํด์ผํ๋ค. (์๋๋ฉด ๋ฆฌ์ ๋ ์ ์์)
CLAuthorizationStatus (๊ถํ ์น์ธ ์ํ)
โ๏ธ case notDetermined
- ์ฑ์ ์์น ์๋น์ค ์ฌ์ฉ ์ฌ๋ถ์ ๋ํด์ ์ฌ์ฉ์๊ฐ ์ ํํ์ง ์์ ๊ฒฝ์ฐ
โ๏ธ case restricted
- ์ฑ์ ์์น ์๋น์ค ์ฌ์ฉ ๊ถํ์ด ์์ด ์ํ ๋ณ๊ฒฝ์ด ๋ถ๊ฐ๋ฅํ ๊ฒฝ์ฐ (ex. ์๋
๋ณดํธ ๊ธฐ๋ฅ)
โ๏ธ case denied
- ์ฑ์ ์์น ์๋น์ค ์ฌ์ฉ ๊ถํ์ Alert์์ ์ฌ์ฉ์๊ฐ ๊ฑฐ๋ถํ ๊ฒฝ์ฐ
- '์ค์ > ์์น ์๋น์ค'์์ ์๋น์ค๋ฅผ ์ค์งํ ๊ฒฝ์ฐ
- ๋นํ๊ธฐ ๋ชจ๋์ธ ๊ฒฝ์ฐ
โ๏ธ case authorizedAlways
- ์ฑ์ ์์น ์๋น์ค ๊ถํ์ ์น์ธํ ๊ฒฝ์ฐ (์ธ์ ๋ ์ง Always)
โ๏ธ case authorizedWhenInUse
- ์ฑ์ ์ฌ์ฉํ๋ ๋์ ์์น ์๋น์ค ๊ถํ์ ์น์ธํ ๊ฒฝ์ฐ
When In Use๋ ์ฑ์ด ์ฌ์ฉ๋๋ ๋์ ๋ชจ๋ ์์น ์๋น์ค๋ฅผ ์ฌ์ฉํ๊ณ ์ด๋ฒคํธ๋ฅผ ์์ ํ ์ ์๋ค. ์ผ๋ฐ์ ์ผ๋ก iOS ์ฑ์ foreground์ ์๊ฑฐ๋ background์์ ์คํ ์ค์ธ ๊ฒฝ์ฐ ์ฌ์ฉ ์ค์ธ ๊ฒ์ผ๋ก ๊ฐ์ฃผํ๋ค.
Always๋ ์ฌ์ฉ์๊ฐ ์ฑ์ด ์คํ๋๊ณ ์๋ค๋ ์ฌ์ค์ ์์ง ๋ชปํ๋ ๊ฒฝ์ฐ์๋ ์ฑ์ ๋ชจ๋ ์์น ์๋น์ค๋ฅผ ์ฌ์ฉํ๊ณ ์ด๋ฒคํธ๋ฅผ ์์ ํ ์ ์๋ค. ์ฑ์ด ์คํ๋๊ณ ์์ง ์์๋ ์์คํ ์ด ์ฑ์ ์คํํ๊ณ ์ด๋ฒคํธ๋ฅผ ์ ๋ฌํ ์ ์๋ค.
โ ๏ธ ์์น ์๋น์ค์ ๋ํ ์น์ธ ์์ฒญ ๋ฉ์๋๋ ์์์ ์ธ๊ธํ๋ info.plist์ ๊ฐ์ ํญ๋ชฉ์ด ์ถ๊ฐ๋์ด ์์ด์ผ ์ฌ์ฉํ ์ ์์ โ ๏ธ
import MapKit
let mapView = MKMapView()
์ฐ์ MapKit ์ํฌํธ ํด์ฃผ๊ณ , mapView ์์ฑํด์ ์์ ๋กญ๊ฒ UI ์ค์ ํ๊ธฐ
// 1. ์์น ํ๋ ์ ์ํฌ ์ํฌํธํ๊ธฐ
import CoreLocation
// 2. ์์น ๋งค๋์ ์์ฑํ๊ธฐ
let locationManager = CLLocationManager()
// 3. ์์น ๊ด๋ จ ํ๋กํ ์ฝ ์ ์ธํ๊ธฐ
extension LocationViewController: CLLocationManagerDelegate {
}
// 4. ํด๋์ค์ ํ๋กํ ์ฝ ์ฐ๊ฒฐํ๊ธฐ
locationManager.delegate = self
extension LocationViewController: CLLocationManagerDelegate {
// 5. ์ฌ์ฉ์ ์์น๋ฅผ ์ฑ๊ณต์ ์ผ๋ก ๊ฐ์ง๊ณ ์จ ๊ฒฝ์ฐ (์ฝ๋ ๊ตฌ์ฑ์ ๋ฐ๋ผ ์ฌ๋ฌ๋ฒ ํธ์ถ์ด ๋ ์๋ ์์)
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let coordinate = locations.last?.coordinate {
setRegionAndAnnotation(center: coordinate)
}
// stopUpdatingLocation์ ํ์ผ๋ฉด, ๋์ด์ ์์น๋ฅผ ์๋ฐ์๋ ๋๋ ์์ ์์๋ stop์ ์ธ์ณ์ผํจ.
locationManager.stopUpdatingLocation() // "๋ก์ง์ด ๋๋๋ฉด stopํด์ค." (์์ธ์ ์ผ๋ก ๋ฌ๋์ฑ๊ฐ์ ๊ฒฝ์ฐ์ ์ด๊ฑฐ ์ฌ์ฉX)
}
// 6. ์ฌ์ฉ์ ์์น๋ฅผ ๊ฐ์ง๊ณ ์ค์ง ๋ชปํ ๊ฒฝ์ฐ
// didFailWithError
func locationManager(_ manager: CLLocationManager, didFailWithError error: any Error) {
print(#function, "iOS14+")
}
// 7. ์ฌ์ฉ์ ๊ถํ ์ํ๊ฐ ๋ณ๊ฒฝ์ด ๋ ๋(iOS14) - ์ฒ์์ ํ์ฉํ๋ค๊ฐ ์์ดํฐ ์ค์ ์์ ๊ฑฐ๋ถํ ๊ฒฝ์ฐ
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
print(#function, "iOS14+")
checkDeviceLocationAuthorization()
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
print(#function, "iOS14-")
}
}
extension LocationViewController {
// 1) ์ฌ์ฉ์์๊ฒ ๊ถํ ์์ฒญ์ ํ๊ธฐ ์ํด, iOS ์์น ์๋น์ค ํ์ฑํ ์ฌ๋ถ ์ฒดํฌ
func checkDeviceLocationAuthorization() {
// ์ผ์ ธ์๋ ๊ฒฝ์ฐ
if CLLocationManager.locationServicesEnabled() {
// 2) ํ์ฌ ์ฌ์ฉ์ ์์น ๊ถํ ์ํ ํ์ธ
checkCurrentLocationAuthorization()
// ๊บผ์ ธ์๋ ๊ฒฝ์ฐ
} else {
"์์น ์๋น์ค๊ฐ ๊บผ์ ธ ์์ด์, ์์น ๊ถํ ์์ฒญ์ ํ ์ ์์ด์!!" -> Alert ๊ธฐ๋ฅ
}
}
// 2) ํ์ฌ ์ฌ์ฉ์ ์์น ๊ถํ ์ํ ํ์ธ
func checkCurrentLocationAuthorization() {
var status = locationManager.authorizationStatus
if #available(iOS 14.0, *) {
status = locationManager.authorizationStatus
} else {
status = CLLocationManager.authorizationStatus()
}
switch status {
// ๊ถํ ๋ฌธ๊ตฌ ๋์ธ ์ ์์
case .notDetermined:
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization() // ์ด๊ฑฐ๋ info.plist์ ์ค์ ํด ๋์ ๊ฒ ๊ฐ์์ง ํ์ธ!
case .denied:
// iOS ์ค์ ์ฐฝ์ผ๋ก ์ด๋ํ๋ผ๋ ์ผ๋ฟ์ ๋์์ฃผ๊ธฐ
case .authorizedWhenInUse:
// ์์น ์ ๋ณด ์๋ ค๋ฌ๋ผ๊ณ ๋ก์ง ๊ตฌ์ฑ
locationManager.startUpdatingLocation()
default:
print("-")
}
}
func setRegionAndAnnotation(center: CLLocationCoordinate2D) {
// ๋งต๋ทฐ์ ์ด๋
ธํ
์ด์
let region = MKCoordinateRegion(center: center, latitudinalMeters: 500, longitudinalMeters: 500)
mapView.setRegion(region, animated: true)
}
}
์ด๋ ๊ฒ ํด์ฃผ๊ณ , viewDidLoad ํน์ ๋ฒํผ Action ๋ฑ ์ํ๋ ๊ณณ -> checkCurrentLocationAuthorization() ์ถ๊ฐํด์ฃผ๊ธฐ
์คํํด๋ณด๋ฉด,
์ด๋ ๊ฒ ์ ์์ ์ผ๋ก ์์น ๊ถํ ๋ฌธ๊ตฌ๊ฐ ๋์ค๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
๊ทผ๋ฐ! ์ด๋ ๊ฒ ๋น๋ํ๋ฉด, ์๋์ ๊ฐ์ ๋ณด๋ผ์ ๊ฒฝ๊ณ ๊ฐ ๋ฌ๋ค.
์ด ๋ฉ์๋๋ฅผ ๊ธฐ๋ณธ ์ค๋ ๋์์ ํธ์ถํ๋ฉด, UI๊ฐ ์๋ตํ์ง ์์ ์ ์๋ค๊ณ ํ๋ค.
extension LocationViewController {
DispatchQueue.global().async { // Concurrent
func checkDeviceLocationAuthorization() {
if CLLocationManager.locationServicesEnabled() {
DispatchQueue.main.async { // UI ๊ด๋ จ -> main์ด ์ํ (Serial)
self.checkCurrentLocationAuthorization()
}
} else {
// Alert ๊ธฐ๋ฅ (ex. "์์น ์๋น์ค๊ฐ ๊บผ์ ธ ์์ด์, ์์น ๊ถํ ์์ฒญ์ ํ ์ ์์ด์!!")
}
}
}
...
}
๊ทธ๋์ ์์ ๊ฐ์ด UI ๊ด๋ จ ์์
์ ๋ค๋ฅธ ์ฐ๋ ๋์์ ์์
ํ ์ ์๋๋ก ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ํด์ฃผ๋ฉด ์ฌ๋ผ์ง๊ฒ ๋๋ค.
'Swift > Xcode' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Swift] CoreData ํ์ฉํด๋ณด๊ธฐ (Subclass ์์ฑ๋ฒ, Double ํ์ ์ ์ธ ์๋๋ ์ด์ ) (0) | 2024.12.12 |
---|---|
[Swift] UIButton Configuration (0) | 2024.05.30 |
[Swift] View Drawing Cycle (0) | 2024.05.28 |
[Swift] Delegate ํจํด (0) | 2024.05.26 |
[Swift] UserDefaults (0) | 2024.05.25 |