Skip to content

Commit

Permalink
Handle location error a little better
Browse files Browse the repository at this point in the history
  • Loading branch information
Frizlab committed Aug 22, 2020
1 parent 9ad0583 commit 623e560
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 14 deletions.
25 changes: 15 additions & 10 deletions GPS Stone/Heart/Services/LocationRecorder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@ final class LocationRecorder : NSObject, CLLocationManagerDelegate {
return status.recordingStatus
}

@objc dynamic private(set) var canRecord: Bool
@objc dynamic private(set) var currentHeading: CLHeading?
@objc dynamic private(set) var currentLocation: CLLocation?
@objc dynamic private(set) var currentLocationManagerError: NSError?
Expand All @@ -140,7 +139,6 @@ final class LocationRecorder : NSObject, CLLocationManagerDelegate {
lm = locationManager
rm = recordingsManager
nc = notificationCenter
canRecord = Set<CLAuthorizationStatus>(arrayLiteral: .notDetermined, .authorizedWhenInUse, .authorizedAlways).contains(CLLocationManager.authorizationStatus())
recStatusesHistory = (try? PropertyListDecoder().decode([RecordingStatusHistoryEntry].self, from: Data(contentsOf: constants.urlToCurrentRecordingInfo))) ?? []
status = Status(recordingStatus: recStatusesHistory.last?.status ?? .stopped, appSettingBestAccuracy: appSettings.useBestGPSAccuracy)

Expand Down Expand Up @@ -287,13 +285,22 @@ final class LocationRecorder : NSObject, CLLocationManagerDelegate {

func locationManager(_ manager: CLLocationManager, didChangeAuthorization authStatus: CLAuthorizationStatus) {
assert(Thread.isMainThread)
canRecord = Set<CLAuthorizationStatus>(arrayLiteral: .notDetermined, .authorizedWhenInUse, .authorizedAlways).contains(authStatus)
/* Nothing to do here, because we use errors to show messages to the user. */
}

func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
NSLog("%@", "Location manager error \(error)")
currentLocationManagerError = error as NSError

let nserror = error as NSError
guard nserror.domain != kCLErrorDomain || nserror.code != CLError.Code.locationUnknown.rawValue else {
/* Doc says this error can be ignored. */
return
}

currentLocationManagerError = nserror
currentLocation = nil

/* Doc says we should stop the location service in case we get a denied. */
}

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
Expand Down Expand Up @@ -651,8 +658,6 @@ final class LocationRecorder : NSObject, CLLocationManagerDelegate {
assert(Thread.isMainThread)
NSLog("%@", "Status change from \(oldStatus) to \(newStatus)")

#warning("Use locationServicesEnabled somehow")

/* *** Let’s save the current status *** */
if oldStatus.recordingStatus != newStatus.recordingStatus {
recStatusesHistory.append(RecordingStatusHistoryEntry(date: Date(), status: newStatus.recordingStatus))
Expand Down Expand Up @@ -710,10 +715,10 @@ final class LocationRecorder : NSObject, CLLocationManagerDelegate {
let neededSignificantLocationChangesTracking = oldStatus.needsSignificantLocationChangesTracking
if needsSignificantLocationChangesTracking && !neededSignificantLocationChangesTracking {
/* This should launch the app when it gets a significant location
  * changes even if the user has force quit it, if the background app
  * refresh is on.
  * After some testing, the app seems to be relaunched even with bg app
  * refresh off! */
 * changes even if the user has force quit it, if the background app
 * refresh is on.
 * After some testing, the app seems to be relaunched even with bg
 * app refresh off! */
lm.startMonitoringSignificantLocationChanges()
} else if !needsSignificantLocationChangesTracking && neededSignificantLocationChangesTracking {
lm.stopMonitoringSignificantLocationChanges()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@
/* The message shown to the user when no GPS info because the permission was denied. */
"error getting location: denied" = "Please allow GPS Stone to access your location for the app to work 😉";

/* The message shown to the user when no GPS info because the location services are disabled. */
"location services disabled" = "This app cannot work when location services are disabled. Please go to your phone settings, in Privacy, and enable location services.";

/* The message shown to the user when no GPS info because the system paused location updates for battery reasons. */
"location updates are paused" = "It seems you haven’t moved for a while. To preserve battery life, the system paused location update.";

Expand Down
11 changes: 7 additions & 4 deletions GPS Stone/Utilities/GPSStoneLocationError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,16 @@ enum GPSStoneLocationError : Error {
case locationNotFoundYet
case locationManagerPausedUpdates
case permissionDenied
case locationServicesDisabled
case unknown(underlyingError: Error)

init(error: Error?) {
if let error = error as NSError? {
switch (error.domain, error.code) {
case (LocationRecorder.errorDomain, LocationRecorder.errorCodeLocationManagerPausedUpdates): self = .locationManagerPausedUpdates
case (kCLErrorDomain, CLError.Code.denied.rawValue): self = .permissionDenied
default: self = .unknown(underlyingError: error)
switch (error.domain, error.code, CLLocationManager.locationServicesEnabled()) {
case (LocationRecorder.errorDomain, LocationRecorder.errorCodeLocationManagerPausedUpdates, _): self = .locationManagerPausedUpdates
case (kCLErrorDomain, CLError.Code.denied.rawValue, true): self = .permissionDenied
case (kCLErrorDomain, CLError.Code.denied.rawValue, false): self = .locationServicesDisabled
default: self = .unknown(underlyingError: error)
}
} else {
self = .locationNotFoundYet
Expand All @@ -33,6 +35,7 @@ enum GPSStoneLocationError : Error {
var localizedDescription: String {
switch self {
case .locationNotFoundYet: return NSLocalizedString("getting loc", comment: "The message shown to the user when no GPS info are available yet, but there are no errors getting the user’s position.")
case .locationServicesDisabled: return NSLocalizedString("location services disabled", comment: "The message shown to the user when no GPS info because the location services are disabled.")
case .locationManagerPausedUpdates: return NSLocalizedString("location updates are paused", comment: "The message shown to the user when no GPS info because the system paused location updates for battery reasons.")
case .permissionDenied: return NSLocalizedString("error getting location: denied", comment: "The message shown to the user when no GPS info because the permission was denied.")
case .unknown(let e): return NSLocalizedString("unknown error getting location", comment: "The message shown to the user when no GPS info because of an unknown error.").applyingCommonTokens(simpleReplacement1: e.localizedDescription)
Expand Down

0 comments on commit 623e560

Please sign in to comment.