Swift: сопоставление, обрабатывающее ошибку NSError в didFailWithError

#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. какой!? 🙂