#swift #ios8 #nserror #didfailwitherror
#swift #ios8 #ошибка nserror #ошибка didfailwitherror
Вопрос:
Я использую CoreLocation для успешного определения местоположения пользователя. Однако, когда я пытаюсь использовать метод CLLocationManagerDelegate:
func locationManager(_ manager: CLLocationManager!, didFailWithError error: NSError!)
Я столкнулся с проблемами с термином ошибки.
func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
println("didFailWithError (error)")
if let err = error {
if err.code == kCLErrorLocationUnknown {
return
}
}
}
Это приводит к сообщению об ошибке «Использование неразрешенного идентификатора kCLErrorLocationUnknown». Я знаю, что kCLErrors являются перечислениями и что они эволюционировали в Swift, но я застрял.
Ответ №1:
Обновление для Swift 4: ошибка теперь передается обратному вызову как error: Error
который может быть преобразован в CLError
:
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
if let clErr = error as? CLError {
switch clErr.code {
case CLError.locationUnknown:
print("location unknown")
case CLError.denied:
print("denied")
default:
print("other Core Location error")
}
} else {
print("other error:", error.localizedDescription)
}
}
Более старый ответ: коды ошибок основного местоположения определяются как
enum CLError : Int {
case LocationUnknown // location is currently unknown, but CL will keep trying
case Denied // Access to location or ranging has been denied by the user
// ...
}
и для сравнения значения перечисления с целым числом err.code
, toRaw()
может быть использовано:
if err.code == CLError.LocationUnknown.toRaw() { ...
Кроме того, вы можете создать CLError
из кода ошибки и проверить, что
для возможных значений:
if let clErr = CLError.fromRaw(err.code) {
switch clErr {
case .LocationUnknown:
println("location unknown")
case .Denied:
println("denied")
default:
println("unknown Core Location error")
}
} else {
println("other error")
}
ОБНОВЛЕНИЕ: В Xcode 6.1 beta 2 методы fromRaw()
и toRaw()
были
заменяется init?(rawValue:)
инициализатором и rawValue
свойством соответственно:
if err.code == CLError.LocationUnknown.rawValue { ... }
if let clErr = CLError(rawValue: code) { ... }
Ответ №2:
В Swift 3 теперь:
if error._code == CLError.denied.rawValue { ... }
Комментарии:
1. Это правильно. На всякий случай, приведение к NSError, вероятно, скоро устареет:
let code = (error as NSError).code; if code == CLError.denied.rawValue { ... } // CODE SMELL!!
Ответ №3:
Swift 4.1:
func locationManager(_: CLLocationManager, didFailWithError error: Error) {
let err = CLError.Code(rawValue: (error as NSError).code)!
switch err {
case .locationUnknown:
break
default:
print(err)
}
}
Комментарии:
1. Это работает. Я нашел другой вариант без использования NSError.
2. какой!? 🙂