/
LocationManager.swift
100 lines (86 loc) · 3.1 KB
/
LocationManager.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
//
// LocationManager.swift
// CriticalMaps
//
// Created by Leonard Thomas on 12/17/18.
//
import CoreLocation
class LocationManager: NSObject, CLLocationManagerDelegate, LocationProvider {
static var accessPermission: LocationProviderPermission {
if Preferences.gpsEnabled {
switch CLLocationManager.authorizationStatus() {
case .authorizedAlways,
.authorizedWhenInUse:
return .authorized
case .notDetermined:
return .unkown
case .restricted,
.denied:
return .denied
@unknown default:
assertionFailure()
return .denied
}
} else {
return .denied
}
}
private var didSetInitialLocation = false
private var _currentLocation: Location?
private(set)
var currentLocation: Location? {
set {
_currentLocation = newValue
guard didSetInitialLocation == false else {
return
}
if let location = currentLocation {
didSetInitialLocation = true
NotificationCenter.default.post(name: Notification.initialGpsDataReceived, object: location)
}
}
get {
guard type(of: self).accessPermission == .authorized else {
return nil
}
return _currentLocation
}
}
private let locationManager = CLLocationManager()
init(updateInterval: TimeInterval = 11) {
super.init()
configureLocationManager()
configureTimer(with: updateInterval)
}
func configureLocationManager() {
locationManager.allowsBackgroundLocationUpdates = true
locationManager.requestAlwaysAuthorization()
locationManager.activityType = .otherNavigation
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
locationManager.delegate = self
locationManager.startUpdatingLocation()
}
private func configureTimer(with interval: TimeInterval) {
Timer.scheduledTimer(timeInterval: interval, target: self, selector: #selector(timerDidUpdate(timer:)), userInfo: nil, repeats: true)
}
@objc private func timerDidUpdate(timer _: Timer) {
requestLocation()
}
func requestLocation() {
guard type(of: self).accessPermission == .authorized else { return }
locationManager.requestLocation()
}
// MARK: CLLocationManagerDelegate
func locationManager(_: CLLocationManager, didFailWithError _: Error) {
locationManager.stopUpdatingLocation()
}
func locationManager(_: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let location = locations.last {
currentLocation = Location(location)
}
locationManager.stopUpdatingLocation()
}
func locationManager(_: CLLocationManager, didChangeAuthorization _: CLAuthorizationStatus) {
NotificationCenter.default.post(name: Notification.gpsStateChanged, object: type(of: self).accessPermission)
}
}