import CoreLocation extension NSError { public var displayMessage: (title: String, body: String) { if let description = self.userInfo[NSLocalizedDescriptionKey] as? String { return (title: "Error", body: description) } else if let failure = self.userInfo[NSLocalizedFailureErrorKey] as? String, let reason = self.localizedFailureReason { if let recovery = self.localizedRecoverySuggestion { return (title: failure, body: reason + "\n" + recovery) } else { return (title: failure, body: reason) } } else { return (title: "Error", body: localizedDescription) } } } extension CocoaError { public static func error(_ description: String) -> NSError { return error(Code(rawValue: 0), userInfo: [NSLocalizedDescriptionKey: description], url: nil) as NSError } public static func error(_ error: String, reason: String, suggestion: String? = nil) -> NSError { var info = [ NSLocalizedFailureErrorKey: error, NSLocalizedFailureReasonErrorKey: reason ] if let suggestion = suggestion { info[NSLocalizedRecoverySuggestionErrorKey] = suggestion } return self.error(Code(rawValue: 0), userInfo: info, url: nil) as NSError } } extension CLError.Code: CustomStringConvertible { public var description: String { switch self { case .locationUnknown: return "Location unknown" case .denied: return "Access denied" case .network: return "general, network-related error" case .headingFailure: return "heading could not be determined" case .regionMonitoringDenied: return "Location region monitoring has been denied" case .regionMonitoringSetupDelayed: return "CL could not immediately initialize region monitoring" case .regionMonitoringResponseDelayed: return "While events for this fence will be delivered, delivery will not occur immediately" case .geocodeFoundNoResult: return "A geocode request yielded no result" case .geocodeFoundPartialResult: return "A geocode request yielded a partial result" case .geocodeCanceled: return "A geocode request was cancelled" case .deferredFailed: return "Deferred mode failed" case .deferredNotUpdatingLocation: return "Deferred mode failed because location updates disabled or paused" case .deferredAccuracyTooLow: return "Deferred mode not supported for the requested accuracy" case .deferredDistanceFiltered: return "Deferred mode does not support distance filters" case .deferredCanceled: return "Deferred mode request canceled a previous request" case .rangingUnavailable: return "Ranging cannot be performed" case .rangingFailure: return "General ranging failure" case .promptDeclined: return "Authorization request not presented to user" default: return "Unknown location error (\(self.rawValue)" } } }